diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 61e4de14b2dfb4d1829436ce18587c168e5fa543..11b921dc0012d38fece27a53349f970f41e78ef5 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -109,17 +109,17 @@ function drupal_theme_rebuild() {
/**
* Allows themes and/or theme engines to discover overridden theme functions.
*
- * @param $cache
+ * @param array $cache
* The existing cache of theme hooks to test against.
- * @param $prefixes
+ * @param array $prefixes
* An array of prefixes to test, in reverse order of importance.
*
- * @return $implementations
+ * @return array
* The functions found, suitable for returning from hook_theme;
*/
function drupal_find_theme_functions($cache, $prefixes) {
- $implementations = array();
- $functions = get_defined_functions();
+ $implementations = [];
+ $grouped_functions = drupal_group_functions_by_prefix();
foreach ($cache as $hook => $info) {
foreach ($prefixes as $prefix) {
@@ -135,8 +135,10 @@ function drupal_find_theme_functions($cache, $prefixes) {
// 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']);
+ // Grep only the functions which are within the prefix group.
+ list($first_prefix,) = explode('_', $prefix, 2);
+ if (!isset($info['base hook']) && !empty($pattern) && isset($grouped_functions[$first_prefix])) {
+ $matches = preg_grep('/^' . $prefix . '_' . $pattern . '/', $grouped_functions[$first_prefix]);
if ($matches) {
foreach ($matches as $match) {
$new_hook = substr($match, strlen($prefix) + 1);
@@ -163,6 +165,25 @@ function drupal_find_theme_functions($cache, $prefixes) {
return $implementations;
}
+/**
+ * Group all user functions by word before first underscore.
+ *
+ * @return array
+ * Functions grouped by the first prefix.
+ */
+function drupal_group_functions_by_prefix() {
+ $functions = get_defined_functions();
+
+ $grouped_functions = [];
+ // Splitting user defined functions into groups by the first prefix.
+ foreach ($functions['user'] as $function) {
+ list($first_prefix,) = explode('_', $function, 2);
+ $grouped_functions[$first_prefix][] = $function;
+ }
+
+ return $grouped_functions;
+}
+
/**
* Allows themes and/or theme engines to easily discover overridden templates.
*