menu.inc 4.27 KB
Newer Older
Dries's avatar
 
Dries committed
1
<?php
Kjartan's avatar
Kjartan committed
2
// $Id$
Dries's avatar
 
Dries committed
3

4
/**
Dries's avatar
 
Dries committed
5
 * Register a menu item with the menu system.
6
 */
Dries's avatar
 
Dries committed
7
function menu($path, $title, $callback = NULL, $help = NULL, $weight = 0, $hidden = 0) {
8
  global $_list;
Dries's avatar
 
Dries committed
9

10 11
  // add the menu to the flat list of menu items:
  $_list[$path] = array("title" => $title, "callback" => $callback, "help" => $help, "weight" => $weight, "hidden" => $hidden);
Dries's avatar
 
Dries committed
12
}
Dries's avatar
 
Dries committed
13

14
/**
Dries's avatar
 
Dries committed
15
 * Returns an array with the menu items that lead to the specied path.
16
 */
Dries's avatar
 
Dries committed
17
function menu_get_trail($path) {
18
  global $_list;
Dries's avatar
 
Dries committed
19

Dries's avatar
 
Dries committed
20
  $trail = array();
Dries's avatar
 
Dries committed
21

Dries's avatar
 
Dries committed
22 23 24
  while ($path) {
    if ($_list[$path]) {
      array_unshift($trail, $path);
25
    }
Dries's avatar
 
Dries committed
26 27

    $path = substr($path, 0, strrpos($path, "/"));
Dries's avatar
 
Dries committed
28 29
  }

Dries's avatar
 
Dries committed
30
  return $trail;
Dries's avatar
 
Dries committed
31 32
}

Dries's avatar
 
Dries committed
33 34 35 36
/**
 * Returns the path of the active menu item.
 */
function menu_get_active_item() {
37
  global $_list;
Dries's avatar
 
Dries committed
38
  static $path;
Dries's avatar
 
Dries committed
39

Dries's avatar
 
Dries committed
40 41
  if (empty($path)) {
    $path = $_GET["q"];
Dries's avatar
 
Dries committed
42

Dries's avatar
 
Dries committed
43
    while ($path && !$_list[$path]) {
44
      $path = substr($path, 0, strrpos($path, "/"));
Dries's avatar
 
Dries committed
45
    }
Dries's avatar
 
Dries committed
46 47
  }

Dries's avatar
 
Dries committed
48
  return $path;
Dries's avatar
 
Dries committed
49 50
}

Dries's avatar
 
Dries committed
51 52 53
/**
* Returns the title of the active menu item.
*/
54 55
function menu_get_active_title() {
  global $_list;
Dries's avatar
 
Dries committed
56

Dries's avatar
 
Dries committed
57
  if ($path = menu_get_active_item()) {
58 59 60
    return ucfirst($_list[$path]["title"]);
  }
}
Dries's avatar
 
Dries committed
61

Dries's avatar
 
Dries committed
62 63 64
/**
* Returns the help associated with the active menu item.
*/
65 66
function menu_get_active_help() {
  global $_list;
Dries's avatar
 
Dries committed
67

Dries's avatar
 
Dries committed
68
  if ($path = menu_get_active_item()) {
69
    return $_list[$path]["help"];
Dries's avatar
 
Dries committed
70
  }
71 72
}

Dries's avatar
 
Dries committed
73 74 75 76
/**
 * Returns an array of rendered menu items in the active breadcrumb trail.
 */
function menu_get_active_breadcrumb() {
Dries's avatar
 
Dries committed
77

Dries's avatar
 
Dries committed
78
  $links[] = l(t("Home"), "");
79

Dries's avatar
 
Dries committed
80 81 82
  $trail = menu_get_trail($_GET["q"]);
  foreach ($trail as $item) {
    $links[] = _render_item($item);
Dries's avatar
 
Dries committed
83 84
  }

Dries's avatar
 
Dries committed
85
  return $links;
86 87 88
}


Dries's avatar
 
Dries committed
89 90 91 92 93
/**
 * Execute the handler associated with the active menu item.
 */
function menu_execute_active_handler() {
  global $_list;
94

Dries's avatar
 
Dries committed
95
  $path = menu_get_active_item();
96

Dries's avatar
 
Dries committed
97 98 99 100 101 102 103 104 105
  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));
    }
  }
Dries's avatar
 
Dries committed
106 107
}

Dries's avatar
 
Dries committed
108 109 110 111 112
/**
 * Returns true when the path is in the active trail.
 */
function menu_in_active_trail($path) {
  static $trail;
113

Dries's avatar
 
Dries committed
114 115 116
  if (empty($trail)) {
    $trail = menu_get_trail($_GET["q"]);
  }
117

Dries's avatar
 
Dries committed
118
  return in_array($path, $trail);
Dries's avatar
 
Dries committed
119
}
Dries's avatar
 
Dries committed
120

Dries's avatar
 
Dries committed
121 122 123
/**
 * Returns a rendered menu tree.
 */
Dries's avatar
 
Dries committed
124
function menu_tree($parent = "") {
125 126
  global $_list;
  static $trail;
Dries's avatar
 
Dries committed
127

Dries's avatar
 
Dries committed
128
  if (empty($trail)) {
Dries's avatar
 
Dries committed
129
    $trail = menu_get_trail($_GET["q"]);
130 131 132
  }

  if ($_list[$parent]["children"]) {
Dries's avatar
 
Dries committed
133
    $output = "\n<ul>\n";
134 135
    usort($_list[$parent]["children"], "_menu_sort");
    foreach ($_list[$parent]["children"] as $item) {
Dries's avatar
 
Dries committed
136 137 138 139 140 141
      /*
      ** 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"] == 0 && ($_list[$item]["callback"] || $_list[$item]["children"])) {
Dries's avatar
 
Dries committed
142
        $style = ($_list[$item]["children"] ? (menu_in_active_trail($item)  ? "expanded" : "collapsed") : "leaf");
Dries's avatar
 
Dries committed
143
        $output .= "<li class=\"$style\">";
Dries's avatar
 
Dries committed
144
        $output .= _render_item($item);
Dries's avatar
 
Dries committed
145
        if (menu_in_active_trail($item)) {
Dries's avatar
 
Dries committed
146 147 148 149
          $output .= menu_tree($item);
        }
        $output .= "</li>\n";
      }
Dries's avatar
 
Dries committed
150
    }
Dries's avatar
 
Dries committed
151
    $output .= "</ul>\n";
Dries's avatar
 
Dries committed
152 153
  }

Dries's avatar
 
Dries committed
154
  return $output;
Dries's avatar
 
Dries committed
155 156
}

Dries's avatar
 
Dries committed
157 158 159
/**
 * Query to module to build the menu.
 */
Dries's avatar
 
Dries committed
160
function menu_build($type) {
161 162 163
  /*
  ** Build a sequential list of all menus items.
  */
Dries's avatar
 
Dries committed
164 165

  module_invoke_all("link", $type);
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188

  /*
  ** 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;
    }
  }
Dries's avatar
 
Dries committed
189 190
}

Dries's avatar
 
Dries committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
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;

  if ($path == $_GET["q"]) {
    $css = " class=\"active\"";
  }

Dries's avatar
 
Dries committed
207
  return "<a href=\"". url($path) ."\"$css>". $_list[$path]["title"] ."</a>";
Dries's avatar
 
Dries committed
208 209 210
}


Dries's avatar
 
Dries committed
211
?>