From f6ef76836c7a9d62a9e2631453f4a545ae7bb9ec Mon Sep 17 00:00:00 2001
From: Fabian Franz <Fabianx@693738.no-reply.drupal.org>
Date: Mon, 4 Jul 2016 22:24:29 -0700
Subject: [PATCH] Issue #2706191 by Goon3r, Dave Reid: Menu
 Access/Theme/Title/Page Delivery Callbacks: Allow Static Methods

---
 CHANGELOG.txt       | 2 ++
 includes/common.inc | 2 +-
 includes/menu.inc   | 6 +++---
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 6c5a9d007e32..531357609c30 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -59,6 +59,8 @@ Drupal 7.50, xxxx-xx-xx (development version)
 - Fixed Drupal 7.36 regression: hidden field textarea #default_value is
   ignored.
 - Made it possible to use any callable as an ajax form callback.
+- Made it possible to use any callable as menu access, menu theme, menu title
+  and page delivery callback.
 
 Drupal 7.44, 2016-06-15
 -----------------------
diff --git a/includes/common.inc b/includes/common.inc
index c97704cf60a3..6b51392df477 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -2617,7 +2617,7 @@ function drupal_deliver_page($page_callback_result, $default_delivery_callback =
   // Give modules a chance to alter the delivery callback used, based on
   // request-time context (e.g., HTTP request headers).
   drupal_alter('page_delivery_callback', $delivery_callback);
-  if (function_exists($delivery_callback)) {
+  if (is_callable($delivery_callback)) {
     $delivery_callback($page_callback_result);
   }
   else {
diff --git a/includes/menu.inc b/includes/menu.inc
index 05ecac060db4..6dcf70ee28ad 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -643,7 +643,7 @@ function _menu_check_access(&$item, $map) {
     if ($callback == 'user_access') {
       $item['access'] = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
     }
-    elseif (function_exists($callback)) {
+    elseif (is_callable($callback)) {
       $item['access'] = call_user_func_array($callback, $arguments);
     }
   }
@@ -703,7 +703,7 @@ function _menu_item_localize(&$item, $map, $link_translate = FALSE) {
         $item['title'] = t($item['title'], menu_unserialize($item['title_arguments'], $map));
       }
     }
-    elseif ($callback && function_exists($callback)) {
+    elseif ($callback && is_callable($callback)) {
       if (empty($item['title_arguments'])) {
         $item['title'] = $callback($item['title']);
       }
@@ -1763,7 +1763,7 @@ function menu_get_custom_theme($initialize = FALSE) {
     // If this returns a valid theme, it will override any theme that was set
     // by a hook_custom_theme() implementation above.
     $router_item = menu_get_item();
-    if (!empty($router_item['access']) && !empty($router_item['theme_callback']) && function_exists($router_item['theme_callback'])) {
+    if (!empty($router_item['access']) && !empty($router_item['theme_callback']) && is_callable($router_item['theme_callback'])) {
       $theme_name = call_user_func_array($router_item['theme_callback'], $router_item['theme_arguments']);
       if (drupal_theme_access($theme_name)) {
         $custom_theme = $theme_name;
-- 
GitLab