diff --git a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php index f807abda586b183d896b921d97fc64257393062f..4956b1cb28c6918f5499f17d753f2fad2e64518d 100644 --- a/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php +++ b/core/lib/Drupal/Core/Config/Entity/ConfigEntityStorage.php @@ -14,6 +14,7 @@ use Drupal\Core\Entity\EntityStorageBase; use Drupal\Core\Config\Config; use Drupal\Core\Config\StorageInterface; +use Drupal\Core\Config\Entity\Exception\ConfigEntityIdLengthException; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityStorageException; use Drupal\Core\Entity\Query\QueryFactory; @@ -38,6 +39,19 @@ */ class ConfigEntityStorage extends EntityStorageBase implements ConfigEntityStorageInterface, ImportableEntityStorageInterface { + /** + * Length limit of the configuration entity ID. + * + * Most file systems limit a file name's length to 255 characters. In + * order to leave sufficient characters to construct a configuration prefix, + * the configuration entity ID is limited to 166 characters which + * leaves 83 characters for the configuration prefix. 5 characters are + * reserved for the file extension. + * + * @see \Drupal\Core\Config\ConfigBase::MAX_NAME_LENGTH + */ + const MAX_ID_LENGTH = 166; + /** * The UUID service. * @@ -322,6 +336,15 @@ public function save(EntityInterface $entity) { $entity->original = $this->loadUnchanged($id); } + // Check the configuration entity ID length. + // @see \Drupal\Core\Config\Entity\ConfigEntityStorage::MAX_ID_LENGTH + if (strlen($entity->{$this->idKey}) > self::MAX_ID_LENGTH) { + throw new ConfigEntityIdLengthException(String::format('Configuration entity ID @id exceeds maximum allowed length of @length characters.', array( + '@id' => $entity->{$this->idKey}, + '@length' => self::MAX_ID_LENGTH, + ))); + } + $entity->preSave($this); $this->invokeHook('presave', $entity); diff --git a/core/lib/Drupal/Core/Config/Entity/Exception/ConfigEntityIdLengthException.php b/core/lib/Drupal/Core/Config/Entity/Exception/ConfigEntityIdLengthException.php new file mode 100644 index 0000000000000000000000000000000000000000..3fcb14221c2c334abce7c336ca0fe66143f52b06 --- /dev/null +++ b/core/lib/Drupal/Core/Config/Entity/Exception/ConfigEntityIdLengthException.php @@ -0,0 +1,15 @@ +<?php + +/** + * @file + * Contains \Drupal\Core\Config\Entity\Exception\ConfigEntityIdLengthException. + */ + +namespace Drupal\Core\Config\Entity\Exception; + +use Drupal\Core\Config\ConfigException; + +/** + * Defines an exception thrown when a configuration entity ID is too long. + */ +class ConfigEntityIdLengthException extends ConfigException {} diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php index 19ebaff67731d8ce186639850bae16d71c57fbc2..51bbf331f50eb4ff80bebac5a0876c939373f528 100644 --- a/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigEntityTest.php @@ -7,8 +7,11 @@ namespace Drupal\config\Tests; +use Drupal\Component\Utility\String; use Drupal\Core\Entity\EntityMalformedException; use Drupal\Core\Entity\EntityStorageException; +use Drupal\Core\Config\Entity\ConfigEntityStorage; +use Drupal\Core\Config\Entity\Exception\ConfigEntityIdLengthException; use Drupal\Core\Language\Language; use Drupal\simpletest\WebTestBase; @@ -142,6 +145,55 @@ function testCRUD() { $this->assertIdentical($config_test->isNew(), FALSE); $this->assertIdentical($config_test->getOriginalId(), $expected['id']); + // Verify that a configuration entity can be saved with an ID of the + // maximum allowed length, but not longer. + + // Test with a short ID. + $id_length_config_test = entity_create('config_test', array( + 'id' => $this->randomName(8), + )); + try { + $id_length_config_test->save(); + $this->pass(String::format("config_test entity with ID length @length was saved.", array( + '@length' => strlen($id_length_config_test->id)) + )); + } + catch (ConfigEntityIdLengthException $e) { + $this->fail($e->getMessage()); + } + + // Test with an ID of the maximum allowed length. + $id_length_config_test = entity_create('config_test', array( + 'id' => $this->randomName(ConfigEntityStorage::MAX_ID_LENGTH), + )); + try { + $id_length_config_test->save(); + $this->pass(String::format("config_test entity with ID length @length was saved.", array( + '@length' => strlen($id_length_config_test->id), + ))); + } + catch (ConfigEntityIdLengthException $e) { + $this->fail($e->getMessage()); + } + + // Test with an ID exeeding the maximum allowed length. + $id_length_config_test = entity_create('config_test', array( + 'id' => $this->randomName(ConfigEntityStorage::MAX_ID_LENGTH + 1), + )); + try { + $status = $id_length_config_test->save(); + $this->fail(String::format("config_test entity with ID length @length exceeding the maximum allowed length of @max saved successfully", array( + '@length' => strlen($id_length_config_test->id), + '@max' => ConfigEntityStorage::MAX_ID_LENGTH, + ))); + } + catch (ConfigEntityIdLengthException $e) { + $this->pass(String::format("config_test entity with ID length @length exceeding the maximum allowed length of @max failed to save", array( + '@length' => strlen($id_length_config_test->id), + '@max' => ConfigEntityStorage::MAX_ID_LENGTH, + ))); + } + // Ensure that creating an entity with the same id as an existing one is not // possible. $same_id = entity_create('config_test', array(