reverted: --- b/core/includes/theme.inc +++ a/core/includes/theme.inc @@ -120,23 +120,6 @@ function drupal_find_theme_functions($cache, $prefixes) { $implementations = array(); $functions = get_defined_functions(); - static $lookup_table = NULL; - static $seen = array(); - - foreach ($functions['user'] as $function) { - if (isset($seen[$function])) { - continue; - } - $seen[$function] = TRUE; - $t = explode('_', $function); - $count = count($t); - $prefix = ''; - for ($i = 0; $i < $count; $i++) { - $prefix .= $t[$i]; - $lookup_table[$prefix][] = $function; - $prefix .= '_'; - } - } foreach ($cache as $hook => $info) { foreach ($prefixes as $prefix) { @@ -152,8 +135,8 @@ // are found using the base hook's pattern, not a pattern from an // intermediary suggestion. $pattern = isset($info['pattern']) ? $info['pattern'] : ($hook . '__'); + if (!isset($info['base hook']) && !empty($pattern)) { + $matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $functions['user']); - if (!isset($info['base hook']) && !empty($pattern) && isset($lookup_table[$prefix])) { - $matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $lookup_table[$prefix]); if ($matches) { foreach ($matches as $match) { $new_hook = substr($match, strlen($prefix) + 1); @@ -169,7 +152,7 @@ // Find theme functions that implement registered theme hooks and include // that in what is returned so that the registry knows that the theme has // this implementation. + if (function_exists($prefix . '_' . $hook)) { - if (isset($seen[$prefix . '_' . $hook])) { $implementations[$hook] = array( 'function' => $prefix . '_' . $hook, ); diff -u b/core/lib/Drupal/Core/Theme/Registry.php b/core/lib/Drupal/Core/Theme/Registry.php --- b/core/lib/Drupal/Core/Theme/Registry.php +++ b/core/lib/Drupal/Core/Theme/Registry.php @@ -537,37 +537,38 @@ // Merge the newly created theme hooks into the existing cache. $cache = $result + $cache; } + + // Let themes have variable preprocessors even if they didn't register a + // template. + if ($type == 'theme' || $type == 'base_theme') { + foreach ($cache as $hook => $info) { + // Check only if not registered by the theme or engine. + if (empty($result[$hook])) { + if (!isset($info['preprocess functions'])) { + $cache[$hook]['preprocess functions'] = array(); + } + // Only use non-hook-specific variable preprocessors for theme hooks + // implemented as templates. See _theme(). + if (isset($info['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; + } + } + } + } } /** * This completes the theme registry adding missing functions and hooks. * * @param array $cache - * The theme registry that will eventually be cached; It is an associative - * array keyed by theme hooks, whose values are associative arrays - * describing the hook: - * - 'type': The passed-in $type. - * - 'theme path': The passed-in $path. - * - 'function': The name of the function generating output for this theme - * hook. Either defined explicitly in hook_theme() or, if neither - * 'function' nor 'template' is defined, then the default theme function - * name is used. The default theme function name is the theme hook - * prefixed by either 'theme_' for modules or '$name_' for everything - * else. If 'function' is defined, 'template' is not used. - * - 'template': The filename of the template generating output for this - * theme hook. The template is in the directory defined by the 'path' key - * of hook_theme() or defaults to "$path/templates". - * - 'variables': The variables for this theme hook as defined in - * hook_theme(). If there is more than one implementation and 'variables' - * is not specified in a later one, then the previous definition is kept. - * - 'render element': The renderable element for this theme hook as defined - * in hook_theme(). If there is more than one implementation and - * 'render element' is not specified in a later one, then the previous - * definition is kept. - * - 'preprocess functions': See _theme() for detailed documentation. + * @see ::processExtension() * @param object $theme * Current active theme. - */ + */ protected function postProcessExtension(array &$cache, $theme) { // Get all user defined functions.