diff --git a/src/BatchProcessor.php b/src/BatchProcessor.php index 940418929d71974983a5db8b7b305de1ca3d6411..8723b9ce9ccbb818889d2ce6b9f7aa0dc856eb22 100644 --- a/src/BatchProcessor.php +++ b/src/BatchProcessor.php @@ -91,7 +91,60 @@ class BatchProcessor { } /** - * Finishes the batch job. + * Calls the updater's commit() method. + * + * @param array $context + * The current context of the batch job. + * + * @see \Drupal\automatic_updates\Updater::commit() + */ + public static function commit(array &$context): void { + try { + static::getUpdater()->commit(); + } + catch (\Throwable $e) { + static::handleException($e, $context); + } + } + + /** + * Calls the updater's clean() method. + * + * @param array $context + * The current context of the batch job. + * + * @see \Drupal\automatic_updates\Updater::clean() + */ + public static function clean(array &$context): void { + try { + static::getUpdater()->clean(); + } + catch (\Throwable $e) { + static::handleException($e, $context); + } + } + + /** + * Finishes the stage batch job. + * + * @param bool $success + * Indicate that the batch API tasks were all completed successfully. + * @param array $results + * An array of all the results. + * @param array $operations + * A list of the operations that had not been completed by the batch API. + */ + public static function finishStage(bool $success, array $results, array $operations): ?RedirectResponse { + if ($success) { + return new RedirectResponse(Url::fromRoute('automatic_updates.confirmation_page', [], + ['absolute' => TRUE])->toString()); + } + static::handleBatchError($results); + return NULL; + } + + /** + * Finishes the commit batch job. * * @param bool $success * Indicate that the batch API tasks were all completed successfully. @@ -100,10 +153,25 @@ class BatchProcessor { * @param array $operations * A list of the operations that had not been completed by the batch API. */ - public static function finish(bool $success, array $results, array $operations): ?RedirectResponse { + public static function finishCommit(bool $success, array $results, array $operations): ?RedirectResponse { + if ($success) { - return new RedirectResponse(Url::fromRoute('automatic_updates.confirmation_page', [], ['absolute' => TRUE])->toString()); + \Drupal::messenger()->addMessage('Update complete!'); + // @todo redirect to update.php? + return new RedirectResponse(Url::fromRoute('automatic_updates.update_form', [], + ['absolute' => TRUE])->toString()); } + static::handleBatchError($results); + return NULL; + } + + /** + * Handles a batch job that finished with errors. + * + * @param array $results + * The batch results. + */ + protected static function handleBatchError(array $results): void { if (isset($results['errors'])) { foreach ($results['errors'] as $error) { \Drupal::messenger()->addError($error); @@ -112,7 +180,6 @@ class BatchProcessor { else { \Drupal::messenger()->addError("Update error"); } - return NULL; } } diff --git a/src/Form/UpdateReady.php b/src/Form/UpdateReady.php index cb978f7d20ae3df62bb25f51882237bae107131b..f4dcc94b9e45a28ee2f8c214e58452b38ab9181a 100644 --- a/src/Form/UpdateReady.php +++ b/src/Form/UpdateReady.php @@ -3,7 +3,9 @@ namespace Drupal\automatic_updates\Form; use Drupal\automatic_updates\AutomaticUpdatesEvents; +use Drupal\automatic_updates\BatchProcessor; use Drupal\automatic_updates\Updater; +use Drupal\Core\Batch\BatchBuilder; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Messenger\MessengerInterface; use Drupal\Core\State\StateInterface; @@ -106,15 +108,15 @@ class UpdateReady extends UpdateFormBase { $this->state->set('system.maintenance_mode', TRUE); // @todo unset after updater. After db update? } - - // @todo Should these operations be done in batch. - $this->updater->commit(); - // Clean could be done in another page load or on cron to reduce page time. - $this->updater->clean(); - $this->messenger->addMessage("Update complete!"); - - // @todo redirect to update.php? - $form_state->setRedirect('automatic_updates.update_form'); + $batch = (new BatchBuilder()) + ->setTitle($this->t('Apply updates')) + ->setInitMessage($this->t('Preparing to apply updates')) + ->addOperation([BatchProcessor::class, 'commit']) + ->addOperation([BatchProcessor::class, 'clean']) + ->setFinishCallback([BatchProcessor::class, 'finishCommit']) + ->toArray(); + + batch_set($batch); } } diff --git a/src/Form/UpdaterForm.php b/src/Form/UpdaterForm.php index 599c7257e0a9453a1e9c0a9881c217d7c2b21aca..98d57ed320dd9bddcc2ec1a471b1e7d86c6033af 100644 --- a/src/Form/UpdaterForm.php +++ b/src/Form/UpdaterForm.php @@ -240,7 +240,7 @@ class UpdaterForm extends UpdateFormBase { ->addOperation([BatchProcessor::class, 'stageProjectVersions'], [ $form_state->getValue('update_version'), ]) - ->setFinishCallback([BatchProcessor::class, 'finish']) + ->setFinishCallback([BatchProcessor::class, 'finishStage']) ->toArray(); batch_set($batch); diff --git a/tests/src/Build/AttendedCoreUpdateTest.php b/tests/src/Build/AttendedCoreUpdateTest.php index 64fd82758a1858764a6f8ddbd4fd6325d4c3477b..23cfc81147f7c53fa3b771761e041e892c4b1a5a 100644 --- a/tests/src/Build/AttendedCoreUpdateTest.php +++ b/tests/src/Build/AttendedCoreUpdateTest.php @@ -122,6 +122,7 @@ class AttendedCoreUpdateTest extends AttendedUpdateTestBase { $this->waitForBatchJob(); $assert_session->pageTextContains('Ready to update'); $page->pressButton('Continue'); + $this->waitForBatchJob(); // @todo This message isn't showing up, for some reason. Figure out what the // eff is going on. // $assert_session->pageTextContains('Update complete!');