class EntityRevision

Same name in this branch
  1. 10 core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php \Drupal\Tests\migrate\Unit\destination\EntityRevision
Same name in other branches
  1. 9 core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php \Drupal\migrate\Plugin\migrate\destination\EntityRevision
  2. 9 core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php \Drupal\Tests\migrate\Unit\destination\EntityRevision
  3. 8.9.x core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php \Drupal\migrate\Plugin\migrate\destination\EntityRevision
  4. 8.9.x core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php \Drupal\Tests\migrate\Unit\destination\EntityRevision
  5. 11.x core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php \Drupal\migrate\Plugin\migrate\destination\EntityRevision
  6. 11.x core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php \Drupal\Tests\migrate\Unit\destination\EntityRevision

Provides entity revision destination plugin.

Refer to the parent class for configuration keys: \Drupal\migrate\Plugin\migrate\destination\EntityContentBase

Entity revisions can only be migrated after the entity to which the revisions belong has been migrated. For example, revisions of a given content type can be migrated only after the nodes of that content type have been migrated.

In order to avoid revision ID conflicts, make sure that the entity migration also includes the revision ID. If the entity migration did not include the revision ID, the entity would get the next available revision ID (1 when migrating to a clean database). Then, when revisions are migrated after the entities, the revision IDs would almost certainly collide.

The examples below contain simple node and node revision migrations. The examples use the EmbeddedDataSource source plugin for the sake of simplicity. The important part of both examples is the 'vid' property, which is the revision ID for nodes.

Example of 'article' node migration, which must be executed before the 'article' revisions.


id: custom_article_migration
label: 'Custom article migration'
source:
  plugin: embedded_data
  data_rows:
    -
      nid: 1
      vid: 2
      revision_timestamp: 1514661000
      revision_log: 'Second revision'
      title: 'Current title'
      content: '<p>Current content</p>'
  ids:
    nid:
      type: integer
process:
  nid: nid
  vid: vid
  revision_timestamp: revision_timestamp
  revision_log: revision_log
  title: title
  'body/0/value': content
  'body/0/format':
     plugin: default_value
     default_value: basic_html
destination:
  plugin: entity:node
  default_bundle: article

Example of the corresponding node revision migration, which must be executed after the above migration.


id: custom_article_revision_migration
label: 'Custom article revision migration'
source:
  plugin: embedded_data
  data_rows:
    -
      nid: 1
      vid: 1
      revision_timestamp: 1514660000
      revision_log: 'First revision'
      title: 'Previous title'
      content: '<p>Previous content</p>'
  ids:
    nid:
      type: integer
process:
  nid:
    plugin: migration_lookup
    migration: custom_article_migration
    source: nid
  vid: vid
  revision_timestamp: revision_timestamp
  revision_log: revision_log
  title: title
  'body/0/value': content
  'body/0/format':
     plugin: default_value
     default_value: basic_html
destination:
  plugin: entity_revision:node
  default_bundle: article
migration_dependencies:
  required:
    - custom_article_migration

Hierarchy

Expanded class hierarchy of EntityRevision

2 files declare their use of EntityRevision
EntityRevisionTest.php in core/modules/migrate/tests/src/Unit/destination/EntityRevisionTest.php
EntityRevisionTest.php in core/modules/migrate/tests/src/Unit/Plugin/migrate/destination/EntityRevisionTest.php

File

core/modules/migrate/src/Plugin/migrate/destination/EntityRevision.php, line 110

Namespace

Drupal\migrate\Plugin\migrate\destination
View source
class EntityRevision extends EntityContentBase {
    
