diff --git a/src/Controller/MigrateController.php b/src/Controller/MigrateController.php index b0d13d2..bdb149a 100644 --- a/src/Controller/MigrateController.php +++ b/src/Controller/MigrateController.php @@ -1,7 +1,8 @@ 'migrate_upgrade']; return $this->redirect('dblog.overview'); } + } diff --git a/src/Form/MigrateUpgradeForm.php b/src/Form/MigrateUpgradeForm.php index eb74e69..416886c 100644 --- a/src/Form/MigrateUpgradeForm.php +++ b/src/Form/MigrateUpgradeForm.php @@ -7,33 +7,43 @@ namespace Drupal\migrate_upgrade\Form; -use Drupal\Core\Form\ConfirmFormHelper; -use Drupal\Core\Form\ConfirmFormInterface; -use Drupal\Core\Form\FormBase; +use Drupal\Core\Datetime\DateFormatterInterface; +use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Form\ConfirmFormBase; use Drupal\Core\Form\FormStateInterface; +use Drupal\Core\Render\RendererInterface; +use Drupal\Core\State\StateInterface; use Drupal\Core\Url; use Drupal\migrate\Entity\Migration; +use Drupal\migrate_upgrade\MigrateUpgradeRunBatch; use Drupal\migrate_upgrade\MigrationCreationTrait; +use Symfony\Component\DependencyInjection\ContainerInterface; /** - * Multi-step form for performing direct site upgrades. + * Defines a multi-step form for performing direct site upgrades. */ -class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { +class MigrateUpgradeForm extends ConfirmFormBase { use MigrationCreationTrait; /** - * The choices of what to do when an upgrade has previously been run. + * If a migration has previously run, perform an incremental migration. */ const MIGRATE_UPGRADE_INCREMENTAL = 1; + + /** + * If a migration has previously run, roll it back and start fresh. + */ const MIGRATE_UPGRADE_ROLLBACK = 2; /** - * @todo: Hardcoding this information is not robust - the migrations - * themselves should hold the necessary information. - * @see https://www.drupal.org/node/2569805 + * Mapping of known migrations and their source and destination modules. + * + * @todo https://www.drupal.org/node/2569805 Hardcoding this information is + * not robust - the migrations themselves should hold the necessary + * information. * - * @var array + * @var array[] */ protected $moduleUpgradePaths = [ 'd6_action_settings' => [ @@ -587,6 +597,65 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { ]; /** + * The state service. + * + * @var \Drupal\Core\State\StateInterface + */ + protected $state; + + /** + * The date formatter service. + * + * @var \Drupal\Core\Datetime\DateFormatterInterface + */ + protected $dateFormatter; + + /** + * The renderer service. + * + * @var \Drupal\Core\Render\RendererInterface + */ + protected $renderer; + + /** + * The migration entity storage. + * + * @var \Drupal\Core\Entity\EntityStorageInterface + */ + protected $entityStorage; + + /** + * MigrateUpgradeForm constructor. + * + * @param \Drupal\Core\State\StateInterface $state + * The state service. + * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter + * The date formatter service. + * @param \Drupal\Core\Render\RendererInterface $renderer + * The renderer service. + * @param \Drupal\Core\Entity\EntityStorageInterface $entity_storage + * The migration entity storage. + */ + public function __construct(StateInterface $state, DateFormatterInterface $date_formatter, RendererInterface $renderer, EntityStorageInterface $entity_storage) { + $this->state = $state; + $this->dateFormatter = $date_formatter; + $this->renderer = $renderer; + $this->entityStorage = $entity_storage; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('state'), + $container->get('date.formatter'), + $container->get('renderer'), + $container->get('entity_type.manager')->getStorage('migration') + ); + } + + /** * {@inheritdoc} */ public function getFormId() { @@ -609,8 +678,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { return $this->buildConfirmForm($form, $form_state); default: - drupal_set_message($this->t('Unrecognized form step @step', - ['@step' => $step]), 'error'); + drupal_set_message($this->t('Unrecognized form step @step', ['@step' => $step]), 'error'); return []; } } @@ -618,10 +686,13 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { /** * {@inheritdoc} */ - public function submitForm(array &$form, FormStateInterface $form_state) {} + public function submitForm(array &$form, FormStateInterface $form_state) { + // This method is intentionally empty, see the specific submit methods for + // each form step. + } /** - * Build the form presenting an overview of the migration process. + * Builds the form presenting an overview of the migration process. * * @param array $form * An associative array containing the structure of the form. @@ -634,12 +705,11 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { public function buildOverviewForm(array $form, FormStateInterface $form_state) { $form['#title'] = $this->t('Drupal Upgrade'); - if ($date_performed = \Drupal::state()->get('migrate_upgrade.performed')) { + if ($date_performed = $this->state->get('migrate_upgrade.performed')) { $form['upgrade_option_item'] = [ '#type' => 'item', - '#prefix' => t('

An upgrade has already been performed on this site.

'), - '#description' => t('

Last upgrade: @date

', - ['@date' => \Drupal::service('date.formatter')->format($date_performed)]), + '#prefix' => $this->t('

An upgrade has already been performed on this site.

'), + '#description' => $this->t('

Last upgrade: @date

', ['@date' => $this->dateFormatter->format($date_performed)]), ]; $form['upgrade_option'] = array( '#type' => 'radios', @@ -664,9 +734,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { $info[] = $this->t('If your previous site has private files to be migrated, a copy of your files directory must be accessible on the host this site is on.'); $info[] = $this->t('In general, enable all modules on this site that are enabled on the previous site. For example, if you have used the book module on the previous site then you must enable the book module on this site for that data to be available on this site.'); $info[] = $this->t('Put this site into maintenance mode.', [ - ':url' => Url::fromRoute('system.site_maintenance_mode') - ->toString(TRUE) - ->getGeneratedUrl(), + ':url' => Url::fromRoute('system.site_maintenance_mode')->toString(TRUE)->getGeneratedUrl(), ]); $form['info'] = [ @@ -694,7 +762,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { } /** - * Overview form submission handler. + * Form submission handler for the overview form. * * @param array $form * An associative array containing the structure of the form. @@ -719,8 +787,9 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { } /** - * Build the form gathering database credential and file location information. - * This is largely borrowed from SiteSettingsForm. + * Builds the database credential form and adds file location information. + * + * This is largely borrowed from \Drupal\Core\Installer\Form\SiteSettingsForm. * * @param array $form * An associative array containing the structure of the form. @@ -729,14 +798,14 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { * * @return array * The form structure. + * + * @todo Private files directory not yet implemented, depends on + * https://www.drupal.org/node/2547125. */ public function buildCredentialForm(array $form, FormStateInterface $form_state) { - // Make sure the install API is available. - include_once DRUPAL_ROOT . '/core/includes/install.inc'; - $form['#title'] = $this->t('Drupal Upgrade'); - $drivers = drupal_get_database_types(); + $drivers = $this->getDatabaseTypes(); $drivers_keys = array_keys($drivers); // @todo https://www.drupal.org/node/2678510 Because this is a multi-step // form, the form is not rebuilt during submission. Ideally we would get @@ -764,7 +833,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { $form['database']['driver']['#disabled'] = TRUE; } - // Add driver specific configuration options. + // Add driver-specific configuration options. foreach ($drivers as $key => $driver) { $form['database']['driver']['#options'][$key] = $driver->name(); @@ -806,15 +875,6 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { '#description' => $this->t('To import files from your current Drupal site, enter a local file directory containing your site (e.g. /var/www/docroot), or your site address (e.g. http://example.com).'), ]; - /* - // @todo: Not yet implemented, depends on https://www.drupal.org/node/2547125. - $form['files']['private_file_directory'] = [ - '#type' => 'textfield', - '#title' => $this->t('Private file path'), - '#description' => $this->t('To import private files from your current Drupal site, enter a local file directory containing your files (e.g. /var/private_files).'), - ]; - */ - $form['actions'] = ['#type' => 'actions']; $form['actions']['save'] = [ '#type' => 'submit', @@ -827,7 +887,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { } /** - * Credential form validation handler. + * Validation handler for the credentials form. * * @param array $form * An associative array containing the structure of the form. @@ -862,22 +922,23 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { } } else { + $database = []; // Find a migration which has database credentials and use those. - $query = \Drupal::entityQuery('migration', 'OR'); + $query = $this->entityStorage->getQuery('OR'); $ids = $query->execute(); foreach ($ids as $id) { - /** @var MigrationInterface $migration */ + /** @var \Drupal\migrate\Entity\MigrationInterface $migration */ $migration = Migration::load($id); $is_drupal_migration = FALSE; foreach ($migration->get('migration_tags') as $migration_tag) { - if (substr($migration_tag, 0, 7) == 'Drupal ') { + if (substr($migration_tag, 0, 7) === 'Drupal ') { $is_drupal_migration = TRUE; break; } } if ($is_drupal_migration) { $source = $migration->get('source'); - if ($database = \Drupal::state()->get($source['database_state_key'])['database']) { + if ($database = $this->state->get($source['database_state_key'])['database']) { break; } } @@ -885,7 +946,6 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { } try { - // Get the template for migration. $migration_template = $this->getMigrationTemplates($database, $form_state->getValue('source_base_path')); @@ -897,6 +957,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { // Convert the migration object into array // so that it can be stored in form storage. + $migration_array = []; foreach ($migrations as $migration) { $migration_array[] = $migration->toArray(); } @@ -922,12 +983,12 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { ], ]; - $form_state->setErrorByName($database['driver'] . '][0', \Drupal::service('renderer')->renderPlain($error_message)); + $form_state->setErrorByName($database['driver'] . '][0', $this->renderer->renderPlain($error_message)); } } /** - * Credential form submission handler. + * Submission handler for the credentials form. * * @param array $form * An associative array containing the structure of the form. @@ -941,7 +1002,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { } /** - * Build the form gathering database credential and file location information. + * Confirmation form for rollbacks, missing migrations, etc. * * @param array $form * An associative array containing the structure of the form. @@ -952,21 +1013,19 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { * The form structure. */ public function buildConfirmForm(array $form, FormStateInterface $form_state) { - $rollback = $form_state->getValue('upgrade_option') == static::MIGRATE_UPGRADE_ROLLBACK; - if ($rollback) { - $form_state->setStorage(['upgrade_option' => static::MIGRATE_UPGRADE_ROLLBACK]); - } - $form['#title'] = $this->getQuestion(); - - $form['#attributes']['class'][] = 'confirmation'; - $form[$this->getFormName()] = ['#type' => 'hidden', '#value' => 1]; + $form = parent::buildForm($form, $form_state); + $form['actions']['submit']['#submit'] = ['::submitConfirmForm']; - if ($rollback) { + if ($rollback = $form_state->getValue('upgrade_option') == static::MIGRATE_UPGRADE_ROLLBACK) { + $form_state->setStorage(['upgrade_option' => static::MIGRATE_UPGRADE_ROLLBACK]); $form['rollback'] = [ '#markup' => $this->t('All previously-imported content, as well as configuration such as field definitions, will be removed.'), ]; + $form['actions']['submit']['#value'] = $this->t('Perform rollback'); } else { + $form['actions']['submit']['#value'] = $this->t('Perform upgrade'); + $table_data = []; $system_data = []; foreach ($form_state->get('migration') as $migration) { @@ -989,8 +1048,8 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { // Missing migrations. $form['missing_module_list_title'] = [ '#type' => 'item', - '#title' => t('Missing upgrade paths'), - '#description' => $this->t('The following items will not be upgraded. For more information see Upgrading from Drupal 6 or 7 to Drupal 8.', [':url' => 'https://www.drupal.org/upgrade/migrate']), + '#title' => $this->t('Missing upgrade paths'), + '#description' => $this->t('The following items will not be upgraded. For more information see Upgrading from Drupal 6 or 7 to Drupal 8.'), ]; $form['missing_module_list'] = [ '#type' => 'table', @@ -1014,7 +1073,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { $form['available_module_list'] = [ '#tree' => TRUE, '#type' => 'details', - '#title' => t('Available upgrade paths'), + '#title' => $this->t('Available upgrade paths'), ]; $form['available_module_list']['module_list'] = [ @@ -1032,7 +1091,7 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { foreach ($destination_module_info as $destination_module => $migration_ids) { $destination_details[$destination_module] = [ '#type' => 'item', - '#plain_text' => $this->t($destination_module), + '#plain_text' => $destination_module, ]; } $form['available_module_list']['module_list'][$source_module] = [ @@ -1046,32 +1105,12 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { '#weight' => -15, ]; } - if ($rollback) { - $confirm_text = $this->t('Perform rollback'); - } - else { - $confirm_text = $this->t('Perform upgrade'); - } - $form['actions'] = ['#type' => 'actions']; - $form['actions']['submit'] = [ - '#type' => 'submit', - '#value' => $confirm_text, - '#button_type' => 'primary', - '#validate' => [], - '#submit' => ['::submitConfirmForm'], - ]; - - $form['actions']['cancel'] = ConfirmFormHelper::buildCancelLink($this, $this->getRequest()); - // By default, render the form using theme_confirm_form(). - if (!isset($form['#theme'])) { - $form['#theme'] = 'confirm_form'; - } return $form; } /** - * Credential form submission handler. + * Submission handler for the confirmation form. * * @param array $form * An associative array containing the structure of the form. @@ -1081,14 +1120,12 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { public function submitConfirmForm(array &$form, FormStateInterface $form_state) { $storage = $form_state->getStorage(); if (isset($storage['upgrade_option']) && $storage['upgrade_option'] == static::MIGRATE_UPGRADE_ROLLBACK) { - $query = \Drupal::entityQuery('migration'); + $query = $this->entityStorage->getQuery(); $names = $query->execute(); // Order the migrations according to their dependencies. - /** @var MigrationInterface[] $migrations */ - $migrations = \Drupal::entityManager() - ->getStorage('migration') - ->loadMultiple($names); + /** @var \Drupal\migrate\Entity\MigrationInterface[] $migrations */ + $migrations = $this->entityStorage->loadMultiple($names); // Assume we want all those tagged 'Drupal %'. foreach ($migrations as $migration_id => $migration) { $keep = FALSE; @@ -1111,18 +1148,18 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { 'progress_message' => '', 'operations' => [ [ - ['Drupal\migrate_upgrade\MigrateUpgradeRunBatch', 'run'], + [MigrateUpgradeRunBatch::class, 'run'], [array_keys($migrations), 'rollback'], ], ], 'finished' => [ - 'Drupal\migrate_upgrade\MigrateUpgradeRunBatch', + MigrateUpgradeRunBatch::class, 'finished', ], ]; batch_set($batch); $form_state->setRedirect('migrate_upgrade.upgrade'); - \Drupal::state()->delete('migrate_upgrade.performed'); + $this->state->delete('migrate_upgrade.performed'); } else { $migration_template = $storage['migration_template']; @@ -1132,18 +1169,18 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { 'progress_message' => '', 'operations' => [ [ - ['Drupal\migrate_upgrade\MigrateUpgradeRunBatch', 'run'], + [MigrateUpgradeRunBatch::class, 'run'], [$migration_ids, 'import'], ], ], 'finished' => [ - 'Drupal\migrate_upgrade\MigrateUpgradeRunBatch', + MigrateUpgradeRunBatch::class, 'finished', ], ]; batch_set($batch); $form_state->setRedirect(''); - \Drupal::state()->set('migrate_upgrade.performed', REQUEST_TIME); + $this->state->set('migrate_upgrade.performed', REQUEST_TIME); } } @@ -1187,18 +1224,4 @@ class MigrateUpgradeForm extends FormBase implements ConfirmFormInterface { return $this->t('Perform upgrade'); } - /** - * {@inheritdoc} - */ - public function getCancelText() { - return $this->t('Cancel'); - } - - /** - * {@inheritdoc} - */ - public function getFormName() { - return 'confirm'; - } - } diff --git a/src/MigrateMessageCapture.php b/src/MigrateMessageCapture.php index 9f622f6..cb5fdcd 100644 --- a/src/MigrateMessageCapture.php +++ b/src/MigrateMessageCapture.php @@ -10,8 +10,7 @@ namespace Drupal\migrate_upgrade; use Drupal\migrate\MigrateMessageInterface; /** - * Defines a migrate message class for capturing messages rather than - * displaying them directly. + * Allows capturing messages rather than displaying them directly. */ class MigrateMessageCapture implements MigrateMessageInterface { @@ -30,16 +29,17 @@ class MigrateMessageCapture implements MigrateMessageInterface { } /** - * Clear out any captured messages. + * Clears out any captured messages. */ public function clear() { $this->messages = []; } /** - * Return any captured messages. + * Returns any captured messages. * * @return array + * The captured messages. */ public function getMessages() { return $this->messages; diff --git a/src/MigrateUpgradeRunBatch.php b/src/MigrateUpgradeRunBatch.php index 3df43da..5809176 100644 --- a/src/MigrateUpgradeRunBatch.php +++ b/src/MigrateUpgradeRunBatch.php @@ -7,6 +7,8 @@ namespace Drupal\migrate_upgrade; +use Drupal\Core\Link; +use Drupal\Core\Url; use Drupal\migrate\Entity\Migration; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\Event\MigrateEvents; @@ -16,8 +18,10 @@ use Drupal\migrate\Event\MigrateMapSaveEvent; use Drupal\migrate\Event\MigratePostRowSaveEvent; use Drupal\migrate\Event\MigrateRowDeleteEvent; use Drupal\migrate\MigrateExecutable; -use Drupal\Core\Url; +/** + * Runs a single migration batch. + */ class MigrateUpgradeRunBatch { /** @@ -54,30 +58,26 @@ class MigrateUpgradeRunBatch { protected static $messages; /** - * Run a single migration batch. + * Runs a single migration batch. * - * @param array $initial_ids + * @param int[] $initial_ids * The full set of migration IDs to import. * @param string $operation - * 'import' or 'rollback'. - * @param $context + * The operation to perform, 'import' or 'rollback'. + * @param array $context * The batch context. */ public static function run($initial_ids, $operation, &$context) { if (!static::$listenersAdded) { + $event_dispatcher = \Drupal::service('event_dispatcher'); if ($operation == 'import') { - \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_ROW_SAVE, - [get_class(), 'onPostRowSave']); - \Drupal::service('event_dispatcher')->addListener(MigrateEvents::MAP_SAVE, - [get_class(), 'onMapSave']); - \Drupal::service('event_dispatcher')->addListener(MigrateEvents::IDMAP_MESSAGE, - [get_class(), 'onIdMapMessage']); + $event_dispatcher->addListener(MigrateEvents::POST_ROW_SAVE, [static::class, 'onPostRowSave']); + $event_dispatcher->addListener(MigrateEvents::MAP_SAVE, [static::class, 'onMapSave']); + $event_dispatcher->addListener(MigrateEvents::IDMAP_MESSAGE, [static::class, 'onIdMapMessage']); } else { - \Drupal::service('event_dispatcher')->addListener(MigrateEvents::POST_ROW_DELETE, - [get_class(), 'onPostRowDelete']); - \Drupal::service('event_dispatcher')->addListener(MigrateEvents::MAP_DELETE, - [get_class(), 'onMapDelete']); + $event_dispatcher->addListener(MigrateEvents::POST_ROW_DELETE, [static::class, 'onPostRowDelete']); + $event_dispatcher->addListener(MigrateEvents::MAP_DELETE, [static::class, 'onMapDelete']); } static::$maxExecTime = ini_get('max_execution_time'); if (static::$maxExecTime <= 0) { @@ -114,7 +114,7 @@ class MigrateUpgradeRunBatch { $migration_name = $migration->label() ? $migration->label() : $migration_id; - try { + try { if ($operation == 'import') { $migration_status = $executable->import(); } @@ -132,12 +132,12 @@ class MigrateUpgradeRunBatch { // Store the number processed in the sandbox. $context['sandbox']['num_processed'] += static::$numProcessed; if ($operation == 'import') { - $message = \Drupal::translation()->formatPlural( + $message = static::getTranslation()->formatPlural( $context['sandbox']['num_processed'], 'Upgraded @migration (processed 1 item total)', 'Upgraded @migration (processed @num_processed items total)', ['@migration' => $migration_name, '@num_processed' => $context['sandbox']['num_processed']]); } else { - $message = \Drupal::translation()->formatPlural( + $message = static::getTranslation()->formatPlural( $context['sandbox']['num_processed'], 'Rolled back @migration (processed 1 item total)', 'Rolled back @migration (processed @num_processed items total)', ['@migration' => $migration_name, '@num_processed' => $context['sandbox']['num_processed']]); $migration->delete(); @@ -149,7 +149,7 @@ class MigrateUpgradeRunBatch { break; case MigrationInterface::RESULT_INCOMPLETE: - $context['sandbox']['messages'][] = \Drupal::translation()->formatPlural( + $context['sandbox']['messages'][] = static::getTranslation()->formatPlural( static::$numProcessed, 'Continuing with @migration (processed 1 item)', 'Continuing with @migration (processed @num_processed items)', ['@migration' => $migration_name, '@num_processed' => static::$numProcessed]); $context['sandbox']['num_processed'] += static::$numProcessed; @@ -191,7 +191,7 @@ class MigrateUpgradeRunBatch { $message_count = count($context['sandbox']['messages']); $context['message'] = ''; for ($index = max(0, $message_count - self::MESSAGE_LENGTH); $index < $message_count; $index++) { - $context['message'] = $context['sandbox']['messages'][$index]. "
\n" . $context['message']; + $context['message'] = $context['sandbox']['messages'][$index] . "
\n" . $context['message']; } if ($message_count > self::MESSAGE_LENGTH) { // Indicate there are earlier messages not displayed. @@ -204,14 +204,18 @@ class MigrateUpgradeRunBatch { $migration = Migration::load($migration_id); $migration_name = $migration->label() ? $migration->label() : $migration_id; if ($operation == 'import') { - $context['message'] = t('Currently upgrading @migration (@current of @max total tasks)', - ['@migration' => $migration_name, '@current' => $context['sandbox']['current'], - '@max' => $context['sandbox']['max']]) . "
\n" . $context['message']; + $context['message'] = t('Currently upgrading @migration (@current of @max total tasks)', [ + '@migration' => $migration_name, + '@current' => $context['sandbox']['current'], + '@max' => $context['sandbox']['max'], + ]) . "
\n" . $context['message']; } else { - $context['message'] = t('Currently rolling back @migration (@current of @max total tasks)', - ['@migration' => $migration_name, '@current' => $context['sandbox']['current'], - '@max' => $context['sandbox']['max']]) . "
\n" . $context['message']; + $context['message'] = t('Currently rolling back @migration (@current of @max total tasks)', [ + '@migration' => $migration_name, + '@current' => $context['sandbox']['current'], + '@max' => $context['sandbox']['max'], + ]) . "
\n" . $context['message']; } } } @@ -224,7 +228,7 @@ class MigrateUpgradeRunBatch { } /** - * A helper method to grab the logger using the migrate_upgrade channel. + * Returns the logger using the migrate_upgrade channel. * * @return \Psr\Log\LoggerInterface * The logger instance. @@ -234,48 +238,57 @@ class MigrateUpgradeRunBatch { } /** - * Implementation of the Batch API finished method. + * Wraps the translation manager. + * + * @return \Drupal\Core\StringTranslation\TranslationManager + * The string translation manager. + */ + protected static function getTranslation() { + return \Drupal::translation(); + } + + /** + * Implements the Batch API finished method. */ public static function finished($success, $results, $operations, $elapsed) { static::displayResults($results); } /** - * Display counts of success/failures on the migration upgrade complete page. + * Displays counts of success/failures on the migration upgrade complete page. * - * @param $results + * @param array $results * An array of result data built during the batch. */ protected static function displayResults($results) { $successes = $results['successes']; $failures = $results['failures']; - $translation = \Drupal::translation(); // If we had any successes lot that for the user. if ($successes > 0) { if ($results['operation'] == 'import') { - drupal_set_message($translation->formatPlural($successes, 'Completed 1 upgrade task successfully', 'Completed @count upgrade tasks successfully')); + drupal_set_message(static::getTranslation()->formatPlural($successes, 'Completed 1 upgrade task successfully', 'Completed @count upgrade tasks successfully')); } else { - drupal_set_message($translation->formatPlural($successes, 'Completed 1 rollback task successfully', 'Completed @count rollback tasks successfully')); + drupal_set_message(static::getTranslation()->formatPlural($successes, 'Completed 1 rollback task successfully', 'Completed @count rollback tasks successfully')); } } // If we had failures, log them and show the migration failed. if ($failures > 0) { if ($results['operation'] == 'import') { - drupal_set_message($translation->formatPlural($failures, '1 upgrade failed', '@count upgrades failed')); + drupal_set_message(static::getTranslation()->formatPlural($failures, '1 upgrade failed', '@count upgrades failed')); drupal_set_message(t('Upgrade process not completed'), 'error'); } else { - drupal_set_message($translation->formatPlural($failures, '1 rollback failed', '@count rollbacks failed')); + drupal_set_message(static::getTranslation()->formatPlural($failures, '1 rollback failed', '@count rollbacks failed')); drupal_set_message(t('Rollback process not completed'), 'error'); } } else { if ($results['operation'] == 'import') { - // Everything went off without a hitch. We may not have had successes but - // we didn't have failures so this is fine. + // Everything went off without a hitch. We may not have had successes + // but we didn't have failures so this is fine. drupal_set_message(t('Congratulations, you upgraded Drupal!')); } else { @@ -285,12 +298,12 @@ class MigrateUpgradeRunBatch { if (\Drupal::moduleHandler()->moduleExists('dblog')) { $url = Url::fromRoute('migrate_upgrade.log'); - drupal_set_message(\Drupal::l(t('Review the detailed upgrade log'), $url), $failures ? 'error' : 'status'); + drupal_set_message(Link::fromTextAndUrl(t('Review the detailed upgrade log'), $url), $failures ? 'error' : 'status'); } } /** - * React to item import. + * Reacts to item import. * * @param \Drupal\migrate\Event\MigratePostRowSaveEvent $event * The post-save event. @@ -303,7 +316,7 @@ class MigrateUpgradeRunBatch { } /** - * React to item deletion. + * Reacts to item deletion. * * @param \Drupal\migrate\Event\MigrateRowDeleteEvent $event * The post-save event. @@ -316,7 +329,7 @@ class MigrateUpgradeRunBatch { } /** - * Count up any map save events. + * Counts up any map save events. * * @param \Drupal\migrate\Event\MigrateMapSaveEvent $event * The map event. @@ -326,7 +339,7 @@ class MigrateUpgradeRunBatch { } /** - * Count up any map delete events. + * Counts up any map delete events. * * @param \Drupal\migrate\Event\MigrateMapDeleteEvent $event * The map event. @@ -336,22 +349,20 @@ class MigrateUpgradeRunBatch { } /** - * Display any messages being logged to the ID map. + * Displays any messages being logged to the ID map. * * @param \Drupal\migrate\Event\MigrateIdMapMessageEvent $event * The message event. */ public static function onIdMapMessage(MigrateIdMapMessageEvent $event) { - if ($event->getLevel() == MigrationInterface::MESSAGE_NOTICE || - $event->getLevel() == MigrationInterface::MESSAGE_INFORMATIONAL) { + if ($event->getLevel() == MigrationInterface::MESSAGE_NOTICE || $event->getLevel() == MigrationInterface::MESSAGE_INFORMATIONAL) { $type = 'status'; } else { $type = 'error'; } $source_id_string = implode(',', $event->getSourceIdValues()); - $message = t('Source ID @source_id: @message', - ['@source_id' => $source_id_string, '@message' => $event->getMessage()]); + $message = t('Source ID @source_id: @message', ['@source_id' => $source_id_string, '@message' => $event->getMessage()]); static::$messages->display($message, $type); } diff --git a/src/MigrationCreationTrait.php b/src/MigrationCreationTrait.php index 648bbbd..3845449 100644 --- a/src/MigrationCreationTrait.php +++ b/src/MigrationCreationTrait.php @@ -15,19 +15,18 @@ use Drupal\migrate\Plugin\RequirementsInterface; use Drupal\Component\Plugin\Exception\PluginNotFoundException; /** - * Trait providing functionality to create the appropriate migrations for - * a given source Drupal database. Note the class using the trait must - * implement TranslationInterface (i.e., define t()). + * Creates the appropriate migrations for a given source Drupal database. */ trait MigrationCreationTrait { /** - * Get the database connection for the source Drupal database. + * Gets the database connection for the source Drupal database. * - * @param \Drupal\Core\Database\Database $database + * @param array $database * Database array representing the source Drupal database. * * @return \Drupal\Core\Database\Connection + * The database connection for the source Drupal database. */ protected function getConnection(array $database) { // Set up the connection. @@ -37,19 +36,20 @@ trait MigrationCreationTrait { } /** - * Get the system data from the system table of the source Drupal database. + * Gets the system data from the system table of the source Drupal database. * - * @param \Drupal\Core\Database\Database $database + * @param array $database * Database array representing the source Drupal database. * * @return array + * The system data from the system table of the source Drupal database. */ protected function getSystemData(array $database) { $connection = $this->getConnection($database); $system_data = []; try { $results = $connection->select('system', 's', [ - 'fetch' => \PDO::FETCH_ASSOC + 'fetch' => \PDO::FETCH_ASSOC, ]) ->fields('s') ->execute(); @@ -64,14 +64,17 @@ trait MigrationCreationTrait { } /** - * Set up the migration template for import from the provided database connection. + * Sets up the relevant migrations for import from a database connection. * - * @param \Drupal\Core\Database\Database $database + * @param array|\Drupal\Core\Database\Database $database * Database array representing the source Drupal database. * @param string $source_base_path * Address of the source Drupal site (e.g., http://example.com/). * - * @return array + * @return int[] + * An array of Migration entity IDs. + * + * @throws \Exception */ protected function getMigrationTemplates(array $database, $source_base_path) { // Set up the connection. @@ -103,15 +106,18 @@ trait MigrationCreationTrait { } /** - * Get the relevant migrations for import from the provided migration template connection. + * Gets the migrations for import. * - * @param string $migration_templates - * Migration template + * Uses the migration template connection to ensure that only the relevant + * migrations are returned. + * + * @param array $migration_templates + * Migration template. * - * @return object + * @return \Drupal\migrate\Entity\MigrationInterface[] + * The migrations for import. */ protected function getMigrations(array $migration_templates) { - // Let the builder service create our migration configuration entities from // the templates, expanding them to multiple entities where necessary. /** @var \Drupal\migrate\MigrationBuilder $builder */ @@ -120,11 +126,13 @@ trait MigrationCreationTrait { $migrations = []; foreach ($initial_migrations as $migration) { try { - if ($migration->getSourcePlugin() instanceof RequirementsInterface) { - $migration->getSourcePlugin()->checkRequirements(); + $source_plugin = $migration->getSourcePlugin(); + if ($source_plugin instanceof RequirementsInterface) { + $source_plugin->checkRequirements(); } - if ($migration->getDestinationPlugin() instanceof RequirementsInterface) { - $migration->getDestinationPlugin()->checkRequirements(); + $destination_plugin = $migration->getDestinationPlugin(); + if ($destination_plugin instanceof RequirementsInterface) { + $destination_plugin->checkRequirements(); } $migrations[] = $migration; } @@ -141,13 +149,16 @@ trait MigrationCreationTrait { } /** - * Save the relevant migrations for import from the provided template - * connection. + * Saves the migrations for import from the provided template connection. * - * @param string $migration_templates + * @param array $migration_templates * Migration template. + * + * @return array + * The migration IDs sorted in dependency order. */ protected function createMigrations(array $migration_templates) { + $migration_ids = []; $migrations = $this->getMigrations($migration_templates); foreach ($migrations as $migration) { // Don't try to resave migrations that already exist. @@ -161,11 +172,14 @@ trait MigrationCreationTrait { } /** - * Determine what version of Drupal the source database contains. + * Determines what version of Drupal the source database contains. * * @param \Drupal\Core\Database\Connection $connection + * The database connection object. * * @return int|FALSE + * An integer representing the major branch of Drupal core (e.g. '6' for + * Drupal 6.x), or FALSE if no valid version is matched. */ protected function getLegacyDrupalVersion(Connection $connection) { // Don't assume because a table of that name exists, that it has the columns @@ -174,8 +188,9 @@ trait MigrationCreationTrait { // Drupal 5/6/7 can be detected by the schema_version in the system table. if ($connection->schema()->tableExists('system')) { try { - $version_string = $connection->query('SELECT schema_version FROM {system} WHERE name = :module', [':module' => 'system']) - ->fetchField(); + $version_string = $connection + ->query('SELECT schema_version FROM {system} WHERE name = :module', [':module' => 'system']) + ->fetchField(); if ($version_string && $version_string[0] == '1') { if ((int) $version_string >= 1000) { $version_string = '5'; @@ -192,7 +207,9 @@ trait MigrationCreationTrait { // For Drupal 8 (and we're predicting beyond) the schema version is in the // key_value store. elseif ($connection->schema()->tableExists('key_value')) { - $result = $connection->query("SELECT value FROM {key_value} WHERE collection = :system_schema and name = :module", [':system_schema' => 'system.schema', ':module' => 'system'])->fetchField(); + $result = $connection + ->query("SELECT value FROM {key_value} WHERE collection = :system_schema and name = :module", [':system_schema' => 'system.schema', ':module' => 'system']) + ->fetchField(); $version_string = unserialize($result); } else {