function ModuleHandler::alter

Same name in other branches
  1. 9 core/lib/Drupal/Core/Extension/ModuleHandler.php \Drupal\Core\Extension\ModuleHandler::alter()
  2. 8.9.x core/lib/Drupal/Core/Extension/ModuleHandler.php \Drupal\Core\Extension\ModuleHandler::alter()
  3. 10 core/lib/Drupal/Core/Extension/ModuleHandler.php \Drupal\Core\Extension\ModuleHandler::alter()

Overrides ModuleHandlerInterface::alter

2 calls to ModuleHandler::alter()
ModuleHandler::alterDeprecated in core/lib/Drupal/Core/Extension/ModuleHandler.php
Passes alterable variables to deprecated hook_TYPE_alter() implementations.
ModuleHandler::reOrderModulesForAlter in core/lib/Drupal/Core/Extension/ModuleHandler.php
Reorder modules for alters.

File

core/lib/Drupal/Core/Extension/ModuleHandler.php, line 403

Class

ModuleHandler
Class that manages modules in a Drupal installation.

Namespace

Drupal\Core\Extension

Code

public function alter($type, &$data, &$context1 = NULL, &$context2 = NULL) {
    // Most of the time, $type is passed as a string, so for performance,
    // normalize it to that. When passed as an array, usually the first item in
    // the array is a generic type, and additional items in the array are more
    // specific variants of it, as in the case of array('form', 'form_FORM_ID').
    if (is_array($type)) {
        $cid = implode(',', $type);
        $extra_types = $type;
        $type = array_shift($extra_types);
        // Allow if statements in this function to use the faster isset() rather
        // than !empty() both when $type is passed as a string, or as an array
        // with one item.
        if (empty($extra_types)) {
            unset($extra_types);
        }
    }
    else {
        $cid = $type;
    }
    // Some alter hooks are invoked many times per page request, so store the
    // list of functions to call, and on subsequent calls, iterate through them
    // quickly.
    if (!isset($this->alterEventListeners[$cid])) {
        $this->alterEventListeners[$cid] = [];
        $hook = $type . '_alter';
        $hook_listeners = $this->getHookListeners($hook);
        if (isset($extra_types)) {
            // For multiple hooks, we need $modules to contain every module that
            // implements at least one of them in the correct order.
            foreach ($extra_types as $extra_type) {
                foreach ($this->getHookListeners($extra_type . '_alter') as $module => $listeners) {
                    if (isset($hook_listeners[$module])) {
                        $hook_listeners[$module] = array_merge($hook_listeners[$module], $listeners);
                    }
                    else {
                        $hook_listeners[$module] = $listeners;
                        $extra_modules = TRUE;
                    }
                }
            }
        }
        // If any modules implement one of the extra hooks that do not implement
        // the primary hook, we need to add them to the $modules array in their
        // appropriate order.
        $modules = array_keys($hook_listeners);
        if (isset($extra_modules)) {
            $modules = $this->reOrderModulesForAlter($modules, $hook);
        }
        foreach ($modules as $module) {
            foreach ($hook_listeners[$module] ?? [] as $listener) {
                $this->alterEventListeners[$cid][] = $listener;
            }
        }
    }
    foreach ($this->alterEventListeners[$cid] as $listener) {
        $listener($data, $context1, $context2);
    }
}

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