    /**
     * {@inheritdoc}
     */
    public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, EntityFieldManagerInterface $entity_field_manager, FieldTypePluginManagerInterface $field_type_manager, AccountSwitcherInterface $account_switcher) {
        $plugin_definition += [
            'label' => new TranslatableMarkup('@entity_type revisions', [
                '@entity_type' => $storage->getEntityType()
                    ->getSingularLabel(),
            ]),
        ];
        parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $entity_field_manager, $field_type_manager, $account_switcher);
    }
    
    /**
     * Gets the entity.
     *
     * @param \Drupal\migrate\Row $row
     *   The row object.
     * @param array $old_destination_id_values
     *   The old destination IDs.
     *
     * @return \Drupal\Core\Entity\EntityInterface|false
     *   The entity or false if it can not be created.
     */
    protected function getEntity(Row $row, array $old_destination_id_values) {
        $revision_id = $old_destination_id_values ? reset($old_destination_id_values) : $row->getDestinationProperty($this->getKey('revision'));
        $entity = NULL;
        if (!empty($revision_id)) {
            
            /** @var \Drupal\Core\Entity\RevisionableStorageInterface $storage */
            $storage = $this->storage;
            if ($entity = $storage->loadRevision($revision_id)) {
                $entity->setNewRevision(FALSE);
            }
        }
        if ($entity === NULL) {
            $entity_id = $row->getDestinationProperty($this->getKey('id'));
            $entity = $this->storage
                ->load($entity_id);
            // If we fail to load the original entity something is wrong and we need
            // to return immediately.
            if (!$entity) {
                return FALSE;
            }
            $entity->enforceIsNew(FALSE);
            $entity->setNewRevision(TRUE);
        }
        // We need to update the entity, so that the destination row IDs are
        // correct.
        $entity = $this->updateEntity($entity, $row);
        $entity->isDefaultRevision(FALSE);
        return $entity;
    }
    
    /**
     * {@inheritdoc}
     */
    protected function save(ContentEntityInterface $entity, array $old_destination_id_values = []) {
        $entity->setSyncing(TRUE);
        $entity->save();
        return [
            $entity->getRevisionId(),
        ];
    }
    
    /**
     * {@inheritdoc}
     */
    public function getIds() {
        $ids = [];
        $revision_key = $this->getKey('revision');
        if (!$revision_key) {
            throw new MigrateException(sprintf('The "%s" entity type does not support revisions.', $this->storage
                ->getEntityTypeId()));
        }
        $ids[$revision_key] = $this->getDefinitionFromEntity($revision_key);
        if ($this->isTranslationDestination()) {
            $langcode_key = $this->getKey('langcode');
            if (!$langcode_key) {
                throw new MigrateException(sprintf('The "%s" entity type does not support translations.', $this->storage
                    ->getEntityTypeId()));
            }
            $ids[$langcode_key] = $this->getDefinitionFromEntity($langcode_key);
        }
        return $ids;
    }
    
    /**
     * {@inheritdoc}
     */
    public function getHighestId() {
        $values = $this->storage
            ->getQuery()
            ->accessCheck(FALSE)
            ->allRevisions()
            ->sort($this->getKey('revision'), 'DESC')
            ->range(0, 1)
            ->execute();
        // The array keys are the revision IDs.
        // The array contains only one entry, so we can use key().
        return (int) key($values);
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
DependencyTrait::$dependencies protected property The object&#039;s dependencies.
DependencyTrait::addDependencies protected function Adds multiple dependencies.
DependencyTrait::addDependency protected function Adds a dependency.
DestinationBase::$migration protected property The migration.
DestinationBase::$rollbackAction protected property The rollback action to be saved for the last imported item.
DestinationBase::$supportsRollback protected property Indicates whether the destination can be rolled back.
DestinationBase::checkRequirements public function Checks if requirements for this plugin are OK. Overrides RequirementsInterface::checkRequirements
DestinationBase::getDestinationModule public function Gets the destination module handling the destination data. Overrides MigrateDestinationInterface::getDestinationModule 1
DestinationBase::rollbackAction public function The rollback action for the last imported item. Overrides MigrateDestinationInterface::rollbackAction
DestinationBase::setRollbackAction protected function For a destination item being updated, set the appropriate rollback action.
DestinationBase::supportsRollback public function Whether the destination can be rolled back or not. Overrides MigrateDestinationInterface::supportsRollback
Entity::$bundles protected property The list of the bundles of this entity type.
Entity::$entityFieldManager protected property The entity field manager.
Entity::$storage protected property The entity storage.
Entity::calculateDependencies public function Calculates dependencies for the configured plugin. Overrides DependentPluginInterface::calculateDependencies
Entity::fields public function Returns an array of destination fields. Overrides MigrateDestinationInterface::fields
Entity::getBundle public function Gets the bundle for the row taking into account the default.
Entity::getEntityId protected function Gets the entity ID of the row. 2
Entity::getKey protected function Returns a specific entity key.
EntityContentBase::$accountSwitcher protected property The account switcher service.
EntityContentBase::$fieldTypeManager protected property Field type plugin manager.
EntityContentBase::create public static function Creates an instance of the plugin. Overrides Entity::create 2
EntityContentBase::import public function Overrides MigrateDestinationInterface::import 2
EntityContentBase::isEntityValidationRequired public function Returns a state of whether an entity needs to be validated before saving. Overrides MigrateValidatableEntityInterface::isEntityValidationRequired
EntityContentBase::isTranslationDestination public function
EntityContentBase::processStubRow protected function Populates as much of the stub row as possible. Overrides Entity::processStubRow 3
EntityContentBase::rollback public function Delete the specified destination object from the target Drupal. Overrides Entity::rollback 1
EntityContentBase::updateEntity protected function Updates an entity with the new values from row. Overrides Entity::updateEntity 3
EntityContentBase::validateEntity public function Validates the entity. Overrides MigrateValidatableEntityInterface::validateEntity
EntityFieldDefinitionTrait::getDefinitionFromEntity protected function Gets the field definition from a specific entity base field.
EntityFieldDefinitionTrait::getEntityTypeId protected static function Finds the entity type from configuration or plugin ID. 3
EntityRevision::getEntity protected function Gets the entity. Overrides Entity::getEntity 2
EntityRevision::getHighestId public function Returns the highest ID tracked by the implementing plugin. Overrides EntityContentBase::getHighestId
EntityRevision::getIds public function Gets the destination IDs. Overrides EntityContentBase::getIds
EntityRevision::save protected function Saves the entity. Overrides EntityContentBase::save 1
EntityRevision::__construct public function Constructs a content entity. Overrides EntityContentBase::__construct
PluginInspectionInterface::getPluginDefinition public function Gets the definition of the plugin implementation. 6
PluginInspectionInterface::getPluginId public function Gets the plugin_id of the plugin instance. 2

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.