diff --git a/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php index 1e7ba32..4c9e890 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityTypeInterface.php @@ -11,7 +11,7 @@ * Gets an array of entity revision metadata keys. * * @param bool $include_backwards_compatibility_field_names - * (optional and @deprecated) Whether to provide the revision keys on a + * (optional and deprecated) Whether to provide the revision keys on a * best-effort basis by looking at the base fields defined by the entity * type. Note that this parameter will be removed in Drupal 9.0.0. Defaults * to TRUE. diff --git a/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php b/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php index ee5ec78..b988e03 100644 --- a/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php +++ b/core/modules/system/src/Tests/Entity/Update/MoveRevisionMetadataFieldsUpdateTest.php @@ -34,9 +34,9 @@ public function testUpdateHookN() { $this->runUpdates(); foreach (['entity_test_revlog', 'entity_test_mul_revlog'] as $entity_type_id) { - /** @var ContentEntityStorageInterface $storage */ + /** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */ $storage = \Drupal::entityTypeManager()->getStorage($entity_type_id); - /** @var ContentEntityTypeInterface $entity_type */ + /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */ $entity_type = $storage->getEntityType(); $revision_metadata_field_names = $entity_type->getRevisionMetadataKeys(); @@ -63,13 +63,13 @@ public function testUpdateHookN() { // Test that the revision metadata values have been transferred correctly // and that the moved fields are accessible. - /** @var ContentEntityInterface | RevisionLogInterface $entity_rev_first */ + /** @var \Drupal\Core\Entity\RevisionLogInterface $entity_rev_first */ $entity_rev_first = $storage->loadRevision(1); $this->assertEqual($entity_rev_first->getRevisionUserId(), '1'); $this->assertEqual($entity_rev_first->getRevisionLogMessage(), 'first revision'); $this->assertEqual($entity_rev_first->getRevisionCreationTime(), '1476268517'); - /** @var ContentEntityInterface | RevisionLogInterface $entity_rev_second */ + /** @var \Drupal\Core\Entity\RevisionLogInterface $entity_rev_second */ $entity_rev_second = $storage->loadRevision(2); $this->assertEqual($entity_rev_second->getRevisionUserId(), '1'); $this->assertEqual($entity_rev_second->getRevisionLogMessage(), 'second revision'); diff --git a/core/modules/system/system.install b/core/modules/system/system.install index c198330..0174b6a 100644 --- a/core/modules/system/system.install +++ b/core/modules/system/system.install @@ -12,6 +12,7 @@ use Drupal\Core\Path\AliasStorage; use Drupal\Core\Url; use Drupal\Core\Database\Database; +use Drupal\Core\Entity\FieldableEntityInterface; use Drupal\Core\DrupalKernel; use Drupal\Core\Site\Settings; use Drupal\Core\StreamWrapper\PrivateStream; @@ -1802,48 +1803,50 @@ function system_update_8203() { /** * Move revision metadata fields to the revision table. - * - * Due to the fields from RevisionLogEntityTrait not being explicitly mentioned - * in the storage they might have been installed wrongly in the base table for - * revisionable untranslatable entities and in the data and revision data - * tables for revisionable and translatable entities. */ function system_update_8300(&$sandbox) { - static $revisions = NULL; + // Due to the fields from RevisionLogEntityTrait not being explicitly + // mentioned in the storage they might have been installed wrongly in the base + // table for revisionable untranslatable entities and in the data and revision + // data tables for revisionable and translatable entities. $entity_definition_update_manager = \Drupal::entityDefinitionUpdateManager(); $database = \Drupal::database(); $database_schema = $database->schema(); foreach (\Drupal::entityTypeManager()->getDefinitions() as $entity_type_id => $entity_type) { - if (is_subclass_of($entity_type->getClass(), \Drupal\Core\Entity\FieldableEntityInterface::class) && $entity_type->isRevisionable()) { + if (is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && $entity_type->isRevisionable()) { /** @var \Drupal\Core\Entity\ContentEntityTypeInterface $entity_type */ $base_fields = $base_fields = \Drupal::service('entity_field.manager')->getBaseFieldDefinitions($entity_type_id); $revision_metadata_fields = $entity_type->getRevisionMetadataKeys(); $fields_to_update = array_intersect_key($base_fields, array_flip($revision_metadata_fields)); if (!empty($fields_to_update)) { + // Initialize the entity table names. + // @see \Drupal\Core\Entity\Sql\SqlContentEntityStorage::initTableLayout() $base_table = $entity_type->getBaseTable() ?: $entity_type_id; $data_table = $entity_type->getDataTable() ?: $entity_type_id . '_field_data'; - $revision_data_table = $entity_type->getRevisionDataTable() ?: $entity_type_id . '_field_revision'; $revision_table = $entity_type->getRevisionTable() ?: $entity_type_id . '_revision'; + $revision_data_table = $entity_type->getRevisionDataTable() ?: $entity_type_id . '_field_revision'; $revision_field = $entity_type->getKey('revision'); + // Collect the revision IDs for an entity type. + $revisions = array_keys(\Drupal::entityQuery($entity_type_id) + ->allRevisions() + ->execute()); + foreach ($fields_to_update as $revision_metadata_field_name => $definition) { // If the revision metadata field is present in the data and the - // revision data table install its definition again with the updated + // revision data table, install its definition again with the updated // storage code in order for the field to be installed in the - // revision table, afterwards copy over the field values and remove + // revision table. Afterwards, copy over the field values and remove // the field from the data and the revision data tables. if ($database_schema->fieldExists($base_table, $revision_metadata_field_name) || ($database_schema->fieldExists($data_table, $revision_metadata_field_name) && $database_schema->fieldExists($revision_data_table, $revision_metadata_field_name))) { // Install the field in the revision table. $entity_definition_update_manager->installFieldStorageDefinition($revision_metadata_field_name, $entity_type_id, $entity_type->getProvider(), $definition); + // No data needs to be migrated if the entity type is not + // translatable. if ($entity_type->isTranslatable()) { - // Collect the revision ids only once for an entity type. - $revisions = isset($revisions) ? $revisions : array_keys(\Drupal::entityQuery($entity_type_id) - ->allRevisions() - ->execute()); - if (!isset($sandbox['progress'])) { // This must be the first run. Initialize the sandbox. $sandbox['progress'] = 0; @@ -1856,8 +1859,7 @@ function system_update_8300(&$sandbox) { $current = $sandbox['current']; for ($i = $current; ($i < $current + 100) && ($i < $sandbox['max']); $i++) { $rev_id = $revisions[$i]; - $fetch_from_table = $entity_type->isTranslatable() ? $revision_data_table : $base_table; - $field_value = $database->select($fetch_from_table, 't') + $field_value = $database->select($revision_data_table, 't') ->fields('t', [$revision_metadata_field_name]) ->condition($revision_field, $rev_id) ->execute() @@ -1887,7 +1889,6 @@ function system_update_8300(&$sandbox) { } } } - $revisions = NULL; } } } diff --git a/core/modules/views/src/Entity/View.php b/core/modules/views/src/Entity/View.php index 5b3a8ff..ff42117 100644 --- a/core/modules/views/src/Entity/View.php +++ b/core/modules/views/src/Entity/View.php @@ -299,7 +299,10 @@ public function preSave(EntityStorageInterface $storage) { foreach ($display_data['display_options']['fields'] as $property_name => &$property_data) { if (isset($property_data['entity_type']) && isset($property_data['field']) && isset($property_data['table'])) { $entity_type = $this->entityTypeManager()->getDefinition($property_data['entity_type']); - if (is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && $entity_type->isRevisionable()) { + // We only need to update the table name for revisionable and + // translatable entity types, otherwise the view is already using + // the correct table. + if (is_subclass_of($entity_type->getClass(), FieldableEntityInterface::class) && $entity_type->isRevisionable() && $entity_type->isTranslatable()) { $revision_metadata_fields = $entity_type->getRevisionMetadataKeys(); $revision_table = $entity_type->getRevisionTable();