You are here

function install_run_task in Drupal 10

Same name and namespace in other branches
  1. 8 core/includes/install.core.inc \install_run_task()
  2. 7 includes/install.core.inc \install_run_task()
  3. 9 core/includes/install.core.inc \install_run_task()

Runs an individual installation task.

Parameters

$task: An array of information about the task to be run as returned by hook_install_tasks().

$install_state: An array of information about the current installation state. This is passed in by reference so that it can be modified by the task.

Return value

The output of the task function, if there is any.

1 call to install_run_task()
install_run_tasks in core/includes/install.core.inc
Runs all tasks for the current installation request.

File

core/includes/install.core.inc, line 612
API functions for installing Drupal.

Code

function install_run_task($task, &$install_state) {
  $function = $task['function'];
  if ($task['type'] == 'form') {
    return install_get_form($function, $install_state);
  }
  elseif ($task['type'] == 'batch') {

    // Start a new batch based on the task function, if one is not running
    // already.
    $current_batch = \Drupal::state()
      ->get('install_current_batch');
    if (!$install_state['interactive'] || !$current_batch) {
      $batches = $function($install_state);
      if (empty($batches)) {

        // If the task did some processing and decided no batch was necessary,
        // there is nothing more to do here.
        return;
      }

      // Create a one item list of batches if only one batch was provided.
      if (isset($batches['operations'])) {
        $batches = [
          $batches,
        ];
      }
      foreach ($batches as $batch_definition) {
        batch_set($batch_definition);

        // For interactive batches, we need to store the fact that this batch
        // task is currently running. Otherwise, we need to make sure the batch
        // will complete in one page request.
        if ($install_state['interactive']) {
          \Drupal::state()
            ->set('install_current_batch', $function);
        }
        else {
          $batch =& batch_get();
          $batch['progressive'] = FALSE;
        }
      }

      // Process the batch. For progressive batches, this will redirect.
      // Otherwise, the batch will complete.
      // Disable the default script for the URL and clone the object, as
      // batch_process() will add additional options to the batch URL.
      $url = Url::fromUri('base:install.php', [
        'query' => $install_state['parameters'],
        'script' => '',
      ]);
      $response = batch_process($url, clone $url);
      if ($response instanceof Response) {
        if (\Drupal::request()
          ->hasSession()) {
          \Drupal::request()
            ->getSession()
            ->save();
        }

        // Send the response.
        $response
          ->send();
        exit;
      }
    }
    elseif ($current_batch == $function) {
      $output = _batch_page(\Drupal::request());

      // Because Batch API now returns a JSON response for intermediary steps,
      // but the installer doesn't handle Response objects yet, just send the
      // output here and emulate the old model.
      // @todo Replace this when we refactor the installer to use a request-
      //   response workflow.
      if ($output instanceof Response) {
        if (\Drupal::request()
          ->hasSession()) {
          \Drupal::request()
            ->getSession()
            ->save();
        }

        // Send the response.
        $output
          ->send();
        exit;
      }

      // The task is complete when we try to access the batch page and receive
      // FALSE in return, since this means we are at a URL where we are no
      // longer requesting a batch ID.
      if ($output === FALSE) {

        // Return nothing so the next task will run in the same request.
        \Drupal::state()
          ->delete('install_current_batch');
        return;
      }
      else {

        // We need to force the page request to end if the task is not
        // complete, since the batch API sometimes prints JSON output
        // rather than returning a themed page.
        $install_state['task_not_complete'] = $install_state['stop_page_request'] = TRUE;
        return $output;
      }
    }
  }
  else {

    // For normal tasks, just return the function result, whatever it is.
    return $function($install_state);
  }
}