drupal/includes/menu.inc

267 lines
5.7 KiB
PHP
Raw Normal View History

2002-12-24 15:40:32 +00:00
<?php
2003-12-27 21:29:20 +00:00
/* $Id$ */
/**
* @defgroup menu Menu system
* @{
*/
define('MENU_SHOW', 0);
define('MENU_HIDE', 1);
define('MENU_HIDE_NOCHILD', 2);
/** @} */
2002-12-24 15:40:32 +00:00
/**
* Register a menu item with the menu system.
*
* @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 $weight Heavier menu items sink down the menu.
* @param $hidden
* - MENU_SHOW show the menu (default).
* - MENU_HIDE hide the menu item, but register a callback.
* - MENU_HIDE_NOCHILD hide the menu item when it has no children.
*/
function menu($path, $title, $callback = NULL, $weight = 0, $hidden = MENU_SHOW) {
global $_list;
// add the menu to the flat list of menu items:
$_list[$path] = array("title" => $title, "callback" => $callback, "weight" => $weight, "hidden" => $hidden);
}
2002-12-24 15:40:32 +00:00
/**
* Returns an array with the menu items that lead to the specified path.
*/
function menu_get_trail($path) {
global $_list;
2002-12-24 15:40:32 +00:00
$trail = array();
while ($path) {
if ($_list[$path]) {
array_unshift($trail, $path);
}
$path = substr($path, 0, strrpos($path, "/"));
}
return $trail;
}
/**
* Returns the path of the active menu item.
* @ingroup menu
*/
function menu_get_active_item() {
return menu_set_active_item();
}
/**
* Sets the path of the active menu item.
* @ingroup menu
*/
function menu_set_active_item($path = NULL) {
global $_list;
static $stored_path;
2002-12-24 15:40:32 +00:00
if (is_null($stored_path) || !empty($path)) {
if (empty($path)) {
$path = $_GET["q"];
}
else {
$_GET['q'] = $path;
}
2002-12-24 15:40:32 +00:00
while ($path && !$_list[$path]) {
$path = substr($path, 0, strrpos($path, "/"));
}
$stored_path = $path;
2002-12-24 15:40:32 +00:00
}
return $stored_path;
2002-12-24 15:40:32 +00:00
}
/**
* Returns the title of the active menu item.
*/
function menu_get_active_title() {
global $_list;
2002-12-24 15:40:32 +00:00
if ($path = menu_get_active_item()) {
return ucfirst($_list[$path]["title"]);
}
}
2002-12-24 15:40:32 +00:00
/**
* Returns the help associated with the active menu item.
*/
function menu_get_active_help() {
2002-12-24 15:40:32 +00:00
if (menu_active_handler_exists()) {
$path = $_GET["q"];
$output = "";
$return = module_invoke_all("help", $path);
foreach ($return as $item) {
if (!empty($item)) {
$output .= $item ."\n";
}
}
return $output;
2002-12-24 15:40:32 +00:00
}
}
/**
* Returns an array of rendered menu items in the active breadcrumb trail.
*/
function menu_get_active_breadcrumb() {
2002-12-24 15:40:32 +00:00
$links[] = l(t("Home"), "");
$trail = menu_get_trail($_GET["q"]);
foreach ($trail as $item) {
$links[] = _render_item($item);
2002-12-24 15:40:32 +00:00
}
return $links;
}
/**
* Execute the handler associated with the active menu item.
*/
function menu_execute_active_handler() {
global $_list;
$path = menu_get_active_item();
if ($_list[$path]["callback"]) {
$arg = substr($_GET["q"], strlen($path) + 1);
if (empty($arg)) {
return call_user_func($_list[$path]["callback"]);
}
else {
return call_user_func_array($_list[$path]["callback"], explode("/", $arg));
}
}
2002-12-24 15:40:32 +00:00
}
function menu_active_handler_exists() {
global $_list;
$path = menu_get_active_item();
return function_exists($_list[$path]["callback"]);
}
/**
* Returns true when the path is in the active trail.
*/
function menu_in_active_trail($path) {
static $trail;
if (empty($trail)) {
$trail = menu_get_trail($_GET["q"]);
}
return in_array($path, $trail);
}
2002-12-24 15:40:32 +00:00
/**
* Returns a rendered menu tree.
*/
2003-11-21 19:08:46 +00:00
function menu_tree($parent = "", $hidden = 0) {
global $_list;
static $trail;
$output = "";
if (empty($trail)) {
$trail = menu_get_trail($_GET["q"]);
}
if (isset($_list[$parent]) && $_list[$parent]["children"]) {
usort($_list[$parent]["children"], "_menu_sort");
foreach ($_list[$parent]["children"] as $item) {
/*
** Don't render the menu when it is hidden, or when it has no call-back
** nor children. The latter check avoids that useless links are being
** rendered.
*/
if (($_list[$item]["hidden"] == MENU_SHOW && ($_list[$item]["callback"] || $_list[$item]["children"])) || ($_list[$item]["hidden"] == MENU_HIDE_NOCHILD && $_list[$item]["children"])) {
$style = ($_list[$item]["children"] ? (menu_in_active_trail($item) ? "expanded" : "collapsed") : "leaf");
$output .= "<li class=\"$style\">";
$output .= _render_item($item);
if (menu_in_active_trail($item)) {
$output .= menu_tree($item);
}
$output .= "</li>\n";
}
else if ($_list[$item]["hidden"] == MENU_HIDE && $_list[$item]["children"]) {
2003-11-21 19:08:46 +00:00
$output .= menu_tree($item, 1);
}
}
if ($output != '' && $hidden != MENU_HIDE) {
$output = "\n<ul>\n$output\n</ul>\n";
}
2002-12-24 15:40:32 +00:00
}
return $output;
2002-12-24 15:40:32 +00:00
}
/**
* Query to module to build the menu.
*/
function menu_build($type) {
/*
** Build a sequential list of all menus items.
*/
module_invoke_all("link", $type);
/*
** Tree-ify the sequential list of menu items by adding each
** menu item to the 'children' array of their direct parent.
*/
global $_list;
foreach ($_list as $path => $data) {
/*
** Find $path's direct parent:
*/
$parent = $path;
do {
$parent = substr($parent, 0, strrpos($parent, "/"));
}
while ($parent && !$_list[$parent]);
if ($path) {
$_list[$parent]["children"][] = $path;
}
}
}
function _menu_sort($a, $b) {
global $_list;
$a = &$_list[$a];
$b = &$_list[$b];
return $a["weight"] < $b["weight"] ? -1 : ($a["weight"] > $b["weight"] ? 1 : ($a["title"] < $b["title"] ? -1 : 1));
}
function _render_item($path) {
global $_list;
return l($_list[$path]["title"], $path);
}
?>