You are here

function update_calculate_project_data in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/update/update.compare.inc \update_calculate_project_data()
  2. 6 modules/update/update.compare.inc \update_calculate_project_data()
  3. 7 modules/update/update.compare.inc \update_calculate_project_data()
  4. 10 core/modules/update/update.compare.inc \update_calculate_project_data()

Calculates the current update status of all projects on the site.

The results of this function are expensive to compute, especially on sites with lots of modules or themes, since it involves a lot of comparisons and other operations. Therefore, we store the results. However, since this is not the data about available updates fetched from the network, it is ok to invalidate it somewhat quickly. If we keep this data for very long, site administrators are more likely to see incorrect results if they upgrade to a newer version of a module or theme but do not visit certain pages that automatically clear this.

Parameters

array $available: Data about available project releases.

Return value

An array of installed projects with current update status information.

See also

update_get_available()

\Drupal\update\UpdateManager::getProjects()

update_process_project_info()

\Drupal\update\UpdateManagerInterface::projectStorage()

\Drupal\update\ProjectCoreCompatibility::setReleaseMessage()

3 calls to update_calculate_project_data()
UpdateController::updateStatus in core/modules/update/src/Controller/UpdateController.php
Returns a page about the update status of projects.
UpdateManagerUpdate::buildForm in core/modules/update/src/Form/UpdateManagerUpdate.php
Form constructor.
update_requirements in core/modules/update/update.install
Implements hook_requirements().

File

core/modules/update/update.compare.inc, line 89
Code required only when comparing available updates to existing data.

Code

function update_calculate_project_data($available) {

  // Retrieve the projects from storage, if present.
  $projects = \Drupal::service('update.manager')
    ->projectStorage('update_project_data');

  // If $projects is empty, then the data must be rebuilt.
  // Otherwise, return the data and skip the rest of the function.
  if (!empty($projects)) {
    return $projects;
  }
  $projects = \Drupal::service('update.manager')
    ->getProjects();
  update_process_project_info($projects);
  if (isset($projects['drupal']) && !empty($available['drupal'])) {

    // Calculate core status first so that it is complete before
    // \Drupal\update\ProjectCoreCompatibility::setReleaseMessage() is called
    // for each module below.
    update_calculate_project_update_status($projects['drupal'], $available['drupal']);
    if (isset($available['drupal']['releases'])) {
      $project_core_compatibility = new ProjectCoreCompatibility($projects['drupal'], $available['drupal']['releases']);
    }
  }
  foreach ($projects as $project => $project_info) {
    if (isset($available[$project])) {
      if ($project === 'drupal') {
        continue;
      }
      update_calculate_project_update_status($projects[$project], $available[$project]);

      // Inject the list of compatible core versions to show administrator(s)
      // which versions of core a given available update can be installed with.
      // Since individual releases of a project can be compatible with different
      // versions of core, and even multiple major versions of core (for
      // example, 8.9.x and 9.0.x), this list will hopefully help
      // administrator(s) know which available updates they can upgrade a given
      // project to.
      if (isset($project_core_compatibility)) {
        $project_core_compatibility
          ->setReleaseMessage($projects[$project]);
      }
    }
    else {
      $projects[$project]['status'] = UpdateFetcherInterface::UNKNOWN;
      $projects[$project]['reason'] = t('No available releases found');
    }
  }

  // Give other modules a chance to alter the status (for example, to allow a
  // contrib module to provide fine-grained settings to ignore specific
  // projects or releases).
  \Drupal::moduleHandler()
    ->alter('update_status', $projects);

  // Store the site's update status for at most 1 hour.
  \Drupal::keyValueExpirable('update')
    ->setWithExpire('update_project_data', $projects, 3600);
  return $projects;
}