diff --git a/core/includes/batch.inc b/core/includes/batch.inc index 7d905cd..f0e32da 100644 --- a/core/includes/batch.inc +++ b/core/includes/batch.inc @@ -399,6 +399,7 @@ function _batch_next_set() { */ function _batch_finished() { $batch = &batch_get(); + $batch_finished_redirect = NULL; // Execute the 'finished' callbacks for each batch set, if defined. foreach ($batch['sets'] as $batch_set) { @@ -410,7 +411,13 @@ function _batch_finished() { if (is_callable($batch_set['finished'])) { $queue = _batch_queue($batch_set); $operations = $queue->getAllItems(); - call_user_func_array($batch_set['finished'], array($batch_set['success'], $batch_set['results'], $operations, \Drupal::service('date.formatter')->formatInterval($batch_set['elapsed'] / 1000))); + $batch_set_result = call_user_func_array($batch_set['finished'], array($batch_set['success'], $batch_set['results'], $operations, \Drupal::service('date.formatter')->formatInterval($batch_set['elapsed'] / 1000))); + // If a batch 'finished' callback requested a redirect after the batch + // is complete, save that for later use. If more than one batch set + // returned a redirect, the last one is used. + if ($batch_set_result instanceof RedirectResponse) { + $batch_finished_redirect = $batch_set_result; + } } } } @@ -441,8 +448,13 @@ function _batch_finished() { \Drupal::request()->query->set('destination', $_batch['destination']); } - // Determine the target path to redirect to. - if (!isset($_batch['form_state'])) { + // Determine the target path to redirect to. If a batch 'finished' callback + // returned a redirect response object, use that. Otherwise, fall back on + // the form redirection. + if (isset($batch_finished_redirect)) { + return $batch_finished_redirect; + } + elseif (!isset($_batch['form_state'])) { $_batch['form_state'] = new FormState(); } if ($_batch['form_state']->getRedirect() === NULL) { diff --git a/core/includes/form.inc b/core/includes/form.inc index 9c72685..c060c0b 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -747,7 +747,14 @@ function batch_set($batch_definition) { * * @param \Drupal\Core\Url|string $redirect * (optional) Either path or Url object to redirect to when the batch has - * finished processing. + * finished processing. Note that to simply force a batch to (conditionally) + * redirect to a custom location after it is finished processing but to + * otherwise allow the standard form API batch handling to occur, it is not + * necessary to call batch_process() and use this parameter. Instead, make + * the batch 'finished' callback return an instance of + * \Symfony\Component\HttpFoundation\RedirectResponse, which will be used + * automatically by the standard batch processing pipeline (and which takes + * precedence over this parameter). * @param \Drupal\Core\Url $url * (optional - should only be used for separate scripts like update.php) * URL of the batch processing page.