From 1af6f9fc8bbce4d408e6f14e14803f9cb634bb05 Mon Sep 17 00:00:00 2001 From: Mike Ryan <mike.ryan@acquia.com> Date: Mon, 10 Aug 2015 15:55:58 -0500 Subject: [PATCH] Issue #2432981: Implemented --update option for migrate-import command --- migrate_tools/migrate_tools.drush.inc | 6 +++ migrate_tools/src/MigrateExecutable.php | 64 +++++++++++++++++++++---- 2 files changed, 60 insertions(+), 10 deletions(-) diff --git a/migrate_tools/migrate_tools.drush.inc b/migrate_tools/migrate_tools.drush.inc index 554b7389..9d62c4e0 100644 --- a/migrate_tools/migrate_tools.drush.inc +++ b/migrate_tools/migrate_tools.drush.inc @@ -40,6 +40,7 @@ function migrate_tools_drush_command() { 'all' => 'Process all migrations.', 'group' => 'Name of the migration group to import', 'feedback' => 'Frequency of progress messages, in items processed', + 'update' => ' In addition to processing unprocessed items from the source, update previously-imported items with the current data', ), 'arguments' => array( 'migration' => 'Name of migration(s) to import. Delimit multiple using commas.', @@ -162,6 +163,8 @@ function drush_migrate_tools_migrate_import($migration_names = '') { $options['feedback'] = drush_get_option('feedback'); } + $update = drush_get_option('update'); + $log = new DrushLogMigrateMessage(); $migrations = drush_migrate_tools_migration_list($group_name, $migration_names); @@ -169,6 +172,9 @@ function drush_migrate_tools_migrate_import($migration_names = '') { // Take it one group at a time, importing the migrations within each group. foreach ($migrations as $group_id => $migration_list) { foreach ($migration_list as $migration_id => $migration) { + if ($update) { + $migration->getIdMap()->prepareUpdate(); + } $executable = new MigrateExecutable($migration, $log, $options); // drush_op() provides --simulate support. drush_op(array($executable, 'import')); diff --git a/migrate_tools/src/MigrateExecutable.php b/migrate_tools/src/MigrateExecutable.php index 94f24575..964109df 100644 --- a/migrate_tools/src/MigrateExecutable.php +++ b/migrate_tools/src/MigrateExecutable.php @@ -7,6 +7,7 @@ namespace Drupal\migrate_tools; +use Drupal\migrate\Event\MigratePreRowSaveEvent; use Drupal\migrate\MigrateExecutable as MigrateExecutableBase; use Drupal\migrate\MigrateMessageInterface; use Drupal\migrate\Entity\MigrationInterface; @@ -60,6 +61,13 @@ class MigrateExecutable extends MigrateExecutableBase { */ protected $counter = 0; + /** + * Whether the destination item exists before saving. + * + * @var bool + */ + protected $preExistingItem = FALSE; + /** * {@inheritdoc} */ @@ -74,8 +82,10 @@ class MigrateExecutable extends MigrateExecutableBase { array($this, 'onMapDelete')); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_IMPORT, array($this, 'onPostImport')); + \Drupal::service('event_dispatcher')->addListener(MigrateEvents::PRE_ROW_SAVE, + array($this, 'onPreRowSave')); \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_ROW_SAVE, - array($this, 'onPostSave')); + array($this, 'onPostRowSave')); } /** @@ -86,7 +96,14 @@ class MigrateExecutable extends MigrateExecutableBase { */ public function onMapSave(MigrateMapSaveEvent $event) { $fields = $event->getFields(); - $this->saveCounters[$fields['source_row_status']]++; + // Distinguish between creation and update. + if ($fields['source_row_status'] == MigrateIdMapInterface::STATUS_IMPORTED && + $this->preExistingItem) { + $this->saveCounters[MigrateIdMapInterface::STATUS_NEEDS_UPDATE]++; + } + else { + $this->saveCounters[$fields['source_row_status']]++; + } } /** @@ -100,14 +117,23 @@ class MigrateExecutable extends MigrateExecutableBase { } /** - * Return the number of items imported. + * Return the number of items created. * * @return int */ - public function getImportedCount() { + public function getCreatedCount() { return $this->saveCounters[MigrateIdMapInterface::STATUS_IMPORTED]; } + /** + * Return the number of items updated. + * + * @return int + */ + public function getUpdatedCount() { + return $this->saveCounters[MigrateIdMapInterface::STATUS_NEEDS_UPDATE]; + } + /** * Return the number of items ignored. * @@ -135,6 +161,7 @@ class MigrateExecutable extends MigrateExecutableBase { */ public function getProcessedCount() { return $this->saveCounters[MigrateIdMapInterface::STATUS_IMPORTED] + + $this->saveCounters[MigrateIdMapInterface::STATUS_NEEDS_UPDATE] + $this->saveCounters[MigrateIdMapInterface::STATUS_IGNORED] + $this->saveCounters[MigrateIdMapInterface::STATUS_FAILED]; } @@ -179,29 +206,46 @@ class MigrateExecutable extends MigrateExecutableBase { protected function progressMessage($done = TRUE) { $processed = $this->getProcessedCount(); if ($done) { - $singular_message = "Processed 1 item (!successes successfully, !failures failed, !ignored ignored) - done with '!name'"; - $plural_message = "Processed !numitems items (!successes successfully, !failures failed, !ignored ignored) - done with '!name'"; + $singular_message = "Processed 1 item (!created created, !updated updated, !failures failed, !ignored ignored) - done with '!name'"; + $plural_message = "Processed !numitems items (!created created, !updated updated, !failures failed, !ignored ignored) - done with '!name'"; } else { - $singular_message = "Processed 1 item (!successes successfully, !failures failed, !ignored ignored) - continuing with '!name'"; - $plural_message = "Processed !numitems items (!successes successfully, !failures failed, !ignored ignored) - continuing with '!name'"; + $singular_message = "Processed 1 item (!created created, !updated updated, !failures failed, !ignored ignored) - continuing with '!name'"; + $plural_message = "Processed !numitems items (!created created, !updated updated, !failures failed, !ignored ignored) - continuing with '!name'"; } $this->message->display(\Drupal::translation()->formatPlural($processed, $singular_message, $plural_message, array('!numitems' => $processed, - '!successes' => $this->getImportedCount(), + '!created' => $this->getCreatedCount(), + '!updated' => $this->getUpdatedCount(), '!failures' => $this->getFailedCount(), '!ignored' => $this->getIgnoredCount(), '!name' => $this->migration->id()))); } + /** + * React to an item about to be imported. + * + * @param \Drupal\migrate\Event\MigratePreRowSaveEvent $event + * The pre-save event. + */ + public function onPreRowSave(MigratePreRowSaveEvent $event) { + $id_map = $event->getRow()->getIdMap(); + if (!empty($id_map['destid1'])) { + $this->preExistingItem = TRUE; + } + else { + $this->preExistingItem = FALSE; + } + } + /** * React to item import. * * @param \Drupal\migrate\Event\MigratePostRowSaveEvent $event * The post-save event. */ - public function onPostSave(MigratePostRowSaveEvent $event) { + public function onPostRowSave(MigratePostRowSaveEvent $event) { if ($this->feedback && ($this->counter) && $this->counter % $this->feedback == 0) { $this->progressMessage(FALSE); $this->resetCounters(); -- GitLab