menu.inc

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

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.