You are here

class ThemeRegistry in Express 8

Extends the theme registry to override and use protected functions.

@todo Refactor into a proper theme.registry service replacement in a bootstrap_core sub-module once this theme can add it as a dependency.

Plugin annotation

@BootstrapAlter("theme_registry");

Hierarchy

Expanded class hierarchy of ThemeRegistry

See also

https://www.drupal.org/node/474684

File

themes/contrib/bootstrap/src/Plugin/Alter/ThemeRegistry.php, line 27
Contains \Drupal\bootstrap\Plugin\Alter\ThemeRegistry.

Namespace

Drupal\bootstrap\Plugin\Alter
View source
class ThemeRegistry extends Registry implements AlterInterface {

  /**
   * The currently set Bootstrap theme object.
   *
   * Cannot use "$theme" because this is the Registry's ActiveTheme object.
   *
   * @var \Drupal\bootstrap\Theme
   */
  protected $currentTheme;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition) {

    // This is technically a plugin constructor, but because we wish to use the
    // protected methods of the Registry class, we must extend from it. Thus,
    // to properly construct the extended Registry object, we must pass the
    // arguments it would normally get from the service container to "fake" it.
    if (!isset($configuration['theme'])) {
      $configuration['theme'] = Bootstrap::getTheme();
    }
    $this->currentTheme = $configuration['theme'];
    parent::__construct(\Drupal::service('app.root'), \Drupal::service('cache.default'), \Drupal::service('lock'), \Drupal::service('module_handler'), \Drupal::service('theme_handler'), \Drupal::service('theme.initialization'), $this->currentTheme
      ->getName());
    $this
      ->setThemeManager(\Drupal::service('theme.manager'));
    $this
      ->init();
  }

  /**
   * {@inheritdoc}
   */
  public function alter(&$cache, &$context1 = NULL, &$context2 = NULL) {

    // Sort the registry alphabetically (for easier debugging).
    ksort($cache);

    // Add extra variables to all theme hooks.
    $extra_variables = Bootstrap::extraVariables();
    foreach (array_keys($cache) as $hook) {

      // Skip theme hooks that don't set variables.
      if (!isset($cache[$hook]['variables'])) {
        continue;
      }
      $cache[$hook]['variables'] += $extra_variables;
    }

    // Ensure paths to templates are set properly. This allows templates to
    // be moved around in a theme without having to constantly ensuring that
    // the theme's hook_theme() definitions have the correct static "path" set.
    foreach ($this->currentTheme
      ->getAncestry() as $ancestor) {
      $current_theme = $ancestor
        ->getName() === $this->currentTheme
        ->getName();
      $theme_path = $ancestor
        ->getPath();
      foreach ($ancestor
        ->fileScan('/\\.html\\.twig$/', 'templates') as $file) {
        $hook = str_replace('-', '_', str_replace('.html.twig', '', $file->filename));
        $path = dirname($file->uri);
        $incomplete = !isset($cache[$hook]) || strrpos($hook, '__');

        // Create a new theme hook. This primarily happens when theme hook
        // suggestion templates are created. To prevent the new hook from
        // inheriting parent hook's "template", it must be manually set here.
        // @see https://www.drupal.org/node/2871551
        if (!isset($cache[$hook])) {
          $cache[$hook] = [
            'template' => str_replace('.html.twig', '', $file->filename),
          ];
        }

        // Always ensure that "path", "type" and "theme path" are properly set.
        $cache[$hook]['path'] = $path;
        $cache[$hook]['type'] = $current_theme ? 'theme' : 'base_theme';
        $cache[$hook]['theme path'] = $theme_path;

        // Flag incomplete.
        if ($incomplete) {
          $cache[$hook]['incomplete preprocess functions'] = TRUE;
        }
      }
    }

    // Discover all the theme's preprocess plugins.
    $preprocess_manager = new PreprocessManager($this->currentTheme);
    $plugins = $preprocess_manager
      ->getDefinitions();
    ksort($plugins, SORT_NATURAL);

    // Iterate over the preprocess plugins.
    foreach ($plugins as $plugin_id => $definition) {
      $incomplete = !isset($cache[$plugin_id]) || strrpos($plugin_id, '__');
      if (!isset($cache[$plugin_id])) {
        $cache[$plugin_id] = [];
      }
      array_walk($cache, function (&$info, $hook) use ($plugin_id, $definition) {
        if ($hook === $plugin_id || strpos($hook, $plugin_id . '__') === 0) {
          if (!isset($info['preprocess functions'])) {
            $info['preprocess functions'] = [];
          }

          // Due to a limitation in \Drupal\Core\Theme\ThemeManager::render,
          // callbacks must be functions and not classes. We always specify
          // "bootstrap_preprocess" here and then assign the plugin ID to a
          // separate property that we can later intercept and properly invoke.
          // @todo Revisit if/when preprocess callbacks can be any callable.
          Bootstrap::addCallback($info['preprocess functions'], 'bootstrap_preprocess', $definition['replace'], $definition['action']);
          $info['preprocess functions'] = array_unique($info['preprocess functions']);
          $info['bootstrap preprocess'] = $plugin_id;
        }
      });
      if ($incomplete) {
        $cache[$plugin_id]['incomplete preprocess functions'] = TRUE;
      }
    }

    // Allow core to post process.
    $this
      ->postProcessExtension($cache, $this->theme);
  }

}

Members

Namesort descending Modifiers Type Description Overrides
Registry::$cache protected property The cache backend to use for the complete theme registry data.
Registry::$initialized protected property Stores whether the registry was already initialized.
Registry::$lock protected property The lock backend that should be used.
Registry::$moduleHandler protected property The module handler to use to load modules.
Registry::$registry protected property The complete theme registry.
Registry::$root protected property The app root.
Registry::$runtimeCache protected property The runtime cache.
Registry::$runtimeRegistry protected property An array of incomplete, runtime theme registries, keyed by theme name.
Registry::$theme protected property The theme object representing the active theme for this registry.
Registry::$themeHandler protected property The theme handler.
Registry::$themeInitialization protected property The theme initialization.
Registry::$themeManager protected property The theme manager.
Registry::$themeName protected property The name of the theme for which to construct the registry, if given.
Registry::build protected function Builds the theme registry cache.
Registry::completeSuggestion protected function Completes the definition of the requested suggestion hook.
Registry::destruct public function Performs destruct operations. Overrides DestructableInterface::destruct
Registry::get public function Returns the complete theme registry from cache or rebuilds it.
Registry::getBaseHook public function Returns the base hook for a given hook suggestion.
Registry::getPath protected function Wraps drupal_get_path().
Registry::getPrefixGroupedUserFunctions public function Gets all user functions grouped by the word before the first underscore.
Registry::getRuntime public function Returns the incomplete, runtime theme registry.
Registry::init protected function Initializes a theme with a certain name.
Registry::mergePreprocessFunctions protected function Merges the source hook's preprocess functions into the destination hook's.
Registry::postProcessExtension protected function Completes the theme registry adding discovered functions and hooks.
Registry::processExtension protected function Process a single implementation of hook_theme().
Registry::reset public function Invalidates theme registry caches.
Registry::setCache protected function Persists the theme registry in the cache backend.
Registry::setThemeManager public function Sets the theme manager.
ThemeRegistry::$currentTheme protected property The currently set Bootstrap theme object.
ThemeRegistry::alter public function Alters data for a specific hook_TYPE_alter() implementation. Overrides AlterInterface::alter
ThemeRegistry::__construct public function Constructs a \Drupal\Core\Theme\Registry object. Overrides Registry::__construct