You are here

function update_retrieve_dependencies in Drupal 9

Same name and namespace in other branches
  1. 8 core/includes/update.inc \update_retrieve_dependencies()
  2. 7 includes/update.inc \update_retrieve_dependencies()

Invokes hook_update_dependencies() in all installed modules.

This function is similar to \Drupal::moduleHandler()->invokeAll(), with the main difference that it does not require that a module be enabled to invoke its hook, only that it be installed. This allows the update system to properly perform updates even on modules that are currently disabled.

Return value

An array of return values obtained by merging the results of the hook_update_dependencies() implementations in all installed modules.

See also

\Drupal\Core\Extension\ModuleHandlerInterface::invokeAll()

hook_update_dependencies()

2 calls to update_retrieve_dependencies()
DependencyHookInvocationTest::testHookUpdateDependencies in core/modules/system/tests/src/Functional/UpdateSystem/DependencyHookInvocationTest.php
Tests the structure of the array returned by hook_update_dependencies().
update_build_dependency_graph in core/includes/update.inc
Constructs a graph which encodes the dependencies between module updates.

File

core/includes/update.inc, line 685
Drupal database update API.

Code

function update_retrieve_dependencies() {
  $return = [];

  /** @var \Drupal\Core\Extension\ModuleExtensionList */
  $extension_list = \Drupal::service('extension.list.module');

  /** @var \Drupal\Core\Update\UpdateHookRegistry $update_registry */
  $update_registry = \Drupal::service('update.update_hook_registry');

  // Get a list of installed modules, arranged so that we invoke their hooks in
  // the same order that \Drupal::moduleHandler()->invokeAll() does.
  foreach ($update_registry
    ->getAllInstalledVersions() as $module => $schema) {

    // Skip modules that are entirely missing from the filesystem here, since
    // module_load_install() will call trigger_error() if invoked on a module
    // that doesn't exist. There's no way to catch() that, so avoid it entirely.
    // This can happen when there are orphaned entries in the system.schema k/v
    // store for modules that have been removed from a site without first being
    // cleanly uninstalled. We don't care here if the module has been installed
    // or not, since we'll filter those out in update_get_update_list().
    if ($schema == $update_registry::SCHEMA_UNINSTALLED || !$extension_list
      ->exists($module)) {

      // Nothing to upgrade.
      continue;
    }
    $function = $module . '_update_dependencies';

    // Ensure install file is loaded.
    module_load_install($module);
    if (function_exists($function)) {
      $updated_dependencies = $function();

      // Each implementation of hook_update_dependencies() returns a
      // multidimensional, associative array containing some keys that
      // represent module names (which are strings) and other keys that
      // represent update function numbers (which are integers). We cannot use
      // array_merge_recursive() to properly merge these results, since it
      // treats strings and integers differently. Therefore, we have to
      // explicitly loop through the expected array structure here and perform
      // the merge manually.
      if (isset($updated_dependencies) && is_array($updated_dependencies)) {
        foreach ($updated_dependencies as $module_name => $module_data) {
          foreach ($module_data as $update_version => $update_data) {
            foreach ($update_data as $module_dependency => $update_dependency) {

              // If there are redundant dependencies declared for the same
              // update function (so that it is declared to depend on more than
              // one update from a particular module), record the dependency on
              // the highest numbered update here, since that automatically
              // implies the previous ones. For example, if one module's
              // implementation of hook_update_dependencies() required this
              // ordering:
              //
              // system_update_8002 ---> user_update_8001
              //
              // but another module's implementation of the hook required this
              // one:
              //
              // system_update_8003 ---> user_update_8001
              //
              // we record the second one, since system_update_8002() is always
              // guaranteed to run before system_update_8003() anyway (within
              // an individual module, updates are always run in numerical
              // order).
              if (!isset($return[$module_name][$update_version][$module_dependency]) || $update_dependency > $return[$module_name][$update_version][$module_dependency]) {
                $return[$module_name][$update_version][$module_dependency] = $update_dependency;
              }
            }
          }
        }
      }
    }
  }
  return $return;
}