diff -u b/core/core.services.yml b/core/core.services.yml --- b/core/core.services.yml +++ b/core/core.services.yml @@ -89,8 +89,8 @@ factory_method: get factory_service: config.context.factory arguments: [Drupal\Core\Config\Context\FreeConfigContext] - config.creationhash: - class: Drupal\Core\Config\CreationHash + config.creation_id_generator: + class: Drupal\Core\Config\CreationId tags: - { name: persist } arguments: ['@uuid'] diff -u b/core/includes/theme.inc b/core/includes/theme.inc --- b/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1144,7 +1144,8 @@ drupal_clear_css_cache(); $theme_config = \Drupal::config('system.theme'); $disabled_themes = \Drupal::config('system.theme.disabled'); - \Drupal::service('config.creationhash')->setPrefix('theme_enable'); + $creation_id_generator = \Drupal::service('config.creation_id_generator'); + $creation_id_generator->setPrefix('theme_enable'); foreach ($theme_list as $key) { // Throw an exception if the theme name is too long. if (strlen($key) > DRUPAL_EXTENSION_NAME_MAX_LENGTH) { @@ -1172,6 +1173,7 @@ // Invoke hook_themes_enabled() after the themes have been enabled. \Drupal::moduleHandler()->invokeAll('themes_enabled', array($theme_list)); + $creation_id_generator->unsetPrefix(); } /** reverted: --- b/core/lib/Drupal/Core/Config/CreationHash.php +++ /dev/null @@ -1,71 +0,0 @@ -uuid = $uuid_generator; - } - - /** - * {@inheritdoc} - */ - public function setPrefix($prefix) { - if (empty($this->prefix)) { - $this->prefix = $prefix; - } - } - - /** - * {@inheritdoc} - */ - public function getPrefix() { - if (empty($this->prefix)) { - $prefix = $this->uuid->generate(); - } - else { - $prefix = $this->prefix; - } - return $prefix; - } - - /** - * {@inheritdoc} - */ - public function generate($id) { - // We need to replace dots in the ids since the uuid is being used in field - // and table names. Without this \Drupal\field\Tests\FieldImportDeleteTest - // does not pass. - return $this->getPrefix() . '__' . str_replace('.', '__', $id); - } - -} reverted: --- b/core/lib/Drupal/Core/Config/CreationHashInterface.php +++ /dev/null @@ -1,38 +0,0 @@ -idKey = $this->entityInfo['entity_keys']['id']; @@ -107,7 +107,7 @@ $this->configFactory = $config_factory; $this->configStorage = $config_storage; $this->entityQueryFactory = $entity_query_factory; - $this->creationHash = $creation_hash_service; + $this->creationIdGenerator = $creation_id_generator; } /** @@ -120,7 +120,7 @@ $container->get('config.factory'), $container->get('config.storage'), $container->get('entity.query'), - $container->get('config.creationhash') + $container->get('config.creation_id_generator') ); } @@ -344,7 +344,7 @@ // Assign a new UUID if there is none yet. if (!isset($entity->{$this->uuidKey})) { - $entity->{$this->uuidKey} = $this->creationHash->generate($entity->id()); + $entity->{$this->uuidKey} = $this->creationIdGenerator->generate($entity->id()); } return $entity; diff -u b/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php --- b/core/lib/Drupal/Core/Extension/ModuleHandler.php +++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php @@ -502,7 +502,8 @@ * {@inheritdoc} */ public function install(array $module_list, $enable_dependencies = TRUE) { - \Drupal::service('config.creationhash')->setPrefix('ModuleHandler::install'); + $creation_id_generator = \Drupal::service('config.creation_id_generator'); + $creation_id_generator->setPrefix('ModuleHandler::install'); $module_config = \Drupal::config('system.module'); if ($enable_dependencies) { // Get all module data so we can find dependencies and sort. @@ -659,6 +660,7 @@ $this->invokeAll('modules_installed', array($modules_installed)); } + $creation_id_generator->unsetPrefix(); return TRUE; } diff -u b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php --- b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php +++ b/core/modules/config/lib/Drupal/config/Tests/ConfigInstallWebTest.php @@ -92,45 +92,44 @@ $this->assertIdentical($config_entity->get('label'), 'Customized integration config label'); } - protected function testCreationHashGeneration() { + protected function testCreationIdGeneration() { \Drupal::moduleHandler()->install(array('config_test')); // Ensure routes provided by the config_test module work. drupal_flush_all_caches(); $default_config_entity = entity_load('config_test', 'dotted.default'); - $default_config_entity_creation_hash = $default_config_entity->uuid(); - $this->assertEqual($default_config_entity_creation_hash, 'ModuleHandler::install__dotted__default'); + $default_config_entity_creation_id = $default_config_entity->uuid(); + $this->assertEqual($default_config_entity_creation_id, 'ModuleHandler::install__dotted__default'); $edit = array( - 'id' => 'test_creation_hash', + 'id' => 'test_creation_id', 'label' => $this->randomName(), ); $this->drupalPostForm('admin/structure/config_test/add', $edit, 'Save'); - $custom_config_entity = entity_load('config_test', 'test_creation_hash'); - $custom_config_entity_creation_hash = $custom_config_entity->uuid(); - $this->assertIdentical(FALSE, strpos($custom_config_entity_creation_hash, 'ModuleHandler::install'), "Runtime generated configuration creation hash does not contain ModuleHandler::install"); + $custom_config_entity = entity_load('config_test', 'test_creation_id'); + $custom_config_entity_creation_id = $custom_config_entity->uuid(); + $this->assertIdentical(FALSE, strpos($custom_config_entity_creation_id, 'ModuleHandler::install'), "Runtime generated configuration creation hash does not contain ModuleHandler::install"); \Drupal::moduleHandler()->uninstall(array('config_test')); // Ensure the config entities have been deleted. $config = \Drupal::config('config_test.dynamic.dotted.default'); $this->assertIdentical($config->isNew(), TRUE); - $config = \Drupal::config('config_test.dynamic.test_creation_hash'); + $config = \Drupal::config('config_test.dynamic.test_creation_id'); $this->assertIdentical($config->isNew(), TRUE); - // Install the integration module. \Drupal::moduleHandler()->install(array('config_test')); $default_config_entity = entity_load('config_test', 'dotted.default'); - // Ensure that the creation hash has not changed after uninstalling and + // Ensure that the creation ID has not changed after uninstalling and // re-installing. - $this->assertIdentical($default_config_entity_creation_hash, $default_config_entity->uuid()); + $this->assertIdentical($default_config_entity_creation_id, $default_config_entity->uuid()); $edit = array( - 'id' => 'test_creation_hash', + 'id' => 'test_creation_id', 'label' => $this->randomName(), ); $this->drupalPostForm('admin/structure/config_test/add', $edit, 'Save'); - $custom_config_entity = entity_load('config_test', 'test_creation_hash'); - $this->assertNotIdentical($custom_config_entity_creation_hash, $custom_config_entity->uuid()); + $custom_config_entity = entity_load('config_test', 'test_creation_id'); + $this->assertNotIdentical($custom_config_entity_creation_id, $custom_config_entity->uuid()); } } diff -u b/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php b/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php --- b/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php +++ b/core/modules/field/lib/Drupal/field/FieldInstanceStorageController.php @@ -8,7 +8,7 @@ namespace Drupal\field; use Drupal\Core\Config\Config; -use Drupal\Core\Config\CreationHashInterface; +use Drupal\Core\Config\CreationIdInterface; use Drupal\Core\Config\Entity\ConfigStorageController; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\Query\QueryFactory; @@ -63,8 +63,8 @@ * The config storage service. * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query_factory * The entity query factory. - * @param \Drupal\Core\Config\CreationHashInterface $creation_hash_service - * The configuration creation hash service. + * @param \Drupal\Core\Config\CreationIdInterface $creation_id_generator + * The configuration creation ID generator. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. * @param \Drupal\Core\Extension\ModuleHandler $module_handler @@ -72,8 +72,8 @@ * @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state * The state key value store. */ - public function __construct($entity_type, array $entity_info, ConfigFactory $config_factory, StorageInterface $config_storage, QueryFactory $entity_query_factory, CreationHashInterface $creation_hash_service, EntityManagerInterface $entity_manager, ModuleHandler $module_handler, KeyValueStoreInterface $state) { - parent::__construct($entity_type, $entity_info, $config_factory, $config_storage, $entity_query_factory, $creation_hash_service); + public function __construct($entity_type, array $entity_info, ConfigFactory $config_factory, StorageInterface $config_storage, QueryFactory $entity_query_factory, CreationIdInterface $creation_id_generator, EntityManagerInterface $entity_manager, ModuleHandler $module_handler, KeyValueStoreInterface $state) { + parent::__construct($entity_type, $entity_info, $config_factory, $config_storage, $entity_query_factory, $creation_id_generator); $this->entityManager = $entity_manager; $this->moduleHandler = $module_handler; $this->state = $state; @@ -89,7 +89,7 @@ $container->get('config.factory'), $container->get('config.storage'), $container->get('entity.query'), - $container->get('config.creationhash'), + $container->get('config.creation_id_generator'), $container->get('entity.manager'), $container->get('module_handler'), $container->get('state') diff -u b/core/modules/field/lib/Drupal/field/FieldStorageController.php b/core/modules/field/lib/Drupal/field/FieldStorageController.php --- b/core/modules/field/lib/Drupal/field/FieldStorageController.php +++ b/core/modules/field/lib/Drupal/field/FieldStorageController.php @@ -8,7 +8,7 @@ namespace Drupal\field; use Drupal\Core\Config\Config; -use Drupal\Core\Config\CreationHashInterface; +use Drupal\Core\Config\CreationIdInterface; use Drupal\Core\Config\Entity\ConfigStorageController; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\Query\QueryFactory; @@ -57,8 +57,8 @@ * The config storage service. * @param \Drupal\Core\Entity\Query\QueryFactory $entity_query_factory * The entity query factory. - * @param \Drupal\Core\Config\CreationHashInterface $creation_hash_service - * The configuration creation hash service. + * @param \Drupal\Core\Config\CreationIdInterface $creation_id_generator + * The configuration creation ID generator. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. * @param \Drupal\Core\Extension\ModuleHandler $module_handler @@ -66,8 +66,8 @@ * @param \Drupal\Core\KeyValueStore\KeyValueStoreInterface $state * The state key value store. */ - public function __construct($entity_type, array $entity_info, ConfigFactory $config_factory, StorageInterface $config_storage, QueryFactory $entity_query_factory, CreationHashInterface $creation_hash_service, EntityManagerInterface $entity_manager, ModuleHandler $module_handler, KeyValueStoreInterface $state) { - parent::__construct($entity_type, $entity_info, $config_factory, $config_storage, $entity_query_factory, $creation_hash_service); + public function __construct($entity_type, array $entity_info, ConfigFactory $config_factory, StorageInterface $config_storage, QueryFactory $entity_query_factory, CreationIdInterface $creation_id_generator, EntityManagerInterface $entity_manager, ModuleHandler $module_handler, KeyValueStoreInterface $state) { + parent::__construct($entity_type, $entity_info, $config_factory, $config_storage, $entity_query_factory, $creation_id_generator); $this->entityManager = $entity_manager; $this->moduleHandler = $module_handler; $this->state = $state; @@ -83,7 +83,7 @@ $container->get('config.factory'), $container->get('config.storage'), $container->get('entity.query'), - $container->get('config.creationhash'), + $container->get('config.creation_id_generator'), $container->get('entity.manager'), $container->get('module_handler'), $container->get('state') reverted: --- b/core/tests/Drupal/Tests/Core/Config/CreationHashTest.php +++ /dev/null @@ -1,49 +0,0 @@ - 'Config creation hash test', - 'description' => 'Tests the use of prefixes by \Drupal\Core\Config\CreationHash.', - 'group' => 'Configuration' - ); - } - - public function testCreationHashNoPrefix() { - $uuid = $this->getMock('Drupal\Component\Uuid\UuidInterface'); - $uuid->expects($this->once()) - ->method('generate') - ->will($this->returnValue('generated-uuid')); - - $creationHash = new CreationHash($uuid); - $this->assertEquals('generated-uuid__test__id', $creationHash->generate('test.id')); - } - - public function testCreationHashPrefix() { - $uuid = $this->getMock('Drupal\Component\Uuid\UuidInterface'); - $uuid->expects($this->never()) - ->method('generate') - ->will($this->returnValue('generated-uuid')); - - $creationHash = new CreationHash($uuid); - $creationHash->setPrefix('CreationHashTest'); - $this->assertEquals('CreationHashTest__test__id', $creationHash->generate('test.id')); - - // Ensure that the prefix cannot be reset. This allows themes to be enabled - // by profiles in their hook_install implementation. - $creationHash->setPrefix('AnotherPrefix'); - $this->assertEquals('CreationHashTest__test__id', $creationHash->generate('test.id')); - } - -} only in patch2: unchanged: --- /dev/null +++ b/core/lib/Drupal/Core/Config/CreationId.php @@ -0,0 +1,92 @@ +uuidGenerator = $uuid_generator; + } + + /** + * {@inheritdoc} + */ + public function setPrefix($prefix) { + $this->prefixes[] = $prefix; + } + + /** + * {@inheritdoc} + */ + public function getPrefix() { + if (empty($this->prefixes)) { + $prefix = $this->uuidGenerator->generate(); + } + else { + $prefix = end($this->prefixes); + } + return $prefix; + } + + /** + * {@inheritdoc} + */ + public function generate($id) { + // We need to replace dots in the ids since the uuid is being used in field + // and table names. Without this \Drupal\field\Tests\FieldImportDeleteTest + // does not pass. + return $this->getPrefix() . '__' . str_replace('.', '__', $id); + } + + /** + * {@inheritdoc} + */ + public function unsetPrefix() { + if (empty($this->prefixes)) { + throw new ConfigException('Cannot unset prefix when the CreationId::$prefixes array is empty.'); + } + return array_pop($this->prefixes); + } +} only in patch2: unchanged: --- /dev/null +++ b/core/lib/Drupal/Core/Config/CreationIdInterface.php @@ -0,0 +1,49 @@ +drupalLogout(); $this->assertText('Main navigation'); + // Verify the configuration entity creation IDs are as expected. + $this->assertEqual(entity_load('view', 'frontpage')->uuid(), 'ModuleHandler::install__frontpage'); + // Once breakpoints are being handled correctly we will be able to assert + // that they are created during theme_enable() and have the expected + // creation ID. } } only in patch2: unchanged: --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Config/CreationIdTest.php @@ -0,0 +1,70 @@ + 'Config creation ID test', + 'description' => 'Tests the use of prefixes by \Drupal\Core\Config\CreationId.', + 'group' => 'Configuration' + ); + } + + public function testCreationIdNoPrefix() { + $uuid = $this->getMock('Drupal\Component\Uuid\UuidInterface'); + $uuid->expects($this->once()) + ->method('generate') + ->will($this->returnValue('generated-uuid')); + + $creationIdGenerator = new CreationId($uuid); + $this->assertEquals('generated-uuid__test__id', $creationIdGenerator->generate('test.id')); + } + + public function testCreationIdPrefix() { + $uuid = $this->getMock('Drupal\Component\Uuid\UuidInterface'); + $uuid->expects($this->once()) + ->method('generate') + ->will($this->returnValue('generated-uuid')); + + $creationIdGenerator = new CreationId($uuid); + $creationIdGenerator->setPrefix('CreationIdTest'); + $this->assertEquals('CreationIdTest__test__id', $creationIdGenerator->generate('test.id')); + + // Add a new prefix to the prefix stack and ensure that it is used. + $creationIdGenerator->setPrefix('AnotherPrefix'); + $this->assertEquals('AnotherPrefix__test__id', $creationIdGenerator->generate('test.id')); + + // Unset the current prefix and ensure that the old prefix is used. + $creationIdGenerator->unsetPrefix(); + $this->assertEquals('CreationIdTest__test__id', $creationIdGenerator->generate('test.id')); + + // Unset the current prefix and ensure that we fallback to using UUID generator. + $creationIdGenerator->unsetPrefix(); + $this->assertEquals('generated-uuid__test__id', $creationIdGenerator->generate('test.id')); + + } + + /** + * @expectedException \Drupal\Core\Config\ConfigException + */ + public function testUnsetPrefixException () { + $uuid = $this->getMock('Drupal\Component\Uuid\UuidInterface'); + $uuid->expects($this->never()) + ->method('generate') + ->will($this->returnValue('generated-uuid')); + + $creationIdGenerator = new CreationId($uuid); + $creationIdGenerator->unsetPrefix(); + } + +}