function _batch_finished

Same name in other branches
  1. 7.x includes/batch.inc \_batch_finished()
  2. 9 core/includes/batch.inc \_batch_finished()
  3. 8.9.x core/includes/batch.inc \_batch_finished()
  4. 11.x core/includes/batch.inc \_batch_finished()

Ends the batch processing.

Call the 'finished' callback of each batch set to allow custom handling of the results and resolve page redirection.

2 calls to _batch_finished()
_batch_page in core/includes/batch.inc
Renders the batch processing page based on the current state of the batch.
_batch_process in core/includes/batch.inc
Processes sets in a batch.

File

core/includes/batch.inc, line 443

Code

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) {
        if (isset($batch_set['finished'])) {
            // Check if the set requires an additional file for function definitions.
            if (isset($batch_set['file']) && is_file($batch_set['file'])) {
                include_once \Drupal::root() . '/' . $batch_set['file'];
            }
            if (is_callable($batch_set['finished'])) {
                $queue = _batch_queue($batch_set);
                $operations = $queue->getAllItems();
                $batch_set_result = call_user_func_array($batch_set['finished'], [
                    $batch_set['success'],
                    $batch_set['results'],
                    $operations,
                    \Drupal::service('date.formatter')->formatInterval((int) ($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;
                }
            }
        }
    }
    // Clean up the batch table and unset the static $batch variable.
    if ($batch['progressive']) {
        \Drupal::service('batch.storage')->delete($batch['id']);
        foreach ($batch['sets'] as $batch_set) {
            if ($queue = _batch_queue($batch_set)) {
                $queue->deleteQueue();
            }
        }
        // Clean-up the session. Not needed for CLI updates.
        $session = \Drupal::request()->getSession();
        $batches = $session->get('batches', []);
        unset($batches[$batch['id']]);
        if (empty($batches)) {
            $session->remove('batches');
        }
        else {
            $session->set('batches', $batches);
        }
    }
    $_batch = $batch;
    $batch = NULL;
    // Redirect if needed.
    if ($_batch['progressive']) {
        // Revert the 'destination' that was saved in batch_process().
        if (isset($_batch['destination'])) {
            \Drupal::request()->query
                ->set('destination', $_batch['destination']);
        }
        // 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) {
            $redirect = $_batch['batch_redirect'] ?: $_batch['source_url'];
            // Any path with a scheme does not correspond to a route.
            if (!$redirect instanceof Url) {
                $options = UrlHelper::parse($redirect);
                if (parse_url($options['path'], PHP_URL_SCHEME)) {
                    $redirect = Url::fromUri($options['path'], $options);
                }
                else {
                    $redirect = \Drupal::pathValidator()->getUrlIfValid($options['path']);
                    if (!$redirect) {
                        // Stay on the same page if the redirect was invalid.
                        $redirect = Url::fromRoute('<current>');
                    }
                    $redirect->setOptions($options);
                }
            }
            $_batch['form_state']->setRedirectUrl($redirect);
        }
        // Use \Drupal\Core\Form\FormSubmitterInterface::redirectForm() to handle
        // the redirection logic.
        $redirect = \Drupal::service('form_submitter')->redirectForm($_batch['form_state']);
        if (is_object($redirect)) {
            return $redirect;
        }
        // If no redirection happened, redirect to the originating page. In case the
        // form needs to be rebuilt, save the final $form_state for
        // \Drupal\Core\Form\FormBuilderInterface::buildForm().
        if ($_batch['form_state']->isRebuilding()) {
            $session = \Drupal::request()->getSession();
            $session->set('batch_form_state', $_batch['form_state']);
        }
        $callback = $_batch['redirect_callback'];
        $_batch['source_url']->mergeOptions([
            'query' => [
                'op' => 'finish',
                'id' => $_batch['id'],
            ],
        ]);
        if (is_callable($callback)) {
            $callback($_batch['source_url'], $_batch['source_url']->getOption('query'));
        }
        elseif ($callback === NULL) {
            // Default to RedirectResponse objects when nothing specified.
            return new RedirectResponse($_batch['source_url']->setAbsolute()
                ->toString());
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.