function Registry::postProcessExtension

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Theme/Registry.php \Drupal\Core\Theme\Registry::postProcessExtension()
  2. 8.9.x core/lib/Drupal/Core/Theme/Registry.php \Drupal\Core\Theme\Registry::postProcessExtension()
  3. 10 core/lib/Drupal/Core/Theme/Registry.php \Drupal\Core\Theme\Registry::postProcessExtension()

Completes the theme registry adding discovered functions and hooks.

Parameters

array $cache: The theme registry as documented in \Drupal\Core\Theme\Registry::processExtension().

\Drupal\Core\Theme\ActiveTheme $theme: Current active theme.

See also

::processExtension()

1 call to Registry::postProcessExtension()
Registry::build in core/lib/Drupal/Core/Theme/Registry.php
Builds the theme registry cache.

File

core/lib/Drupal/Core/Theme/Registry.php, line 718

Class

Registry
Defines the theme registry service.

Namespace

Drupal\Core\Theme

Code

protected function postProcessExtension(array &$cache, ActiveTheme $theme) {
    // Gather prefixes. This will be used to limit the found functions to the
    // expected naming conventions.
    $prefixes = array_keys((array) $this->moduleHandler
        ->getModuleList());
    foreach (array_reverse($theme->getBaseThemeExtensions()) as $base) {
        $prefixes[] = $base->getName();
    }
    if ($theme->getEngine()) {
        $prefixes[] = $theme->getEngine() . '_engine';
    }
    $prefixes[] = $theme->getName();
    $grouped_functions = $this->getPrefixGroupedUserFunctions($prefixes);
    // Collect all variable preprocess functions in the correct order.
    $suggestion_level = [];
    $matches = [];
    // Look for functions named according to the pattern and add them if they
    // have matching hooks in the registry.
    foreach ($prefixes as $prefix) {
        // Grep only the functions which are within the prefix group.
        [
            $first_prefix,
        ] = explode('_', $prefix, 2);
        if (!isset($grouped_functions[$first_prefix])) {
            continue;
        }
        // Add the function and the name of the associated theme hook to the list
        // of preprocess functions grouped by suggestion specificity if a matching
        // base hook is found.
        foreach ($grouped_functions[$first_prefix] as $candidate) {
            if (preg_match("/^{$prefix}_preprocess_(((?:[^_]++|_(?!_))+)__.*)/", $candidate, $matches)) {
                if (isset($cache[$matches[2]])) {
                    $level = substr_count($matches[1], '__');
                    $suggestion_level[$level][$candidate] = $matches[1];
                }
            }
        }
    }
    // Add missing variable preprocessors. This is needed for modules that do
    // not explicitly register the hook. For example, when a theme contains a
    // variable preprocess function but it does not implement a template, it
    // will go missing. This will add the expected function. It also allows
    // modules or themes to have a variable process function based on a pattern
    // even if the hook does not exist.
    ksort($suggestion_level);
    foreach ($suggestion_level as $level => $item) {
        foreach ($item as $preprocessor => $hook) {
            if (isset($cache[$hook]['preprocess functions']) && !in_array($preprocessor, $cache[$hook]['preprocess functions'])) {
                // Add missing preprocessor to existing hook.
                $cache[$hook]['preprocess functions'][] = $preprocessor;
            }
            elseif (!isset($cache[$hook]) && strpos($hook, '__')) {
                // Process non-existing hook and register it.
                // Look for a previously defined hook that is either a less specific
                // suggestion hook or the base hook.
                $this->completeSuggestion($hook, $cache);
                $cache[$hook]['preprocess functions'][] = $preprocessor;
            }
        }
    }
    // Inherit all base hook variable preprocess functions into suggestion
    // hooks. This ensures that derivative hooks have a complete set of variable
    // preprocess functions.
    foreach ($cache as $hook => $info) {
        // The 'base hook' is only applied to derivative hooks already registered
        // from a pattern. This is typically set from
        // drupal_find_theme_templates().
        if (isset($info['incomplete preprocess functions'])) {
            $this->completeSuggestion($hook, $cache);
            unset($cache[$hook]['incomplete preprocess functions']);
        }
        // Optimize the registry.
        if (isset($cache[$hook]['preprocess functions']) && empty($cache[$hook]['preprocess functions'])) {
            unset($cache[$hook]['preprocess functions']);
        }
        // Ensure uniqueness.
        if (isset($cache[$hook]['preprocess functions'])) {
            $cache[$hook]['preprocess functions'] = array_unique($cache[$hook]['preprocess functions']);
        }
    }
}

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