diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc index 21ff011..5bd5dcf 100644 --- a/core/modules/content_translation/content_translation.admin.inc +++ b/core/modules/content_translation/content_translation.admin.inc @@ -337,25 +337,10 @@ function content_translation_form_language_content_settings_submit(array $form, } // Ensure entity and menu router information are correctly rebuilt. - $entity_manager = \Drupal::entityManager(); - $entity_manager->clearCachedDefinitions(); + \Drupal::entityManager()->clearCachedDefinitions(); \Drupal::service('router.builder_indicator')->setRebuildNeeded(); - - // Handle field storage definition creation, if needed. - // @todo Generalize this code in https://www.drupal.org/node/2346013. - // @todo Handle initial values in https://www.drupal.org/node/2346019. - if (\Drupal::service('entity.definition_update_manager')->needsUpdates()) { - foreach ($entity_types as $entity_type_id => $entity_type) { - $storage_definitions = $entity_manager->getFieldStorageDefinitions($entity_type_id); - $installed_storage_definitions = $entity_manager->getLastInstalledFieldStorageDefinitions($entity_type_id); - foreach (array_diff_key($storage_definitions, $installed_storage_definitions) as $storage_definition) { - /** @var $storage_definition \Drupal\Core\Field\FieldStorageDefinitionInterface */ - if ($storage_definition->getProvider() == 'content_translation') { - $entity_manager->onFieldStorageDefinitionCreate($storage_definition); - } - } - } - } + \Drupal::service('content_translation.updates_manager')->updateDefinitions($entity_types); drupal_set_message(t('Settings successfully updated.')); } + diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 4f59ad3..a1dc61e 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -6,14 +6,13 @@ */ use Drupal\Core\Access\AccessResult; -use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\ContentEntityFormInterface; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\language\Entity\ContentLanguageSettings; use Drupal\node\NodeInterface; /** diff --git a/core/modules/content_translation/content_translation.services.yml b/core/modules/content_translation/content_translation.services.yml index 8d4740f..a06deae 100644 --- a/core/modules/content_translation/content_translation.services.yml +++ b/core/modules/content_translation/content_translation.services.yml @@ -24,3 +24,9 @@ services: content_translation.manager: class: Drupal\content_translation\ContentTranslationManager arguments: ['@entity.manager'] + + content_translation.updates_manager: + class: Drupal\content_translation\ContentTranslationUpdatesManager + arguments: ['@entity.manager', '@entity.definition_update_manager'] + tags: + - { name: event_subscriber } diff --git a/core/modules/content_translation/src/ContentTranslationUpdatesManager.php b/core/modules/content_translation/src/ContentTranslationUpdatesManager.php new file mode 100644 index 0000000..2a7fdca --- /dev/null +++ b/core/modules/content_translation/src/ContentTranslationUpdatesManager.php @@ -0,0 +1,89 @@ +entityManager = $entity_manager; + $this->updateManager = $update_manager; + } + + /** + * Executes field storage definition updates if needed. + * + * @param array $entity_types + * A list of entity type definitions to be processed. + */ + public function updateDefinitions(array $entity_types) { + // Handle field storage definition creation, if needed. + // @todo Generalize this code in https://www.drupal.org/node/2346013. + // @todo Handle initial values in https://www.drupal.org/node/2346019. + if ($this->updateManager->needsUpdates()) { + foreach ($entity_types as $entity_type_id => $entity_type) { + $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); + $installed_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id); + foreach (array_diff_key($storage_definitions, $installed_storage_definitions) as $storage_definition) { + /** @var $storage_definition \Drupal\Core\Field\FieldStorageDefinitionInterface */ + if ($storage_definition->getProvider() == 'content_translation') { + $this->entityManager->onFieldStorageDefinitionCreate($storage_definition); + } + } + } + } + } + + /** + * Listener for the ConfigImporter import event. + */ + public function onConfigImporterImport() { + $entity_types = array_filter(\Drupal::entityManager()->getDefinitions(), function (EntityTypeInterface $entity_type) { + return $entity_type->isTranslatable(); + }); + $this->updateDefinitions($entity_types); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[ConfigEvents::IMPORT][] = ['onConfigImporterImport', 60]; + return $events; + } + +} diff --git a/core/modules/content_translation/src/Tests/ContentTranslationConfigImportTest.php b/core/modules/content_translation/src/Tests/ContentTranslationConfigImportTest.php new file mode 100644 index 0000000..c06fdb2 --- /dev/null +++ b/core/modules/content_translation/src/Tests/ContentTranslationConfigImportTest.php @@ -0,0 +1,111 @@ +installEntitySchema('entity_test_mul'); + $this->copyConfig($this->container->get('config.storage'), $this->container->get('config.storage.staging')); + + // Set up the ConfigImporter object for testing. + $storage_comparer = new StorageComparer( + $this->container->get('config.storage.staging'), + $this->container->get('config.storage'), + $this->container->get('config.manager') + ); + $this->configImporter = new ConfigImporter( + $storage_comparer->createChangelist(), + $this->container->get('event_dispatcher'), + $this->container->get('config.manager'), + $this->container->get('lock'), + $this->container->get('config.typed'), + $this->container->get('module_handler'), + $this->container->get('module_installer'), + $this->container->get('theme_handler'), + $this->container->get('string_translation') + ); + } + + /** + * Tests config import updates. + */ + function testConfigImportUpdates() { + $entity_type_id = 'entity_test_mul'; + $config_id = $entity_type_id . '.' . $entity_type_id; + $config_name = 'language.content_settings.' . $config_id; + $storage = $this->container->get('config.storage'); + $staging = $this->container->get('config.storage.staging'); + + // Verify the configuration to create does not exist yet. + $this->assertIdentical($storage->exists($config_name), FALSE, $config_name . ' not found.'); + + // Create new config entity. + $data = array( + 'uuid' => 'a019d89b-c4d9-4ed4-b859-894e4e2e93cf', + 'langcode' => 'en', + 'status' => TRUE, + 'dependencies' => array( + 'module' => array('content_translation') + ), + 'id' => $config_id, + 'target_entity_type_id' => 'entity_test_mul', + 'target_bundle' => 'entity_test_mul', + 'default_langcode' => 'site_default', + 'language_alterable' => FALSE, + 'third_party_settings' => array( + 'content_translation' => array('enabled' => TRUE), + ), + ); + $staging->write($config_name, $data); + $this->assertIdentical($staging->exists($config_name), TRUE, $config_name . ' found.'); + + // Import. + $this->configImporter->reset()->import(); + + // Verify the values appeared. + $config = $this->config($config_name); + $this->assertIdentical($config->get('id'), $config_id); + + // Verify that updates were performed. + $entity_type = $this->container->get('entity.manager')->getDefinition($entity_type_id); + $table = $entity_type->getDataTable(); + $db_schema = $this->container->get('database')->schema(); + $result = $db_schema->fieldExists($table, 'content_translation_source') && $db_schema->fieldExists($table, 'content_translation_outdated'); + $this->assertTrue($result, 'Content translation updates were successfully performed during config import.'); + } + +}