Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEV - MIG - UI Rollback option for CSV Migration Group #105

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion src/Form/Ingest/Review.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

use Drupal\islandora_spreadsheet_ingest\Util\MigrationRollbackBatch;
use Drupal\migrate_tools\MigrateExecutable;
use Symfony\Component\DependencyInjection\ContainerInterface;

use Drupal\migrate\Plugin\MigrationInterface;
Expand Down Expand Up @@ -145,7 +147,7 @@ public function submitActivation(array &$form, FormStateInterface $form_state) {
* @param mixed $context
* A reference to the batch context.
*/
public function runBatchOp(MigrationInterface $migration, MigrateBatchExecutable $e, &$context) {
public function runBatchOp(MigrationInterface $migration, MigrateExecutable $e, &$context) {
Copy link
Contributor Author

@dynac01 dynac01 May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this because both MigrateBatchExecutable and MigrationRollbackBatch extend MigrateExecutable

$sandbox =& $context['sandbox'];

if (!isset($sandbox['prepped'])) {
Expand Down Expand Up @@ -193,6 +195,10 @@ protected function processingMethods() {
'label' => $this->t('Immediate'),
'callable' => [$this, 'submitProcessImmediate'],
],
'rollback_migration_group' => [
'label' => $this->t('Rollback Migration Group'),
'callable' => [$this, 'submitProcessRollbackMigrationGroup'],
],
];
}

Expand Down Expand Up @@ -250,6 +256,38 @@ protected function submitProcessImmediate(array &$form, FormStateInterface $form
}
}

/**
* Callback for the "rollback_migration_group" method.
*/
protected function submitProcessRollbackMigrationGroup(): void {
try {
$migrations = $this->migrationPluginManager->createInstancesByTag($this->migrationGroupDeriver->deriveTag($this->entity));
$batch = [
'operations' => [],
];

foreach ($migrations as $migration) {
$executable = new MigrationRollbackBatch($migration, $this->messenger, [
'limit' => 0,
'update' => 0,
'force' => 0,
]);
$batch['operations'][] = [
[$this, 'runBatchOp'],
[$migration, $executable],
];
}

batch_set($batch);
} catch (\Exception $e) {
$this->logger('isi.review')->error("Failed to roll back migration: {exc}\n{backtrace}", [
'exc' => $e->getMessage(),
'backtrace' => $e->getTraceAsString(),
]);
$this->messenger->addError($this->t("Failed to rollback migration."));
}
}

/**
* Submission handler; route to selected processing method.
*/
Expand Down
105 changes: 105 additions & 0 deletions src/Util/MigrationRollbackBatch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

namespace Drupal\islandora_spreadsheet_ingest\Util;

use Drupal\Core\Messenger\MessengerInterface;
use Drupal\migrate\MigrateMessage;
use Drupal\migrate\Plugin\MigrationInterface;
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\migrate_tools\MigrateExecutable;

/**
* Class responsible for rolling back a migration in batches.
*/
class MigrationRollbackBatch extends MigrateExecutable {

use DependencySerializationTrait {
__sleep as traitSleep;
__wakeup as traitWakeup;
}

/**
* Manages migration plugin instances. It's used to create instances of migrations by their group ID.
*
* @var MigrationPluginManagerInterface
*/
protected MigrationPluginManagerInterface $migrationPluginManager;
protected MessengerInterface $messenger;

public function __construct(
MigrationInterface $migration,
MessengerInterface $messenger,
array $options,
) {
parent::__construct($migration, new MigrateMessage(), $options);
$this->messenger = $messenger;
}

/**
* Prepare a batch array for execution for the given migration.
*
* @return array
* A batch array with operations and the like.
*
* @throws \Exception
* If the migration could not be enqueued successfully.
*/
public function prepareBatch(): array {
return [
'title' => $this->t('Rolling back migration: @migration', ['@migration' => $this->migration->id()]),
'operations' => [
[[$this, 'processBatch'], []],
],
'finished' => [$this, 'finishBatch'],
];
}

/**
* Process each batch to roll back all contained rows
*
* @param array $context
* @return void
*/
public function processBatch(array &$context): void {
$context['message'] = $this->t('Processing of "@migration_id"', ['@migration_id' => $this->migration->id()]);

$status = $this->rollback();

if ($status === MigrationInterface::RESULT_COMPLETED) {
$message = $this->t('Rollback completed', ['@id' => $this->migration->id()]);
$this->messenger->addStatus($message);
}
else {
$message = $this->t('Rollback of @name migration failed.', ['@name' => $this->migration->id()]);
$this->messenger->addError($message);
}

$context['message'] = $this->t('"@migration_id" has been processed', ['@migration_id' => $this->migration->id()]);
}


/**
* Display success or error messages following the completion of processing
*
* @param $success
* @param $results
* @param $ops
* @param $interval
* @return void
*/
public function finishBatch($success, $results, $ops, $interval): void {
if (!$success || empty($results['errors'])) {
$this->messenger->addError(
$this->t(
'Rollback encountered errors.'
)
);

foreach ($results['errors'] as $e) {
$this->messenger->addError(
$this->t('Migration group rollback failed with exception: @e', ['@e' => $e]));
}
}
}
}
Loading