diff --git a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php index 8f75bde..1db9e97 100644 --- a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php +++ b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManager.php @@ -19,27 +19,6 @@ class EntityDefinitionUpdateManager implements EntityDefinitionUpdateManagerInte use StringTranslationTrait; /** - * Indicates that a definition has just been created. - * - * @var int - */ - const DEFINITION_CREATED = 1; - - /** - * Indicates that a definition has changes. - * - * @var int - */ - const DEFINITION_UPDATED = 2; - - /** - * Indicates that a definition has just been deleted. - * - * @var int - */ - const DEFINITION_DELETED = 3; - - /** * The entity manager service. * * @var \Drupal\Core\Entity\EntityManagerInterface @@ -70,6 +49,22 @@ public function getChangeSummary() { $summary = array(); foreach ($this->getChangeList() as $entity_type_id => $change_list) { + // Process entity type definition changes. + if (!empty($change_list['entity_type'])) { + $entity_type = $this->entityManager->getDefinition($entity_type_id); + $t_args = array('%entity_type' => $entity_type->getLabel()); + + switch ($change_list['entity_type']) { + case static::DEFINITION_CREATED: + $summary[$entity_type_id][] = $this->t('Create the %entity_type entity type.', $t_args); + break; + + case static::DEFINITION_UPDATED: + $summary[$entity_type_id][] = $this->t('Update the %entity_type entity type.', $t_args); + break; + } + } + // Process field storage definition changes. if (!empty($change_list['field_storage_definitions'])) { $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); @@ -91,11 +86,6 @@ public function getChangeSummary() { } } } - // Process entity type definition changes. - if (!empty($change_list['entity_type']) && $change_list['entity_type'] == static::DEFINITION_UPDATED) { - $entity_type = $this->entityManager->getDefinition($entity_type_id); - $summary[$entity_type_id][] = $this->t('Update the %entity_type entity type.', array('%entity_type' => $entity_type->getLabel())); - } } return $summary; @@ -110,10 +100,19 @@ public function applyUpdates() { // this is necessary when you change an entity type from non-revisionable // to revisionable and at the same time add revisionable fields to the // entity type. - if (!empty($change_list['entity_type']) && $change_list['entity_type'] == static::DEFINITION_UPDATED) { + if (!empty($change_list['entity_type'])) { $entity_type = $this->entityManager->getDefinition($entity_type_id); - $original = $this->entityManager->getLastInstalledDefinition($entity_type_id); - $this->entityManager->onEntityTypeUpdate($entity_type, $original); + + switch ($change_list['entity_type']) { + case static::DEFINITION_CREATED: + $this->entityManager->onEntityTypeCreate($entity_type); + break; + + case static::DEFINITION_UPDATED: + $original = $this->entityManager->getLastInstalledDefinition($entity_type_id); + $this->entityManager->onEntityTypeUpdate($entity_type, $original); + break; + } } // Process field storage definition changes. @@ -160,54 +159,55 @@ protected function getChangeList() { foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) { $original = $this->entityManager->getLastInstalledDefinition($entity_type_id); - // Only manage changes to already installed entity types. Entity type - // installation is handled elsewhere (e.g., - // \Drupal\Core\Extension\ModuleHandler::install()). - if (!$original) { - continue; - } - // @todo Support non-storage-schema-changing definition updates too: // https://www.drupal.org/node/2336895. - if ($this->requiresEntityStorageSchemaChanges($entity_type, $original)) { - $change_list[$entity_type_id]['entity_type'] = static::DEFINITION_UPDATED; + if (!$original) { + $change_list[$entity_type_id]['entity_type'] = static::DEFINITION_CREATED; } + else { + if ($this->requiresEntityStorageSchemaChanges($entity_type, $original)) { + $change_list[$entity_type_id]['entity_type'] = static::DEFINITION_UPDATED; + } - if ($this->entityManager->getStorage($entity_type_id) instanceof DynamicallyFieldableEntityStorageInterface) { - $field_changes = array(); - $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); - $original_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id); + if ($this->entityManager->getStorage($entity_type_id) instanceof DynamicallyFieldableEntityStorageInterface) { + $field_changes = array(); + $storage_definitions = $this->entityManager->getFieldStorageDefinitions($entity_type_id); + $original_storage_definitions = $this->entityManager->getLastInstalledFieldStorageDefinitions($entity_type_id); - // Detect created field storage definitions. - foreach (array_diff_key($storage_definitions, $original_storage_definitions) as $field_name => $storage_definition) { - $field_changes[$field_name] = static::DEFINITION_CREATED; - } + // Detect created field storage definitions. + foreach (array_diff_key($storage_definitions, $original_storage_definitions) as $field_name => $storage_definition) { + $field_changes[$field_name] = static::DEFINITION_CREATED; + } - // Detect deleted field storage definitions. - foreach (array_diff_key($original_storage_definitions, $storage_definitions) as $field_name => $original_storage_definition) { - $field_changes[$field_name] = static::DEFINITION_DELETED; - } + // Detect deleted field storage definitions. + foreach (array_diff_key($original_storage_definitions, $storage_definitions) as $field_name => $original_storage_definition) { + $field_changes[$field_name] = static::DEFINITION_DELETED; + } - // Detect updated field storage definitions. - foreach (array_intersect_key($storage_definitions, $original_storage_definitions) as $field_name => $storage_definition) { - // @todo Support non-storage-schema-changing definition updates too: - // https://www.drupal.org/node/2336895. So long as we're checking - // based on schema change requirements rather than definition - // equality, skip the check if the entity type itself needs to be - // updated, since that can affect the schema of all fields, so we - // want to process that update first without reporting false - // positives here. - if (!isset($change_list[$entity_type_id]['entity_type']) && $this->requiresFieldStorageSchemaChanges($storage_definition, $original_storage_definitions[$field_name])) { - $field_changes[$field_name] = static::DEFINITION_UPDATED; + // Detect updated field storage definitions. + foreach (array_intersect_key($storage_definitions, $original_storage_definitions) as $field_name => $storage_definition) { + // @todo Support non-storage-schema-changing definition updates too: + // https://www.drupal.org/node/2336895. So long as we're checking + // based on schema change requirements rather than definition + // equality, skip the check if the entity type itself needs to be + // updated, since that can affect the schema of all fields, so we + // want to process that update first without reporting false + // positives here. + if (!isset($change_list[$entity_type_id]['entity_type']) && $this->requiresFieldStorageSchemaChanges($storage_definition, $original_storage_definitions[$field_name])) { + $field_changes[$field_name] = static::DEFINITION_UPDATED; + } } - } - if ($field_changes) { - $change_list[$entity_type_id]['field_storage_definitions'] = $field_changes; + if ($field_changes) { + $change_list[$entity_type_id]['field_storage_definitions'] = $field_changes; + } } } } + // @todo Support deleting entity definitions when we support base field + // purging. See https://www.drupal.org/node/2282119. + return array_filter($change_list); } diff --git a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php index c6ead5b..25bbdad 100644 --- a/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityDefinitionUpdateManagerInterface.php @@ -35,6 +35,27 @@ interface EntityDefinitionUpdateManagerInterface { /** + * Indicates that a definition has just been created. + * + * @var int + */ + const DEFINITION_CREATED = 1; + + /** + * Indicates that a definition has changes. + * + * @var int + */ + const DEFINITION_UPDATED = 2; + + /** + * Indicates that a definition has just been deleted. + * + * @var int + */ + const DEFINITION_DELETED = 3; + + /** * Checks if there are any definition updates that need to be applied. * * @return bool diff --git a/core/modules/locale/src/Tests/LocaleTranslatedSchemaDefinitionTest.php b/core/modules/locale/src/Tests/LocaleTranslatedSchemaDefinitionTest.php index 73a9f25..f94db02 100644 --- a/core/modules/locale/src/Tests/LocaleTranslatedSchemaDefinitionTest.php +++ b/core/modules/locale/src/Tests/LocaleTranslatedSchemaDefinitionTest.php @@ -31,6 +31,8 @@ protected function setUp() { parent::setUp(); ConfigurableLanguage::createFromLangcode('fr')->save(); $this->config('system.site')->set('langcode', 'fr')->save(); + // Make sure new entity type definitions are processed. + \Drupal::service('entity.definition_update_manager')->applyUpdates(); // Clear all caches so that the base field definition, its cache in the // entity manager, the t() cache, etc. are all cleared. drupal_flush_all_caches(); diff --git a/core/modules/system/src/Tests/Update/UpdateScriptTest.php b/core/modules/system/src/Tests/Update/UpdateScriptTest.php index 5b09674..2da975f 100644 --- a/core/modules/system/src/Tests/Update/UpdateScriptTest.php +++ b/core/modules/system/src/Tests/Update/UpdateScriptTest.php @@ -32,6 +32,8 @@ protected function setUp() { parent::setUp(); $this->update_url = $GLOBALS['base_url'] . '/update.php'; $this->update_user = $this->drupalCreateUser(array('administer software updates', 'access site in maintenance mode')); + // Make sure updates for new entity type definitions are processed. + \Drupal::service('entity.definition_update_manager')->applyUpdates(); } /**