menu.inc

  1. 7.x includes/menu.inc
  2. 6.x includes/menu.inc
  3. 4.x includes/menu.inc
  4. 5.x includes/menu.inc

File

includes/menu.inc
View source
  1. <?php
  2. /**
  3. * This file contains mostly menu-related all-purpose functions
  4. * for FlightPath
  5. */
  6. /**
  7. * Look for modules implementing hook_menu_handle_replacement_pattern, and apply to str.
  8. *
  9. * @param unknown_type $str
  10. */
  11. function menu_convert_replacement_pattern($str) {
  12. // Find modules which implement the hook_menu_handle_replacement_pattern function.
  13. $modules = modules_implement_hook("menu_handle_replacement_pattern");
  14. foreach($modules as $module) {
  15. $str = call_user_func($module . '_menu_handle_replacement_pattern', $str);
  16. }
  17. return $str;
  18. }
  19. /**
  20. * Go through all installed modules and rebuild the menu_router table,
  21. * based on each module's hook_menu function.
  22. */
  23. function menu_rebuild_cache($bool_display_message = TRUE) {
  24. // Begin by wiping out the menu_router table
  25. db_query("TRUNCATE TABLE menu_router ");
  26. $modules = modules_implement_hook("menu");
  27. foreach ($modules as $module) {
  28. $items = call_user_func($module . "_menu");
  29. // Okay, now go through the $items array, and write the needed information
  30. // to the menu_router array.
  31. foreach ($items as $path => $item) {
  32. if (is_numeric($path)) continue; // problem, so skip.
  33. // Update our menu_router table.
  34. // Now, insert the new one.
  35. db_query("INSERT INTO menu_router
  36. (path, access_callback, access_arguments, page_callback, page_arguments, title, description, type, weight, icon, page_settings, tab_family, tab_parent, file)
  37. VALUES
  38. ('?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?')
  39. ", $path, $item["access_callback"], serialize($item["access_arguments"]), $item["page_callback"],
  40. serialize($item['page_arguments']), $item['title'], $item['description'], $item['type'], $item['weight'], $item['icon'],
  41. serialize($item['page_settings']), $item['tab_family'], $item['tab_parent'], $item['file']);
  42. }
  43. }
  44. if ($bool_display_message) {
  45. fp_add_message(t("The menu router has been rebuilt"));
  46. }
  47. }
  48. function menu_get_module_path($module, $bool_include_file_system_path = FALSE) {
  49. $system_path = "";
  50. if ($bool_include_file_system_path) {
  51. $system_path = $GLOBALS["fp_system_settings"]["file_system_path"] . "/";
  52. }
  53. if (isset($GLOBALS["fp_system_settings"]["modules"][$module]["path"])) {
  54. return $system_path . $GLOBALS["fp_system_settings"]["modules"][$module]["path"];
  55. }
  56. else {
  57. return FALSE;
  58. }
  59. }
  60. /**
  61. * Looks at the router item's details (from menu_get_item)
  62. * and returns TRUE or FALSE if the user can access this item.
  63. */
  64. function menu_check_user_access($router_item) {
  65. $access = FALSE;
  66. if ($router_item["access_callback"] == 1) {
  67. $access = TRUE;
  68. }
  69. if (is_array($router_item["access_arguments"])) {
  70. if ($router_item["access_callback"] == "") {
  71. // If we specified access arguments, but not a callback, assume it
  72. // is the function user_has_permission().
  73. $router_item["access_callback"] = "user_has_permission";
  74. }
  75. }
  76. if (!$access && $router_item["access_callback"] != "") {
  77. // We need to see if the user has the right permissions to use this item. We will do this
  78. // by calling the access_callback, passing it the access_arguments
  79. $access = call_user_func_array($router_item["access_callback"], $router_item["access_arguments"]);
  80. }
  81. return $access;
  82. }
  83. function menu_execute_page_request() {
  84. $path = $_GET["q"];
  85. //If the path is blank, figure out what the "font page" is, and use that path.
  86. if ($path == "") {
  87. $path = variable_get("front_page", "main");
  88. }
  89. if ($router_item = menu_get_item($path)) {
  90. // Let's save the router item in the GLOBALS array, so we can use information from it
  91. // throughout FlightPath, if we need to.
  92. $GLOBALS["fp_current_menu_router_item"] = $router_item;
  93. // If the menu item contains a "redirect", then we should perform
  94. // an fp_goto to that immediately.
  95. if (isset($router_item["page_settings"]["redirect"])) {
  96. $p = $router_item["page_settings"]["redirect"]["path"];
  97. $q = $router_item["page_settings"]["redirect"]["query"];
  98. fp_goto($p, $q);
  99. return;
  100. }
  101. // Let's figure out if the user has access to this menu item or not.
  102. if (menu_check_user_access($router_item)) {
  103. if ($router_item['file'] != "") {
  104. require_once($router_item['file']);
  105. }
  106. $page = array();
  107. $page["content"] = call_user_func_array($router_item['page_callback'], $router_item['page_arguments']);
  108. $page["path"] = $path;
  109. $page["title"] = $router_item["title"];
  110. $page["router_item"] = $router_item;
  111. return $page;
  112. }
  113. else {
  114. return MENU_ACCESS_DENIED;
  115. }
  116. }
  117. return MENU_NOT_FOUND;
  118. }
  119. /**
  120. * Return menu_items whose path begins with the menu_root.
  121. * Ex: "tools" would return tools/fun and tools/here/there
  122. */
  123. function menu_get_items_beginning_with($menu_root) {
  124. $rtn = array();
  125. $res = db_query("SELECT path FROM menu_router WHERE path LIKE '?%'
  126. ORDER BY weight, title", $menu_root);
  127. while ($cur = db_fetch_array($res)) {
  128. $path = $cur["path"];
  129. $item = menu_get_item($path);
  130. if ($item) {
  131. $rtn[] = $item;
  132. }
  133. }
  134. return $rtn;
  135. }
  136. function menu_get_items_in_tab_family($tab_family) {
  137. $rtn = array();
  138. $res = db_query("SELECT path FROM menu_router WHERE tab_family = '?'
  139. ORDER BY weight, title", $tab_family);
  140. while ($cur = db_fetch_array($res)) {
  141. $path = $cur["path"];
  142. $item = menu_get_item($path);
  143. if ($item) {
  144. $rtn[] = $item;
  145. }
  146. }
  147. return $rtn;
  148. }
  149. /**
  150. * Figure out which menu_router path matches the supplied path and return it.
  151. *
  152. */
  153. function menu_get_item($path) {
  154. // Since the menu item may be using wildcards, we must
  155. // try to figure out exactly which defined path is the best one
  156. // to take.
  157. // To cut down on the amount we need to query, we will use a global variable.
  158. if (!isset($GLOBALS["fp_menu_items"]) || !is_array($GLOBALS["fp_menu_items"]) || count($GLOBALS["fp_menu_items"]) == 0) {
  159. // The global array is not set. Let's populate it from the database.
  160. $res = db_query("SELECT path FROM menu_router");
  161. while ($cur = db_fetch_array($res)) {
  162. $GLOBALS["fp_menu_items"][] = $cur["path"];
  163. }
  164. }
  165. $menu_items = $GLOBALS["fp_menu_items"];
  166. // Okay, first things first, does the path *exactly* match anything in our GLOBALS array?
  167. if (in_array($path, $menu_items)) {
  168. return menu_get_menu_router_item_from_db($path);
  169. }
  170. // If we are here, we didn't see an exact match. That may mean we are using wildcards,
  171. // and therefore we should pick only the best match.
  172. // For example, if the path is "node/5/edit", we should return the
  173. // menu_router item "node/%/edit", but not "node/%/%". We will figure this out
  174. // by breaking up our paths into pieces, and then comparing each piece, and scoring URLs
  175. // as we do on how many levels they match on. The URL with the higest match wins.
  176. $defined_score = array();
  177. // Now, go through and find the best URL definition that matches the given URL.
  178. $given_pieces = explode("/", $path);
  179. foreach ($menu_items as $defined_url) {
  180. $defined_pieces = explode("/", $defined_url);
  181. // First, make only look for the ones with the exact same count as us...
  182. if (count($defined_pieces) != count($given_pieces)) continue;
  183. $defined_score[$defined_url]++;
  184. // Okay, now go through the pieces and compare.
  185. foreach ($defined_pieces as $c => $defined_piece) {
  186. // If it's exactly a match, then inc its score.
  187. if ($defined_piece == $given_pieces[$c]) {
  188. $defined_score[$defined_url]++;
  189. }
  190. // If it's totally off, then kick it out!
  191. if ($defined_piece != "%" && $defined_piece != $given_pieces[$c]) {
  192. unset($defined_score[$defined_url]);
  193. break;
  194. }
  195. }
  196. }
  197. arsort($defined_score);
  198. $best_match_path = "";
  199. if (count($defined_score) > 0) {
  200. $best_match_path = key($defined_score);
  201. }
  202. // Okay, the best_match_path is the one that best fits our path. Let's return the details
  203. // for it from menu_router.
  204. if ($best_match_path) {
  205. return menu_get_menu_router_item_from_db($best_match_path);
  206. }
  207. // Else, nothing was found!
  208. return NULL;
  209. }
  210. /**
  211. * Return array from menu_router for this item. *
  212. */
  213. function menu_get_menu_router_item_from_db($path) {
  214. $res = db_query("SELECT * FROM menu_router WHERE path = '?' ", $path);
  215. $cur = db_fetch_array($res);
  216. if ($cur["path"] != $path) {
  217. // It was not found!
  218. return NULL;
  219. }
  220. // Unserialize the things which are supposed to be unserialized.
  221. $cur["page_arguments"] = unserialize($cur["page_arguments"]);
  222. if (!is_array($cur["page_arguments"])) {
  223. $cur["page_arguments"] = array();
  224. }
  225. // If any of the page_arguments is a number by itself, we will instead
  226. // use the number of the URL args.
  227. // For example, if the URL path is "node/edit/apple"
  228. // and there is a page_argument for the number 2, we will replace
  229. // it with "apple". This is how the menu system can use wildcards from the url
  230. // for the page arguments.
  231. foreach ($cur["page_arguments"] as $c => $arg) {
  232. if (is_numeric($arg)) {
  233. $temp = explode("/", $_REQUEST["q"]);
  234. $cur["page_arguments"][$c] = $temp[$arg];
  235. }
  236. }
  237. $cur["access_arguments"] = unserialize($cur["access_arguments"]);
  238. if (!is_array($cur["access_arguments"])) {
  239. $cur["access_arguments"] = array();
  240. }
  241. // Same situation for access_arguments as the page_arguments above.
  242. foreach ($cur["access_arguments"] as $c => $arg) {
  243. if (is_numeric($arg)) {
  244. $temp = explode("/", $_REQUEST["q"]);
  245. $cur["access_arguments"][$c] = $temp[$arg];
  246. }
  247. }
  248. $cur["page_settings"] = unserialize($cur["page_settings"]);
  249. if (!is_array($cur["page_settings"])) {
  250. $cur["page_settings"] = array();
  251. }
  252. // If there is a title property, run it through t()
  253. if ($cur["title"] != "") {
  254. $cur["title"] = t($cur["title"]);
  255. }
  256. // If there is a description, run through t()
  257. if ($cur["description"] != "") {
  258. $cur["description"] = t($cur["description"]);
  259. }
  260. // If the page_settings has menu links, run their texts through t().
  261. foreach ($cur["page_settings"] as $key => $val) {
  262. if ($key == "menu_links" && is_array($val)) {
  263. foreach ($val as $c => $mitems) {
  264. if ($mitems["text"] != "") {
  265. $cur["page_settings"]["menu_links"][$c]["text"] = t($mitems["text"]);
  266. }
  267. }
  268. }
  269. }
  270. return $cur;
  271. }

Functions

Namesort descending Description
menu_check_user_access Looks at the router item's details (from menu_get_item) and returns TRUE or FALSE if the user can access this item.
menu_convert_replacement_pattern Look for modules implementing hook_menu_handle_replacement_pattern, and apply to str.
menu_execute_page_request
menu_get_item Figure out which menu_router path matches the supplied path and return it.
menu_get_items_beginning_with Return menu_items whose path begins with the menu_root. Ex: "tools" would return tools/fun and tools/here/there
menu_get_items_in_tab_family
menu_get_menu_router_item_from_db Return array from menu_router for this item. *
menu_get_module_path
menu_rebuild_cache Go through all installed modules and rebuild the menu_router table, based on each module's hook_menu function.