Esempio n. 1
0
 /**
  * Builds the theme registry cache.
  *
  * Theme hook definitions are collected in the following order:
  * - Modules
  * - Base theme engines
  * - Base themes
  * - Theme engine
  * - Theme
  *
  * All theme hook definitions are essentially just collated and merged in the
  * above order. However, various extension-specific default values and
  * customizations are required; e.g., to record the effective file path for
  * theme template. Therefore, this method first collects all extensions per
  * type, and then dispatches the processing for each extension to
  * processExtension().
  *
  * After completing the collection, modules are allowed to alter it. Lastly,
  * any derived and incomplete theme hook definitions that are hook suggestions
  * for base hooks (e.g., 'block__node' for the base hook 'block') need to be
  * determined based on the full registry and classified as 'base hook'.
  *
  * See the @link themeable Default theme implementations topic @endlink for
  * details.
  *
  * @return \Drupal\Core\Utility\ThemeRegistry
  *   The build theme registry.
  *
  * @see hook_theme_registry_alter()
  */
 protected function build()
 {
     $cache = array();
     // First, preprocess the theme hooks advertised by modules. This will
     // serve as the basic registry. Since the list of enabled modules is the
     // same regardless of the theme used, this is cached in its own entry to
     // save building it for every theme.
     if ($cached = $this->cache->get('theme_registry:build:modules')) {
         $cache = $cached->data;
     } else {
         foreach ($this->moduleHandler->getImplementations('theme') as $module) {
             $this->processExtension($cache, $module, 'module', $module, $this->getPath($module));
         }
         // Only cache this registry if all modules are loaded.
         if ($this->moduleHandler->isLoaded()) {
             $this->cache->set("theme_registry:build:modules", $cache, Cache::PERMANENT, array('theme_registry'));
         }
     }
     // Process each base theme.
     // Ensure that we start with the root of the parents, so that both CSS files
     // and preprocess functions comes first.
     foreach (array_reverse($this->theme->getBaseThemes()) as $base) {
         // If the base theme uses a theme engine, process its hooks.
         $base_path = $base->getPath();
         if ($this->theme->getEngine()) {
             $this->processExtension($cache, $this->theme->getEngine(), 'base_theme_engine', $base->getName(), $base_path);
         }
         $this->processExtension($cache, $base->getName(), 'base_theme', $base->getName(), $base_path);
     }
     // And then the same thing, but for the theme.
     if ($this->theme->getEngine()) {
         $this->processExtension($cache, $this->theme->getEngine(), 'theme_engine', $this->theme->getName(), $this->theme->getPath());
     }
     // Hooks provided by the theme itself.
     $this->processExtension($cache, $this->theme->getName(), 'theme', $this->theme->getName(), $this->theme->getPath());
     // Discover and add all preprocess functions for theme hook suggestions.
     $this->postProcessExtension($cache, $this->theme);
     // Let modules and themes alter the registry.
     $this->moduleHandler->alter('theme_registry', $cache);
     $this->themeManager->alterForTheme($this->theme, 'theme_registry', $cache);
     // @todo Implement more reduction of the theme registry entry.
     // Optimize the registry to not have empty arrays for functions.
     foreach ($cache as $hook => $info) {
         if (empty($info['preprocess functions'])) {
             unset($cache[$hook]['preprocess functions']);
         }
     }
     $this->registry[$this->theme->getName()] = $cache;
     return $this->registry[$this->theme->getName()];
 }
Esempio n. 2
0
 /**
  * Discovers files relevant to theme hooks.
  *
  * @param array $cache
  *   The theme registry, as documented in
  *   \Drupal\Core\Theme\Registry::processExtension().
  * @param \Drupal\Core\Theme\ActiveTheme $theme
  *   Current active theme.
  *
  * @see \Drupal\Core\Theme\Registry::processExtension()
  */
 protected function discoverFiles(array &$cache, ActiveTheme $theme)
 {
     $name = $theme->getName();
     $path = $theme->getPath();
     // Find theme hook files.
     foreach (_bootstrap_file_scan_directory($path, '/(\\.func\\.php|\\.vars\\.php|\\.html\\.twig)$/') as $file) {
         // Transform "-" in file names to "_" to match theme hook naming scheme.
         $hook = strtr($file->name, '-', '_');
         // Strip off the extension.
         if (($pos = strpos($hook, '.')) !== FALSE) {
             $hook = substr($hook, 0, $pos);
         }
         // File to be included by core when a theme hook is invoked.
         if (isset($cache[$hook])) {
             // Due to the order in which templates are discovered, a theme's
             // templates are first discovered while in the twig engine's
             // hook_theme() invocation. Correct the path to the template here.
             if (preg_match('/twig$/', $file->uri)) {
                 $cache[$hook]['path'] = dirname($file->uri);
             } else {
                 include_once DRUPAL_ROOT . '/' . $file->uri;
                 if (!isset($cache[$hook]['includes'])) {
                     $cache[$hook]['includes'] = array();
                 }
                 if (!in_array($file->uri, $cache[$hook]['includes'])) {
                     $cache[$hook]['includes'][] = $file->uri;
                 }
             }
             if (!isset($cache[$hook]['preprocess functions'])) {
                 $cache[$hook]['preprocess functions'] = array();
             }
             if (isset($cache[$hook]['template']) && function_exists($name . '_preprocess')) {
                 $cache[$hook]['preprocess functions'][] = $name . '_preprocess';
             }
             if (function_exists($name . '_preprocess_' . $hook)) {
                 $cache[$hook]['preprocess functions'][] = $name . '_preprocess_' . $hook;
                 $cache[$hook]['theme path'] = $path;
             }
         }
     }
 }