summaryrefslogtreecommitdiff
path: root/includes/menu.inc
diff options
context:
space:
mode:
Diffstat (limited to 'includes/menu.inc')
-rw-r--r--includes/menu.inc61
1 files changed, 46 insertions, 15 deletions
diff --git a/includes/menu.inc b/includes/menu.inc
index 9a7c7234d..4ccd126cb 100644
--- a/includes/menu.inc
+++ b/includes/menu.inc
@@ -15,6 +15,10 @@ define('MENU_MODIFIED', 1);
define('MENU_LOCKED', 2);
define('MENU_CUSTOM', 3);
+define('MENU_FALLTHROUGH', 0);
+define('MENU_DENIED', 1);
+define('MENU_FOUND', 2);
+
/** @} */
/**
@@ -23,7 +27,10 @@ define('MENU_CUSTOM', 3);
* @ingroup menu
* @param $path Location then menu item refers to.
* @param $title The title of the menu item to show in the rendered menu.
- * @param $callback The function to call when this is the active menu item.
+ * @param $callback
+ * - string - The function to call when this is the active menu item.
+ * - MENU_FALLTHROUGH - Use the callback defined by the menu item's parent.
+ * - MENU_DENIED - Deny access to this menu item by this user.
* @param $weight Heavier menu items sink down the menu.
* @param $visibility
* - MENU_SHOW - Show the menu item (default).
@@ -31,11 +38,9 @@ define('MENU_CUSTOM', 3);
* - MENU_HIDE_NOCHILD - Hide the menu item when it has no children.
* @param $status
* - MENU_NORMAL - The menu item can be moved (default).
- * - MENU_MODIFIED - The administrator has moved or otherwise changed the menu item.
* - MENU_LOCKED - The administrator may not modify the item.
- * - MENU_CUSTOM - The menu item was created by the administrator.
*/
-function menu($path, $title, $callback = NULL, $weight = 0, $visibility = MENU_SHOW, $status = MENU_NORMAL) {
+function menu($path, $title, $callback = MENU_FALLTHROUGH, $weight = 0, $visibility = MENU_SHOW, $status = MENU_NORMAL) {
global $_menu;
// add the menu to the flat list of menu items:
@@ -90,7 +95,13 @@ function menu_get_trail($path) {
$trail = array();
- $mid = menu_get_active_item();
+ // Find the ID of the given path.
+ while ($path && !$menu['path index'][$path]) {
+ $path = substr($path, 0, strrpos($path, '/'));
+ }
+ $mid = $menu['path index'][$path];
+
+ // Follow the parents up the chain to get the trail.
while ($mid && $menu['items'][$mid]) {
array_unshift($trail, $mid);
$mid = $menu['items'][$mid]['pid'];
@@ -171,9 +182,13 @@ function menu_get_active_breadcrumb() {
$links[] = l(t('Home'), '');
$trail = menu_get_trail($_GET['q']);
+
+ // The last item in the trail is the page title; don't display it here.
+ array_pop($trail);
+
foreach ($trail as $mid) {
- // Don't show menu items without valid link targets.
- if ($menu['items'][$mid]['path'] != '') {
+ // Don't show hidden menu items or items without valid link targets.
+ if (isset($menu['visible'][$mid]) && $menu['items'][$mid]['path'] != '') {
$links[] = _menu_render_item($mid);
}
}
@@ -188,20 +203,26 @@ function menu_execute_active_handler() {
$menu = menu_get_menu();
$path = $_GET['q'];
- while ($path && (!$menu['path index'][$path] || !$menu['items'][$menu['path index'][$path]]['callback'])) {
+ while ($path && (!$menu['path index'][$path] || $menu['items'][$menu['path index'][$path]]['callback'] === MENU_FALLTHROUGH)) {
$path = substr($path, 0, strrpos($path, '/'));
}
$mid = $menu['path index'][$path];
+ if ($menu['items'][$mid]['callback'] === MENU_DENIED) {
+ return MENU_DENIED;
+ }
- if ($menu['items'][$mid]['callback']) {
+ if (is_string($menu['items'][$mid]['callback'])) {
$arg = substr($_GET['q'], strlen($menu['items'][$mid]['path']) + 1);
if (isset($arg)) {
- return call_user_func_array($menu['items'][$mid]['callback'], explode('/', $arg));
+ call_user_func_array($menu['items'][$mid]['callback'], explode('/', $arg));
}
else {
- return call_user_func($menu['items'][$mid]['callback']);
+ call_user_func($menu['items'][$mid]['callback']);
}
+ return MENU_FOUND;
}
+
+ return MENU_FALLTHROUGH;
}
/**
@@ -211,11 +232,18 @@ function menu_active_handler_exists() {
$menu = menu_get_menu();
$path = $_GET['q'];
- while ($path && (!$menu['path index'][$path] || !$menu['items'][$menu['path index'][$path]]['callback'])) {
+ while ($path && (!$menu['path index'][$path] || $menu['items'][$menu['path index'][$path]]['callback'] === MENU_FALLTHROUGH)) {
$path = substr($path, 0, strrpos($path, '/'));
}
$mid = $menu['path index'][$path];
+ if ($menu['items'][$mid]['callback'] === MENU_FALLTHROUGH) {
+ return FALSE;
+ }
+ if ($menu['items'][$mid]['callback'] === MENU_DENIED) {
+ return FALSE;
+ }
+
return function_exists($menu['items'][$mid]['callback']);
}
@@ -298,7 +326,7 @@ function menu_build() {
while ($item = db_fetch_object($result)) {
// First, add any custom items added by the administrator.
if ($item->status == MENU_CUSTOM) {
- $_menu['items'][$item->mid] = array('pid' => $item->pid, 'path' => $item->path, 'title' => $item->title, 'callback' => NULL, 'weight' => $item->weight, 'visibility' => MENU_SHOW, 'status' => MENU_CUSTOM);
+ $_menu['items'][$item->mid] = array('pid' => $item->pid, 'path' => $item->path, 'title' => $item->title, 'callback' => MENU_FALLTHROUGH, 'weight' => $item->weight, 'visibility' => MENU_SHOW, 'status' => MENU_CUSTOM);
$_menu['path index'][$item->path] = $item->mid;
}
// Don't display non-custom menu items if no module declared them.
@@ -371,9 +399,12 @@ function menu_build_visible_tree($pid = 0) {
$children = array_merge($children, menu_build_visible_tree($mid));
}
}
- if (($parent['visibility'] == MENU_SHOW) ||
- ($parent['visibility'] == MENU_HIDE_NOCHILD && count($children) > 1)) {
+ if ((($parent['visibility'] == MENU_SHOW) ||
+ ($parent['visibility'] == MENU_HIDE_NOCHILD && count($children) > 1)) && $parent['callback'] !== MENU_DENIED) {
$_menu['visible'][$pid] = array('title' => $parent['title'], 'path' => $parent['path'], 'children' => $children);
+ foreach ($children as $mid) {
+ $_menu['visible'][$mid]['pid'] = $pid;
+ }
return array($pid);
}
else {