Updated all the contrib modules to their latest versions.
[yaffs-website] / web / modules / contrib / migrate_upgrade / src / MigrateUpgradeDrushRunner.php
index 7196c2c4c0237df0ef69d7a929e3c52b47e74ce9..b219f2f1b651d217a0557a584bfe7fcd9cfe722d 100644 (file)
@@ -2,6 +2,7 @@
 
 namespace Drupal\migrate_upgrade;
 
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
 use Drupal\migrate\Plugin\MigrationInterface;
 use Drupal\migrate\Event\MigrateEvents;
 use Drupal\migrate\Event\MigrateIdMapMessageEvent;
@@ -11,6 +12,7 @@ use Drupal\migrate_drupal\MigrationConfigurationTrait;
 use Drupal\migrate_plus\Entity\Migration;
 use Drupal\migrate_plus\Entity\MigrationGroup;
 use Drupal\Core\Database\Database;
+use Drush\Sql\SqlBase;
 
 class MigrateUpgradeDrushRunner {
 
@@ -50,7 +52,21 @@ class MigrateUpgradeDrushRunner {
    *
    * @var array
    */
-  protected $nodeMigrations = [];
+  protected $d6NodeMigrations = [];
+
+  /**
+   * List of D6 node revision migration IDs we've seen.
+   *
+   * @var array
+   */
+  protected $d6RevisionMigrations = [];
+
+  /**
+   * Drush options parameters.
+   *
+   * @var array
+   */
+  protected $options = [];
 
   /**
    * List of process plugin IDs used to lookup migrations.
@@ -62,6 +78,37 @@ class MigrateUpgradeDrushRunner {
     'migration_lookup',
   ];
 
+  /**
+   * MigrateUpgradeDrushRunner constructor.
+   *
+   * @param array $options
+   *   Drush options parameters.
+   */
+  public function __construct(array $options = []) {
+    $this->setOptions($options);
+  }
+
+  /**
+   * Set options parameters according to Drush version.
+   *
+   * @param array $options
+   *   Drush options parameters.
+   */
+  protected function setOptions(array $options = []) {
+    $this->options = $options;
+    // Drush <= 8.
+    if (empty($this->options)) {
+      $this->options = [
+        'legacy_db_key' => drush_get_option('legacy-db-key'),
+        'legacy-db-url' => drush_get_option('legacy-db-url'),
+        'legacy-db-prefix' => drush_get_option('legacy-db-prefix'),
+        'legacy-root' => drush_get_option('legacy-root'),
+        'debug' => drush_get_option('debug'),
+        'migration-prefix' => drush_get_option('migration-prefix', 'upgrade_'),
+      ];
+    }
+  }
+
   /**
    * From the provided source information, instantiate the appropriate migrations
    * in the active configuration.
@@ -69,19 +116,19 @@ class MigrateUpgradeDrushRunner {
    * @throws \Exception
    */
   public function configure() {
-    $legacy_db_key = drush_get_option('legacy-db-key');
+    $legacy_db_key = $this->options['legacy-db-key'];
+    $db_url = $this->options['legacy-db-url'];
+    $db_prefix = $this->options['legacy-db-prefix'];
     if (!empty($legacy_db_key)) {
-      $connection = Database::getConnection('default', drush_get_option('legacy-db-key'));
+      $connection = Database::getConnection('default', $legacy_db_key);
       $this->version = $this->getLegacyDrupalVersion($connection);
-      $database_state['key'] = drush_get_option('legacy-db-key');
+      $database_state['key'] = $legacy_db_key;
       $database_state_key = 'migrate_drupal_' . $this->version;
       \Drupal::state()->set($database_state_key, $database_state);
       \Drupal::state()->set('migrate.fallback_state_key', $database_state_key);
     }
     else {
-      $db_url = drush_get_option('legacy-db-url');
-      $db_spec = drush_convert_db_from_db_url($db_url);
-      $db_prefix = drush_get_option('legacy-db-prefix');
+      $db_spec = SqlBase::dbSpecFromDbUrl($db_url);
       $db_spec['prefix'] = $db_prefix;
       $connection = $this->getConnection($db_spec);
       $this->version = $this->getLegacyDrupalVersion($connection);
@@ -94,6 +141,7 @@ class MigrateUpgradeDrushRunner {
     foreach ($migrations as $migration) {
       $this->applyFilePath($migration);
       $this->expandNodeMigrations($migration);
+      $this->prefixFileMigration($migration);
       $this->migrationList[$migration->id()] = $migration;
     }
   }
@@ -108,7 +156,7 @@ class MigrateUpgradeDrushRunner {
     $destination = $migration->getDestinationConfiguration();
     if ($destination['plugin'] === 'entity:file') {
       // Make sure we have a single trailing slash.
-      $source_base_path = rtrim(drush_get_option('legacy-root'), '/') . '/';
+      $source_base_path = rtrim($this->options['legacy-root'], '/') . '/';
       $source = $migration->getSourceConfiguration();
       $source['constants']['source_base_path'] = $source_base_path;
       $migration->set('source', $source);
@@ -123,30 +171,59 @@ class MigrateUpgradeDrushRunner {
    */
   protected function expandNodeMigrations(MigrationInterface $migration) {
     $source = $migration->getSourceConfiguration();
-    // Track the node migrations as we see them.
+    // Track the node and node_revision migrations as we see them.
     if ($source['plugin'] == 'd6_node') {
-      $this->nodeMigrations[] = $migration->id();
+      $this->d6NodeMigrations[] = $migration->id();
     }
-    elseif ($source['plugin'] == 'd6_term_node' || $source['plugin'] == 'd6_term_node_revision') {
-      if ($source['plugin'] == 'd6_term_node') {
-        $id_property = 'nid';
-      }
-      else {
-        $id_property = 'vid';
-      }
+    elseif ($source['plugin'] == 'd6_node_revision') {
+      $this->d6RevisionMigrations[] = $migration->id();
+    }
+    elseif ($source['plugin'] == 'd6_term_node') {
       // If the ID mapping is to the underived d6_node migration, replace
       // it with an expanded list of node migrations.
       $process = $migration->getProcess();
       $new_nid_process = [];
-      foreach ($process[$id_property] as $delta => $plugin_configuration) {
+      foreach ($process['nid'] as $delta => $plugin_configuration) {
         if (in_array($plugin_configuration['plugin'], $this->migrationLookupPluginIds) &&
             is_string($plugin_configuration['migration']) &&
             substr($plugin_configuration['migration'], -7) == 'd6_node') {
-          $plugin_configuration['migration'] = $this->nodeMigrations;
+          $plugin_configuration['migration'] = $this->d6NodeMigrations;
         }
         $new_nid_process[$delta] = $plugin_configuration;
       }
-      $migration->setProcessOfProperty($id_property, $new_nid_process);
+      $migration->setProcessOfProperty('nid', $new_nid_process);
+    }
+    elseif ($source['plugin'] == 'd6_term_node_revision') {
+      // If the ID mapping is to the underived d6_node_revision migration, replace
+      // it with an expanded list of node migrations.
+      $process = $migration->getProcess();
+      $new_vid_process = [];
+      foreach ($process['vid'] as $delta => $plugin_configuration) {
+        if (in_array($plugin_configuration['plugin'], $this->migrationLookupPluginIds) &&
+            is_string($plugin_configuration['migration']) &&
+            substr($plugin_configuration['migration'], -16) == 'd6_node_revision') {
+          $plugin_configuration['migration'] = $this->d6RevisionMigrations;
+        }
+        $new_vid_process[$delta] = $plugin_configuration;
+      }
+      $migration->setProcessOfProperty('vid', $new_vid_process);
+    }
+  }
+
+  /**
+   * For D6 file fields, make sure the d6_file migration is prefixed.
+   *
+   * @param \Drupal\migrate\Plugin\MigrationInterface $migration
+   *   Migration to alter.
+   */
+  protected function prefixFileMigration(MigrationInterface $migration) {
+    $process = $migration->getProcess();
+    foreach ($process as $destination => &$plugins) {
+      foreach ($plugins as &$plugin) {
+        if ($plugin['plugin'] == 'd6_field_file') {
+          $plugin['migration'] = $this->modifyId($plugin['migration']);
+        }
+      }
     }
   }
 
@@ -155,7 +232,7 @@ class MigrateUpgradeDrushRunner {
    */
   public function import() {
     static::$messages = new DrushLogMigrateMessage();
-    if (drush_get_option('debug')) {
+    if ($this->options['debug']) {
       \Drupal::service('event_dispatcher')->addListener(MigrateEvents::IDMAP_MESSAGE,
         [get_class(), 'onIdMapMessage']);
     }
@@ -174,7 +251,7 @@ class MigrateUpgradeDrushRunner {
     $db_info = \Drupal::state()->get($this->databaseStateKey);
 
     // Create a group to hold the database configuration.
-    $group = [
+    $group_details = [
       'id' => $this->databaseStateKey,
       'label' => 'Import from Drupal ' . $this->version,
       'description' => 'Migrations originally generated from drush migrate-upgrade --configure-only',
@@ -182,53 +259,88 @@ class MigrateUpgradeDrushRunner {
       'shared_configuration' => [
         'source' => [
           'key' => 'drupal_' . $this->version,
-        ]
-      ]
+        ],
+      ],
     ];
 
     // Only add the database connection info to the configuration entity
     // if it was passed in as a parameter.
-    if (!empty(drush_get_option('legacy-db-url'))) {
-      $group['shared_configuration']['source']['database'] = $db_info['database'];
+    if (!empty($this->options['legacy-db-url'])) {
+      $group_details['shared_configuration']['source']['database'] = $db_info['database'];
     }
 
     // Ditto for the key.
-    if (!empty(drush_get_option('legacy-db-key'))) {
-      $group['shared_configuration']['source']['key'] = drush_get_option('legacy-db-key');
+    if (!empty($this->options['legacy-db-key'])) {
+      $group_details['shared_configuration']['source']['key'] = $this->options['legacy-db-key'];
     }
 
-    $group = MigrationGroup::create($group);
+    // Load existing migration group and update it with changed settings,
+    // or create a new one if none exists.
+    $group = MigrationGroup::load($group_details['id']);
+    if (empty($group)) {
+      $group = MigrationGroup::create($group_details);
+    }
+    else {
+      $this->setEntityProperties($group, $group_details);
+    }
     $group->save();
     foreach ($this->migrationList as $migration_id => $migration) {
       drush_print(dt('Exporting @migration as @new_migration',
         ['@migration' => $migration_id, '@new_migration' => $this->modifyId($migration_id)]));
-      $entity_array['id'] = $migration_id;
-      $entity_array['class'] = $migration->get('class');
-      $entity_array['cck_plugin_method'] = $migration->get('cck_plugin_method');
-      $entity_array['field_plugin_method'] = $migration->get('field_plugin_method');
-      $entity_array['migration_group'] = $this->databaseStateKey;
-      $entity_array['migration_tags'] = $migration->get('migration_tags');
-      $entity_array['label'] = $migration->get('label');
-      $entity_array['source'] = $migration->getSourceConfiguration();
-      $entity_array['destination'] = $migration->getDestinationConfiguration();
-      $entity_array['process'] = $migration->get('process');
-      $entity_array['migration_dependencies'] = $migration->getMigrationDependencies();
-      $migration_entity = Migration::create($this->substituteIds($entity_array));
+      $migration_details['id'] = $migration_id;
+      $migration_details['class'] = $migration->get('class');
+      $migration_details['cck_plugin_method'] = $migration->get('cck_plugin_method');
+      $migration_details['field_plugin_method'] = $migration->get('field_plugin_method');
+      $migration_details['migration_group'] = $this->databaseStateKey;
+      $migration_details['migration_tags'] = $migration->get('migration_tags');
+      $migration_details['label'] = $migration->get('label');
+      $migration_details['source'] = $migration->getSourceConfiguration();
+      $migration_details['destination'] = $migration->getDestinationConfiguration();
+      $migration_details['process'] = $migration->get('process');
+      $migration_details['migration_dependencies'] = $migration->getMigrationDependencies();
+      $migration_details = $this->substituteIds($migration_details);
+      $migration_entity = Migration::load($migration_details['id']);
+      if (empty($migration_entity)) {
+        $migration_entity = Migration::create($migration_details);
+      }
+      else {
+        $this->setEntityProperties($migration_entity, $migration_details);
+      }
       $migration_entity->save();
     }
   }
 
+  /**
+   * Set entity properties.
+   *
+   * @param ConfigEntityInterface $entity
+   *   The entity to update.
+   * @param array $properties
+   *   The properties to update.
+   */
+  protected function setEntityProperties(ConfigEntityInterface $entity, array $properties) {
+    foreach ($properties as $key => $value) {
+      $entity->set($key, $value);
+    }
+    foreach ($entity as $property => $value) {
+      // Filter out values not in updated properties.
+      if (!isset($properties[$property])) {
+        $entity->set($property, NULL);
+      }
+    }
+  }
+
   /**
    * Rewrite any migration plugin IDs so they won't conflict with the core
    * IDs.
    *
-   * @param $entity_array
+   * @param array $entity_array
    *   A configuration array for a migration.
    *
    * @return array
    *   The migration configuration array modified with new IDs.
    */
-  protected function substituteIds($entity_array) {
+  protected function substituteIds(array $entity_array) {
     $entity_array['id'] = $this->modifyId($entity_array['id']);
     foreach ($entity_array['migration_dependencies'] as $type => $dependencies) {
       foreach ($dependencies as $key => $dependency) {
@@ -286,7 +398,7 @@ class MigrateUpgradeDrushRunner {
    *   The ID modified to serve as a configuration entity ID.
    */
   protected function modifyId($id) {
-    return drush_get_option('migration-prefix', 'upgrade_') . str_replace(':', '_', $id);
+    return $this->options['migration-prefix'] . str_replace(':', '_', $id);
   }
 
   /**