You are here

class MultiversionMigration in Multiversion 8

Hierarchy

Expanded class hierarchy of MultiversionMigration

1 file declares its use of MultiversionMigration
multiversion.install in ./multiversion.install

File

src/MultiversionMigration.php, line 19

Namespace

Drupal\multiversion
View source
class MultiversionMigration implements MultiversionMigrationInterface {

  /**
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * @var \Drupal\Core\Extension\ModuleInstallerInterface
   */
  protected $moduleInstaller;

  /**
   * The database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $connection;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, EntityTypeManagerInterface $entity_type_manager) {
    return new static($container
      ->get('module_handler'), $container
      ->get('module_installer'), $container
      ->get('database'));
  }

  /**
   * Constructor.
   *
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   * @param \Drupal\Core\Extension\ModuleInstallerInterface $module_installer
   * @param \Drupal\Core\Database\Connection $connection
   */
  public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, Connection $connection) {
    $this->moduleHandler = $module_handler;
    $this->moduleInstaller = $module_installer;
    $this->connection = $connection;
  }

  /**
   * {@inheritdoc}
   */
  public function installDependencies() {
    $modules = [
      'migrate',
      'migrate_drupal',
    ];
    foreach ($modules as $i => $module) {
      if ($this->moduleHandler
        ->moduleExists($module)) {
        unset($modules[$i]);
      }
    }
    if (!empty($modules)) {
      $this->moduleInstaller
        ->install($modules, TRUE);
    }
    return $this;
  }

  /**
   * {@inheritdoc}
   *
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   * @param array $field_map
   *
   * @return \Drupal\multiversion\MultiversionMigrationInterface
   */
  public function migrateContentToTemp(EntityTypeInterface $entity_type, $field_map) {
    $id = $entity_type
      ->id() . '__' . MultiversionManager::TO_TMP;
    $definition = [
      'id' => $id,
      'label' => '',
      'process' => $field_map,
      'source' => [
        'plugin' => 'multiversion',
        'translations' => (bool) $entity_type
          ->getKey('langcode'),
      ],
      'destination' => [
        'plugin' => 'tempstore',
        'translations' => (bool) $entity_type
          ->getKey('langcode'),
      ],
    ];
    $migration = \Drupal::service('plugin.manager.migration')
      ->createStubMigration($definition);
    $this
      ->executeMigration($migration);
    return $this;
  }

  /**
   * {@inheritdoc}
   *
   * Usage example:
   * @code
   * // For some specific content types, we are still able to use
   * // a `purge` or `delete` function.
   * if (in_array($this->getEntityTypeId(), ['replication_log'])) {
   *   $original_storage = $storage->getOriginalStorage();
   *   $entities = $original_storage->loadMultiple();
   *   $this->purge($entities);
   * }
   * @endcode
   */
  public function emptyOldStorage(EntityStorageInterface $storage) {
    if ($storage instanceof ContentEntityStorageInterface) {
      $storage
        ->truncate();
    }
    elseif ($storage instanceof FileStorageInterface) {

      // Do not delete file entity from the storage as it deletes physical
      // file - just truncate file managed database table.
      $this->connection
        ->truncate('file_managed')
        ->execute();
    }
    else {
      $entities = $storage
        ->loadMultiple();
      $storage
        ->delete($entities);
    }
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function applyNewStorage(array $entity_type_ids) {
    if (version_compare(\Drupal::VERSION, '8.7', '<')) {

      // The first call is for making entity types revisionable, the second call
      // is for adding required fields.
      \Drupal::entityDefinitionUpdateManager()
        ->applyUpdates();
      \Drupal::entityDefinitionUpdateManager()
        ->applyUpdates();
    }
    else {
      foreach ($entity_type_ids as $entity_type_id) {
        $entity_type = \Drupal::entityTypeManager()
          ->getDefinition($entity_type_id);
        $field_storage_definitions = \Drupal::service('entity_field.manager')
          ->getFieldStorageDefinitions($entity_type_id);
        \Drupal::entityDefinitionUpdateManager()
          ->updateFieldableEntityType($entity_type, $field_storage_definitions);
      }
    }
    return $this;
  }

  /**
   * {@inheritdoc}
   *
   * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type
   * @param array $field_map
   *
   * @return \Drupal\multiversion\MultiversionMigrationInterface
   */
  public function migrateContentFromTemp(EntityTypeInterface $entity_type, $field_map) {
    $id = $entity_type
      ->id() . '__' . MultiversionManager::FROM_TMP;
    $definition = [
      'id' => $id,
      'label' => '',
      'process' => $field_map,
      'source' => [
        'plugin' => 'tempstore',
        'translations' => (bool) $entity_type
          ->getKey('langcode'),
      ],
      'destination' => [
        'plugin' => 'multiversion',
        'translations' => (bool) $entity_type
          ->getKey('langcode'),
      ],
    ];
    $migration = \Drupal::service('plugin.manager.migration')
      ->createStubMigration($definition);
    $this
      ->executeMigration($migration);
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function uninstallDependencies() {
    return $this;
  }

  /**
   * {@inheritdoc}
   */
  public function cleanupMigration($id) {
    \Drupal::service('plugin.manager.migration')
      ->createStubMigration([
      'id' => $id,
    ])
      ->getIdMap()
      ->destroy();
  }

  /**
   * Helper method to fetch the field map for an entity type.
   *
   * @param EntityTypeInterface $entity_type
   * @param string $op
   * @param string $action
   *
   * @return array
   */
  public function getFieldMap(EntityTypeInterface $entity_type, $op, $action) {
    $map = [];

    // For some reasons it sometimes doesn't work if injecting the service.
    $entity_type_bundle_info = \Drupal::service('entity_type.bundle.info');
    $entity_type_bundle_info
      ->clearCachedBundles();
    $bundle_info = $entity_type_bundle_info
      ->getBundleInfo($entity_type
      ->id());
    foreach ($bundle_info as $bundle_id => $bundle_label) {

      // For some reasons it sometimes doesn't work if injecting the service.
      $entity_field_manager = \Drupal::service('entity_field.manager');
      $entity_field_manager
        ->clearCachedFieldDefinitions();
      $definitions = $entity_field_manager
        ->getFieldDefinitions($entity_type
        ->id(), $bundle_id);
      foreach ($definitions as $definition) {
        $name = $definition
          ->getName();

        // We don't want our own fields to be part of the migration mapping or
        // they would get assigned NULL instead of default values.
        if (!in_array($name, [
          'workspace',
          '_deleted',
          '_rev',
        ])) {
          $map[$name] = $name;
        }
      }
    }

    // @todo Implement hook/alter functionality here.
    if (MultiversionManager::OP_DISABLE == $op) {
      $parent_key = 'parent';
      if ('menu_link_content' == $entity_type
        ->id() && isset($map[$parent_key])) {
        $map[$parent_key] = [
          [
            'plugin' => 'splice',
            'delimiter' => ':',
            'source' => $parent_key,
            'strict' => FALSE,
            'slice' => 2,
          ],
        ];
      }
    }
    return $map;
  }

  /**
   * Helper method for running a migration.
   *
   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
   * @return \Drupal\migrate\MigrateExecutableInterface
   */
  protected function executeMigration(MigrationInterface $migration) {

    // Add necessary database connection that the Migrate API needs during
    // a migration like this.
    $connection_info = Database::getConnectionInfo('default');
    foreach ($connection_info as $target => $value) {
      $connection_info[$target]['prefix'] = [
        'default' => $value['prefix']['default'],
      ];
    }
    Database::addConnectionInfo('migrate', 'default', $connection_info['default']);
    $message = new MigrateMessage();
    $executable = new MigrateExecutable($migration, $message);
    $executable
      ->import();
    return $executable;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
MultiversionMigration::$connection protected property The database connection.
MultiversionMigration::$moduleHandler protected property
MultiversionMigration::$moduleInstaller protected property
MultiversionMigration::applyNewStorage public function Converts the entity storage to revisionable for the given entity type IDs. Overrides MultiversionMigrationInterface::applyNewStorage
MultiversionMigration::cleanupMigration public function Removes the map and message tables for a migration. Overrides MultiversionMigrationInterface::cleanupMigration
MultiversionMigration::create public static function Factory method. Overrides MultiversionMigrationInterface::create
MultiversionMigration::emptyOldStorage public function Usage example: Overrides MultiversionMigrationInterface::emptyOldStorage
MultiversionMigration::executeMigration protected function Helper method for running a migration.
MultiversionMigration::getFieldMap public function Helper method to fetch the field map for an entity type. Overrides MultiversionMigrationInterface::getFieldMap
MultiversionMigration::installDependencies public function Overrides MultiversionMigrationInterface::installDependencies
MultiversionMigration::migrateContentFromTemp public function Overrides MultiversionMigrationInterface::migrateContentFromTemp
MultiversionMigration::migrateContentToTemp public function Overrides MultiversionMigrationInterface::migrateContentToTemp
MultiversionMigration::uninstallDependencies public function Overrides MultiversionMigrationInterface::uninstallDependencies
MultiversionMigration::__construct public function Constructor.