- Patch #151583 by pwolanin, Shakur, webernet, Arancaytar et al: various menu module fixes.
parent
8cd661b82b
commit
e0fe1ae8eb
|
|
@ -67,7 +67,7 @@
|
|||
*
|
||||
* Everything described so far is stored in the menu_router table. The
|
||||
* menu_links table holds the visible menu links. By default these are
|
||||
* derived from the same hook_menu definitions, however you are free to
|
||||
* derived from the same hook_menu definitons, however you are free to
|
||||
* add more with menu_link_save().
|
||||
*/
|
||||
|
||||
|
|
@ -297,7 +297,6 @@ function menu_get_item($path = NULL) {
|
|||
/**
|
||||
* Execute the page callback associated with the current path
|
||||
*/
|
||||
|
||||
function menu_execute_active_handler($path = NULL) {
|
||||
if (_menu_site_is_offline()) {
|
||||
return MENU_SITE_OFFLINE;
|
||||
|
|
@ -378,6 +377,9 @@ function _menu_check_access(&$item, $map) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Localize the item title using t() or another callback.
|
||||
*/
|
||||
function _menu_item_localize(&$item) {
|
||||
// Translate the title to allow storage of English title strings
|
||||
// in the database, yet display of them in the language required
|
||||
|
|
@ -514,15 +516,15 @@ function _menu_link_translate(&$item) {
|
|||
_menu_link_map_translate($map, $item['to_arg_functions']);
|
||||
$item['href'] = implode('/', $map);
|
||||
|
||||
// Note- skip callbacks without real values for their arguments
|
||||
// Note- skip callbacks without real values for their arguments.
|
||||
if (strpos($item['href'], '%') !== FALSE) {
|
||||
$item['access'] = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
// TODO: menu_tree_data may set this ahead of time for links to nodes
|
||||
// menu_tree_check_access() may set this ahead of time for links to nodes.
|
||||
if (!isset($item['access'])) {
|
||||
if (!_menu_load_objects($item, $map)) {
|
||||
// An error occurred loading an object
|
||||
// An error occured loading an object.
|
||||
$item['access'] = FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -606,16 +608,22 @@ function menu_tree_output($tree) {
|
|||
function menu_tree_all_data($menu_name = 'navigation', $item = NULL, $show_hidden = FALSE) {
|
||||
static $tree = array();
|
||||
|
||||
// Use $mlid as a flag for whether the data being loaded is for the whole tree.
|
||||
$mlid = isset($item['mlid']) ? $item['mlid'] : 0;
|
||||
// Generate the cache ID.
|
||||
$cid = 'links:'. $menu_name .':all:'. $mlid .':'. (int)$show_hidden;
|
||||
|
||||
if (!isset($tree[$cid])) {
|
||||
// If the static variable doesn't have the data, check {cache_menu}.
|
||||
$cache = cache_get($cid, 'cache_menu');
|
||||
if ($cache && isset($cache->data)) {
|
||||
$tree[$cid] = $cache->data;
|
||||
}
|
||||
else {
|
||||
// Build and run the query, and build the tree.
|
||||
if ($mlid) {
|
||||
// The tree is for a single item, so we need to match the values in its
|
||||
// p columns and 0 (the top level) with the plid values of other links.
|
||||
$args = array(0, $item['p1'], $item['p2'], $item['p3'], $item['p4'], $item['p5']);
|
||||
$args = array_unique($args);
|
||||
$placeholders = implode(', ', array_fill(0, count($args), '%d'));
|
||||
|
|
@ -624,26 +632,28 @@ function menu_tree_all_data($menu_name = 'navigation', $item = NULL, $show_hidde
|
|||
$parents[] = $item['mlid'];
|
||||
}
|
||||
else {
|
||||
// Get all links in this menu.
|
||||
$where = '';
|
||||
$args = array();
|
||||
$parents = array();
|
||||
}
|
||||
if (!$show_hidden) {
|
||||
$where .= ' AND ml.hidden = 0';
|
||||
}
|
||||
else {
|
||||
$where .= ' AND ml.hidden > 0';
|
||||
}
|
||||
array_unshift($args, $menu_name);
|
||||
list(, $tree[$cid]) = _menu_tree_data(db_query("
|
||||
// Select the links from the table, and recursively build the tree. We
|
||||
// LEFT JOIN since there is no match in {menu_router} for an external link.
|
||||
// We need to select links that are visible or hidden (ml.hidden >= 0), but
|
||||
// not callbacks (ml.hidden < 0), so that we can later exclude all the
|
||||
// children of a hidden item.
|
||||
// No need to order by p6 - there is a sort by weight later.
|
||||
$tree[$cid] = menu_tree_data(db_query("
|
||||
SELECT m.*, ml.menu_name, ml.mlid, ml.plid, ml.link_path, ml.router_path, ml.hidden, ml.external, ml.has_children, ml.expanded, ml.weight + 50000 AS weight, ml.depth, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.module, ml.link_title, ml.options
|
||||
FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
|
||||
WHERE ml.menu_name = '%s'". $where ."
|
||||
WHERE ml.menu_name = '%s'". $where ." AND ml.hidden >= 0
|
||||
ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC", $args), $parents);
|
||||
// Cache the data.
|
||||
cache_set($cid, $tree[$cid], 'cache_menu');
|
||||
}
|
||||
// TODO: special case node links and access check via db_rewite_sql()
|
||||
_menu_tree_check_access($tree[$cid]);
|
||||
// Check access for the current user to each item in the tree.
|
||||
menu_tree_check_access($tree[$cid], $show_hidden);
|
||||
}
|
||||
|
||||
return $tree[$cid];
|
||||
|
|
@ -651,7 +661,7 @@ function menu_tree_all_data($menu_name = 'navigation', $item = NULL, $show_hidde
|
|||
|
||||
/**
|
||||
* Get the data structure representing a named menu tree, based on the current
|
||||
* page. The tree order is maintained by storing each parent in an individual
|
||||
* page. The tree order is maintained by storing each parent in an invidual
|
||||
* field, see http://drupal.org/node/141866 for more.
|
||||
*
|
||||
* @param $menu_name
|
||||
|
|
@ -666,28 +676,38 @@ function menu_tree_all_data($menu_name = 'navigation', $item = NULL, $show_hidde
|
|||
function menu_tree_page_data($menu_name = 'navigation') {
|
||||
static $tree = array();
|
||||
|
||||
// Load the menu item corresponding to the current page.
|
||||
if ($item = menu_get_item()) {
|
||||
// Generate the cache ID.
|
||||
$cid = 'links:'. $menu_name .':page:'. $item['href'] .':'. (int)$item['access'];
|
||||
|
||||
if (!isset($tree[$cid])) {
|
||||
// If the static variable doesn't have the data, check {cache_menu}.
|
||||
$cache = cache_get($cid, 'cache_menu');
|
||||
if ($cache && isset($cache->data)) {
|
||||
$tree[$cid] = $cache->data;
|
||||
}
|
||||
else {
|
||||
// Build and run the query, and build the tree.
|
||||
if ($item['access']) {
|
||||
// Check whether a menu link exists that corresponds to the current path.
|
||||
$parents = db_fetch_array(db_query("SELECT p1, p2, p3, p4, p5, p6 FROM {menu_links} WHERE menu_name = '%s' AND link_path = '%s'", $menu_name, $item['href']));
|
||||
// We may be on a local task that's not in the links
|
||||
// TODO how do we handle the case like a local task on a specific node in the menu?
|
||||
|
||||
if (empty($parents)) {
|
||||
// If no link exists, we may be on a local task that's not in the links.
|
||||
// TODO: handle the case like a local task on a specific node in the menu.
|
||||
$parents = db_fetch_array(db_query("SELECT p1, p2, p3, p4, p5, p6 FROM {menu_links} WHERE menu_name = '%s' AND link_path = '%s'", $menu_name, $item['tab_root']));
|
||||
}
|
||||
// We always want all the top-level links with plid == 0.
|
||||
$parents[] = '0';
|
||||
|
||||
$args = $parents = array_unique($parents);
|
||||
$placeholders = implode(', ', array_fill(0, count($args), '%d'));
|
||||
$expanded = variable_get('menu_expanded', array());
|
||||
// Check whether the current menu has any links set to be expanded.
|
||||
if (in_array($menu_name, $expanded)) {
|
||||
// Collect all the links set to be expanded, and then add all their
|
||||
// children to the list also.
|
||||
do {
|
||||
$result = db_query("SELECT mlid FROM {menu_links} WHERE expanded != 0 AND has_children != 0 AND menu_name = '%s' AND plid IN (". $placeholders .') AND mlid NOT IN ('. $placeholders .')', array_merge(array($menu_name), $args, $args));
|
||||
while ($item = db_fetch_array($result)) {
|
||||
|
|
@ -698,23 +718,28 @@ function menu_tree_page_data($menu_name = 'navigation') {
|
|||
}
|
||||
array_unshift($args, $menu_name);
|
||||
}
|
||||
// Show the root menu for access denied.
|
||||
else {
|
||||
$args = array('navigation', '0');
|
||||
// Show only the top-level menu items when access is denied.
|
||||
$args = array($menu_name, '0');
|
||||
$placeholders = '%d';
|
||||
$parents = array();
|
||||
}
|
||||
// Select the links from the table, and recursively build the tree. We
|
||||
// LEFT JOIN since there is no match in {menu_router} for an external link.
|
||||
// We need to select links that are visible or hidden (ml.hidden >= 0), but
|
||||
// not callbacks (ml.hidden < 0), so that we can later exclude all the
|
||||
// children of a hidden item.
|
||||
// No need to order by p6 - there is a sort by weight later.
|
||||
list(, $tree[$cid]) = _menu_tree_data(db_query("
|
||||
$tree[$cid] = menu_tree_data(db_query("
|
||||
SELECT m.*, ml.menu_name, ml.mlid, ml.plid, ml.link_path, ml.router_path, ml.hidden, ml.external, ml.has_children, ml.expanded, ml.weight + 50000 AS weight, ml.depth, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.module, ml.link_title, ml.options
|
||||
FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
|
||||
WHERE ml.menu_name = '%s' AND ml.plid IN (". $placeholders .") AND ml.hidden = 0
|
||||
WHERE ml.menu_name = '%s' AND ml.plid IN (". $placeholders .") AND ml.hidden >= 0
|
||||
ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC", $args), $parents);
|
||||
// Cache the data.
|
||||
cache_set($cid, $tree[$cid], 'cache_menu');
|
||||
}
|
||||
// TODO: special case node links and access check via db_rewite_sql()
|
||||
_menu_tree_check_access($tree[$cid]);
|
||||
// Check access for the current user to each item in the tree.
|
||||
menu_tree_check_access($tree[$cid]);
|
||||
}
|
||||
return $tree[$cid];
|
||||
}
|
||||
|
|
@ -722,15 +747,34 @@ function menu_tree_page_data($menu_name = 'navigation') {
|
|||
return array();
|
||||
}
|
||||
|
||||
function _menu_tree_check_access(&$tree) {
|
||||
/**
|
||||
* Check access and perform other dynamic operations for each link in the tree.
|
||||
*/
|
||||
function menu_tree_check_access(&$tree, $show_hidden = FALSE) {
|
||||
// TODO: special case node links and access check via db_rewite_sql().
|
||||
// TODO: move sorting of siblings in the tree here so that we can sort based on
|
||||
// the localized title of each link. Currently the dorting is done in
|
||||
// function _menu_tree_data().
|
||||
_menu_tree_check_access($tree, $show_hidden);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper function for menu_tree_check_access()
|
||||
*/
|
||||
function _menu_tree_check_access(&$tree, $show_hidden) {
|
||||
foreach ($tree as $key => $v) {
|
||||
$item = &$tree[$key]['link'];
|
||||
if (!$item['hidden'] || $show_hidden) {
|
||||
_menu_link_translate($item);
|
||||
}
|
||||
else {
|
||||
$item['access'] = FALSE;
|
||||
}
|
||||
if (!$item['access']) {
|
||||
unset($tree[$key]);
|
||||
}
|
||||
elseif ($tree[$key]['below']) {
|
||||
_menu_tree_check_access($tree[$key]['below']);
|
||||
_menu_tree_check_access($tree[$key]['below'], $show_hidden);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -738,10 +782,6 @@ function _menu_tree_check_access(&$tree) {
|
|||
/**
|
||||
* Build the data representing a menu tree.
|
||||
*
|
||||
* The function is a bit complex because the rendering of an item depends on
|
||||
* the next menu item. So we are always rendering the element previously
|
||||
* processed not the current one.
|
||||
*
|
||||
* @param $result
|
||||
* The database result.
|
||||
* @param $parents
|
||||
|
|
@ -749,12 +789,23 @@ function _menu_tree_check_access(&$tree) {
|
|||
* to the root of the menu tree.
|
||||
* @param $depth
|
||||
* The depth of the current menu tree.
|
||||
* @param $previous_element
|
||||
* The previous menu link in the current menu tree.
|
||||
* @return
|
||||
* See menu_tree_data for a description of the data structure.
|
||||
* See menu_tree_page_data for a description of the data structure.
|
||||
*/
|
||||
function _menu_tree_data($result = NULL, $parents = array(), $depth = 1, $previous_element = '') {
|
||||
function menu_tree_data($result = NULL, $parents = array(), $depth = 1) {
|
||||
|
||||
list(, $tree) = _menu_tree_data($result, $parents, $depth);
|
||||
return $tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper function to build the data representing a menu tree.
|
||||
*
|
||||
* The function is a bit complex because the rendering of an item depends on
|
||||
* the next menu item. So we are always rendering the element previously
|
||||
* processed not the current one.
|
||||
*/
|
||||
function _menu_tree_data($result, $parents, $depth, $previous_element = '') {
|
||||
$remnant = NULL;
|
||||
$tree = array();
|
||||
while ($item = db_fetch_array($result)) {
|
||||
|
|
@ -763,7 +814,7 @@ function _menu_tree_data($result = NULL, $parents = array(), $depth = 1, $previo
|
|||
$item['in_active_trail'] = in_array($item['mlid'], $parents);
|
||||
// The weights are uniform 5 digits because of the 50000 offset in the
|
||||
// query. We add mlid at the end of the index to insure uniqueness.
|
||||
$index = $previous_element ? ($previous_element['weight'] .' '. $previous_element['title'] . $previous_element['mlid']) : '';
|
||||
$index = $previous_element ? ($previous_element['weight'] .' '. drupal_strtolower($previous_element['link_title']) . $previous_element['mlid']) : '';
|
||||
// The current item is the first in a new submenu.
|
||||
if ($item['depth'] > $depth) {
|
||||
// _menu_tree returns an item and the menu tree structure.
|
||||
|
|
@ -798,8 +849,8 @@ function _menu_tree_data($result = NULL, $parents = array(), $depth = 1, $previo
|
|||
}
|
||||
}
|
||||
if ($previous_element) {
|
||||
// We have one more link dangling.
|
||||
$tree[$previous_element['weight'] .' '. $previous_element['title'] .' '. $previous_element['mlid']] = array(
|
||||
// We have one more link dangling
|
||||
$tree[$previous_element['weight'] .' '. drupal_strtolower($previous_element['link_title']) .' '. $previous_element['mlid']] = array(
|
||||
'link' => $previous_element,
|
||||
'below' => '',
|
||||
);
|
||||
|
|
@ -833,6 +884,9 @@ function theme_menu_item($link, $has_children, $menu = '', $in_active_trail = FA
|
|||
return '<li class="'. $class .'">'. $link . $menu .'</li>'."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the HTML output for a single local task link.
|
||||
*/
|
||||
function theme_menu_local_task($link, $active = FALSE) {
|
||||
return '<li '. ($active ? 'class="active" ' : '') .'>'. $link .'</li>';
|
||||
}
|
||||
|
|
@ -886,6 +940,9 @@ function menu_get_names($reset = FALSE) {
|
|||
return $names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of links to be rendered as the Primary links.
|
||||
*/
|
||||
function menu_primary_links() {
|
||||
$tree = menu_tree_page_data('primary-links');
|
||||
$links = array();
|
||||
|
|
@ -898,6 +955,9 @@ function menu_primary_links() {
|
|||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of links to be rendered as the Secondary links.
|
||||
*/
|
||||
function menu_secondary_links() {
|
||||
$tree = menu_tree_page_data('secondary-links');
|
||||
$links = array();
|
||||
|
|
@ -941,7 +1001,7 @@ function menu_local_tasks($level = 0, $return_root = FALSE) {
|
|||
while ($item = db_fetch_array($result)) {
|
||||
_menu_translate($item, $map, TRUE);
|
||||
if ($item['tab_parent']) {
|
||||
// All tabs, but not the root page.
|
||||
// All tabs, but not the root page
|
||||
$children[$item['tab_parent']][$item['path']] = $item;
|
||||
}
|
||||
// Store the translated item for later use.
|
||||
|
|
@ -976,7 +1036,7 @@ function menu_local_tasks($level = 0, $return_root = FALSE) {
|
|||
$tabs[$item['number_parts']]['output'] = $tabs_current;
|
||||
}
|
||||
|
||||
// Find all tabs at the same level or above the current one
|
||||
// Find all tabs at the same level or above the current one.
|
||||
$parent = $router_item['tab_parent'];
|
||||
$path = $router_item['path'];
|
||||
$current = $router_item;
|
||||
|
|
@ -1032,10 +1092,16 @@ function menu_local_tasks($level = 0, $return_root = FALSE) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendered local tasks at the top level.
|
||||
*/
|
||||
function menu_primary_local_tasks() {
|
||||
return menu_local_tasks(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the rendered local tasks at the second level.
|
||||
*/
|
||||
function menu_secondary_local_tasks() {
|
||||
return menu_local_tasks(1);
|
||||
}
|
||||
|
|
@ -1065,6 +1131,9 @@ function theme_menu_local_tasks() {
|
|||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set (or get) the active menu for the current page - determines the active trail.
|
||||
*/
|
||||
function menu_set_active_menu_name($menu_name = NULL) {
|
||||
static $active;
|
||||
|
||||
|
|
@ -1077,6 +1146,9 @@ function menu_set_active_menu_name($menu_name = NULL) {
|
|||
return $active;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active menu for the current page - determines the active trail.
|
||||
*/
|
||||
function menu_get_active_menu_name() {
|
||||
return menu_set_active_menu_name();
|
||||
}
|
||||
|
|
@ -1084,6 +1156,9 @@ function menu_get_active_menu_name() {
|
|||
function menu_set_active_item() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set (or get) the active trail for the current page - the path to root in the menu tree..
|
||||
*/
|
||||
function menu_set_active_trail($new_trail = NULL) {
|
||||
static $trail;
|
||||
|
||||
|
|
@ -1121,6 +1196,9 @@ function menu_set_active_trail($new_trail = NULL) {
|
|||
return $trail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the active trail for the current page - the path to root in the menu tree..
|
||||
*/
|
||||
function menu_get_active_trail() {
|
||||
return menu_set_active_trail();
|
||||
}
|
||||
|
|
@ -1128,6 +1206,9 @@ function menu_get_active_trail() {
|
|||
function menu_set_location() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the breadcrumb for the current page, as determined by the active trail.
|
||||
*/
|
||||
function menu_get_active_breadcrumb() {
|
||||
$breadcrumb = array();
|
||||
$item = menu_get_item();
|
||||
|
|
@ -1147,6 +1228,9 @@ function menu_get_active_breadcrumb() {
|
|||
return $breadcrumb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the title of the current page, as determined by the active trail.
|
||||
*/
|
||||
function menu_get_active_title() {
|
||||
$active_trail = menu_get_active_trail();
|
||||
|
||||
|
|
@ -1168,20 +1252,23 @@ function menu_get_active_title() {
|
|||
* rendering.
|
||||
*/
|
||||
function menu_link_load($mlid) {
|
||||
if ($item = db_fetch_array(db_query("SELECT * FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.mlid = %d", $mlid))) {
|
||||
if (is_numeric($mlid) && $item = db_fetch_array(db_query("SELECT m.*, ml.* FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.mlid = %d", $mlid))) {
|
||||
_menu_link_translate($item);
|
||||
return $item;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the cached cached data for a single named menu.
|
||||
*/
|
||||
function menu_cache_clear($menu_name = 'navigation') {
|
||||
cache_clear_all('links:'. $menu_name .':', 'cache_menu', TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* This should be called any time broad changes might have been made to the
|
||||
* router items or menu links.
|
||||
* Clears all cached menu data. This should be called any time broad changes
|
||||
* might have been made to the router items or menu links.
|
||||
*/
|
||||
function menu_cache_clear_all() {
|
||||
cache_clear_all('*', 'cache_menu', TRUE);
|
||||
|
|
@ -1253,13 +1340,15 @@ function _menu_link_build($item) {
|
|||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to build menu links for the items in the menu router.
|
||||
*/
|
||||
function _menu_navigation_links_rebuild($menu) {
|
||||
// Add normal and suggested items as links.
|
||||
$menu_links = array();
|
||||
foreach ($menu as $path => $item) {
|
||||
if ($item['_visible']) {
|
||||
$item = _menu_link_build($item);
|
||||
// We add nonexisting items.
|
||||
if ($item['_visible'] && !db_result(db_query("SELECT COUNT(*) FROM {menu_links} WHERE menu_name = '%s' AND link_path = '%s'", $item['menu_name'], $item['link_path']))) {
|
||||
$menu_links[$path] = $item;
|
||||
$sort[$path] = $item['_number_parts'];
|
||||
}
|
||||
|
|
@ -1269,9 +1358,15 @@ function _menu_navigation_links_rebuild($menu) {
|
|||
array_multisort($sort, SORT_NUMERIC, $menu_links);
|
||||
|
||||
foreach ($menu_links as $item) {
|
||||
$existing_item = db_fetch_array(db_query("SELECT mlid, customized FROM {menu_links} WHERE menu_name = '%s' AND link_path = '%s' AND module = 'system'", $item['menu_name'], $item['link_path']));
|
||||
if ($existing_item) {
|
||||
$item['mlid'] = $existing_item['mlid'];
|
||||
}
|
||||
if (!$existing_item || !$existing_item['customized']) {
|
||||
menu_link_save($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
$placeholders = implode(', ', array_fill(0, count($menu), "'%s'"));
|
||||
// Remove items if their router path does not exist any more.
|
||||
db_query('DELETE FROM {menu_links} WHERE router_path NOT IN ('. $placeholders .')', array_keys($menu));
|
||||
|
|
@ -1297,6 +1392,9 @@ function menu_link_delete($mlid, $path = NULL) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for menu_link_delete; deletes a single menu link.
|
||||
*/
|
||||
function _menu_delete_item($item) {
|
||||
// System-created items get automatically deleted, but only on menu rebuild.
|
||||
if ($item && $item['module'] != 'system') {
|
||||
|
|
@ -1331,8 +1429,7 @@ function _menu_delete_item($item) {
|
|||
* weight default is 0
|
||||
* expanded whether the item is expanded.
|
||||
* options An array of options, @see l for more.
|
||||
* mlid If it's an existing item, this comes from the database.
|
||||
* Never set by hand.
|
||||
* mlid Set to an existing value, or 0 or NULL to insert a new link.
|
||||
* plid The mlid of the parent.
|
||||
* router_path The path of the relevant router item.
|
||||
*/
|
||||
|
|
@ -1341,8 +1438,10 @@ function menu_link_save(&$item) {
|
|||
|
||||
drupal_alter('menu_link', $item, $menu);
|
||||
|
||||
$item['_external'] = menu_path_is_external($item['link_path']);
|
||||
// Load defaults.
|
||||
// This is the easiest way to handle the unique internal path '<front>',
|
||||
// since a path marked as external does not need to match a router path.
|
||||
$item['_external'] = menu_path_is_external($item['link_path']) || $item['link_path'] == '<front>';
|
||||
// Load defaults
|
||||
$item += array(
|
||||
'menu_name' => 'navigation',
|
||||
'weight' => 0,
|
||||
|
|
@ -1352,19 +1451,13 @@ function menu_link_save(&$item) {
|
|||
'expanded' => 0,
|
||||
'options' => array(),
|
||||
'module' => 'menu',
|
||||
'customized' => 0,
|
||||
);
|
||||
$menu_name = $item['menu_name'];
|
||||
$existing_item = FALSE;
|
||||
if (isset($item['mlid'])) {
|
||||
$existing_item = db_fetch_array(db_query("SELECT * FROM {menu_links} WHERE mlid = %d", $item['mlid']));
|
||||
}
|
||||
else {
|
||||
$existing_item = db_fetch_array(db_query("SELECT * FROM {menu_links} WHERE menu_name = '%s' AND link_path = '%s'", $menu_name, $item['link_path']));
|
||||
}
|
||||
|
||||
if ($existing_item) {
|
||||
$item['mlid'] = $existing_item['mlid'];
|
||||
}
|
||||
|
||||
// Find the parent - it must be in the same menu.
|
||||
if (isset($item['plid'])) {
|
||||
|
|
@ -1378,7 +1471,7 @@ function menu_link_save(&$item) {
|
|||
} while ($parent === FALSE && $parent_path);
|
||||
}
|
||||
// Menu callbacks need to be in the links table for breadcrumbs, but can't
|
||||
// be parents if they are generated directly from a router item
|
||||
// be parents if they are generated directly from a router item.
|
||||
if (empty($parent['mlid']) || $parent['hidden'] < 0) {
|
||||
$item['plid'] = 0;
|
||||
}
|
||||
|
|
@ -1391,15 +1484,15 @@ function menu_link_save(&$item) {
|
|||
menu_name, plid, link_path,
|
||||
hidden, external, has_children,
|
||||
expanded, weight,
|
||||
module, link_title, options) VALUES (
|
||||
module, link_title, options, customized) VALUES (
|
||||
'%s', %d, '%s',
|
||||
%d, %d, %d,
|
||||
%d, %d,
|
||||
'%s', '%s', '%s')",
|
||||
'%s', '%s', '%s', %d)",
|
||||
$item['menu_name'], $item['plid'], $item['link_path'],
|
||||
$item['hidden'], $item['_external'], $item['has_children'],
|
||||
$item['expanded'], $item['weight'],
|
||||
$item['module'], $item['link_title'], serialize($item['options']));
|
||||
$item['module'], $item['link_title'], serialize($item['options']), $item['customized']);
|
||||
$item['mlid'] = db_last_insert_id('menu_links', 'mlid');
|
||||
}
|
||||
|
||||
|
|
@ -1409,7 +1502,7 @@ function menu_link_save(&$item) {
|
|||
$item['depth'] = 1;
|
||||
}
|
||||
else {
|
||||
// Cannot add beyond the maximum depth.
|
||||
// Cannot add beyond the maximum depth
|
||||
if ($item['has_children'] && $existing_item) {
|
||||
$limit = MENU_MAX_DEPTH - menu_link_children_relative_depth($existing_item) - 1;
|
||||
}
|
||||
|
|
@ -1450,12 +1543,12 @@ function menu_link_save(&$item) {
|
|||
router_path = '%s', hidden = %d, external = %d, has_children = %d,
|
||||
expanded = %d, weight = %d, depth = %d,
|
||||
p1 = %d, p2 = %d, p3 = %d, p4 = %d, p5 = %d, p6 = %d,
|
||||
module = '%s', link_title = '%s', options = '%s' WHERE mlid = %d",
|
||||
module = '%s', link_title = '%s', options = '%s', customized = %d WHERE mlid = %d",
|
||||
$item['menu_name'], $item['plid'], $item['link_path'],
|
||||
$item['router_path'], $item['hidden'], $item['_external'], $item['has_children'],
|
||||
$item['expanded'], $item['weight'], $item['depth'],
|
||||
$item['p1'], $item['p2'], $item['p3'], $item['p4'], $item['p5'], $item['p6'],
|
||||
$item['module'], $item['link_title'], serialize($item['options']), $item['mlid']);
|
||||
$item['module'], $item['link_title'], serialize($item['options']), $item['customized'], $item['mlid']);
|
||||
// Check the has_children status of the parent.
|
||||
if ($item['plid']) {
|
||||
$parent_has_children = (bool)db_result(db_query("SELECT COUNT(*) FROM {menu_links} WHERE plid = %d AND hidden = 0", $item['plid']));
|
||||
|
|
@ -1552,6 +1645,9 @@ function _menu_link_move_children($item, $existing_item) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function that sets the p1..p6 values for a menu link being saved.
|
||||
*/
|
||||
function _menu_link_parents_set(&$item, $parent) {
|
||||
$i = 1;
|
||||
while ($i < $item['depth']) {
|
||||
|
|
@ -1567,6 +1663,9 @@ function _menu_link_parents_set(&$item, $parent) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to build the router table based on the data from hook_menu.
|
||||
*/
|
||||
function _menu_router_build($callbacks) {
|
||||
// First pass: separate callbacks from paths, making paths ready for
|
||||
// matching. Calculate fitness, and fill some default values.
|
||||
|
|
@ -1582,7 +1681,7 @@ function _menu_router_build($callbacks) {
|
|||
// We store the highest index of parts here to save some work in the fit
|
||||
// calculation loop.
|
||||
$slashes = $number_parts - 1;
|
||||
// extract functions
|
||||
// Extract load and to_arg functions.
|
||||
foreach ($parts as $k => $part) {
|
||||
$match = FALSE;
|
||||
if (preg_match('/^%([a-z_]*)$/', $part, $matches)) {
|
||||
|
|
@ -1646,7 +1745,7 @@ function _menu_router_build($callbacks) {
|
|||
foreach ($menu as $path => $v) {
|
||||
$item = &$menu[$path];
|
||||
if (!isset($item['access callback']) && isset($item['access arguments'])) {
|
||||
$item['access callback'] = 'user_access'; // Default callback
|
||||
$item['access callback'] = 'user_access'; // Default callback.
|
||||
}
|
||||
if (!$item['_tab']) {
|
||||
// Non-tab items
|
||||
|
|
@ -1740,6 +1839,9 @@ function _menu_router_build($callbacks) {
|
|||
return $menu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns TRUE if a path is external (e.g. http://example.com).
|
||||
*/
|
||||
function menu_path_is_external($path) {
|
||||
$colonpos = strpos($path, ':');
|
||||
return $colonpos !== FALSE && !preg_match('![/?#]!', substr($path, 0, $colonpos)) && filter_xss_bad_protocol($path, FALSE) == check_plain($path);
|
||||
|
|
@ -1749,11 +1851,11 @@ function menu_path_is_external($path) {
|
|||
* Returns TRUE if the site is off-line for maintenance.
|
||||
*/
|
||||
function _menu_site_is_offline() {
|
||||
// Check if site is set to off-line mode
|
||||
// Check if site is set to off-line mode.
|
||||
if (variable_get('site_offline', 0)) {
|
||||
// Check if the user has administration privileges
|
||||
// Check if the user has administration privileges.
|
||||
if (!user_access('administer site configuration')) {
|
||||
// Check if this is an attempt to login
|
||||
// Check if this is an attempt to login.
|
||||
if (drupal_get_normal_path($_GET['q']) != 'user') {
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Menu administration tabs:
|
|||
return $output;
|
||||
case 'admin/build/menu':
|
||||
return '<p>'. t('Menus are a collection of links (menu items) used to navigate a website. The list(s) below display the currently available menus along with their menu items. Select an operation from the list to manage each menu or menu item.', array('@admin-settings-menus' => url('admin/build/menu/settings'), '@admin-block' => url('admin/build/block'))) .'</p>';
|
||||
case 'admin/build/menu/menu/add':
|
||||
case 'admin/build/menu/add':
|
||||
return '<p>'. t('Enter the name for your new menu. Remember to enable the newly created block in the <a href="@blocks">blocks administration page</a>.', array('@blocks' => url('admin/build/block'))) .'</p>';
|
||||
case 'admin/build/menu/item/add':
|
||||
return '<p>'. t('Enter the title, path, position and the weight for your new menu item.') .'</p>';
|
||||
|
|
@ -45,150 +45,169 @@ function menu_menu() {
|
|||
$items['admin/build/menu'] = array(
|
||||
'title' => 'Menus',
|
||||
'description' => "Control your site's navigation menu, primary links and secondary links. as well as rename and reorganize menu items.",
|
||||
'page callback' => 'system_admin_menu_block_page',
|
||||
'file' => 'system.admin.inc',
|
||||
'file path' => drupal_get_path('module', 'system'),
|
||||
'page callback' => 'menu_overview_page',
|
||||
'access callback' => 'user_access',
|
||||
'access arguments' => array('administer menu'),
|
||||
);
|
||||
$result = db_query('SELECT * FROM {menu_custom} ORDER BY title');
|
||||
while ($menu = db_fetch_object($result)) {
|
||||
$items['admin/build/menu/'. $menu->menu_name] = array(
|
||||
'title' => $menu->title,
|
||||
'page callback' => 'menu_overview',
|
||||
'page arguments' => array($menu->menu_name),
|
||||
'description' => $menu->description,
|
||||
);
|
||||
$items['admin/build/menu/'. $menu->menu_name .'/list'] = array(
|
||||
'title' => 'List items',
|
||||
'weight' => -10,
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
);
|
||||
$items['admin/build/menu/'. $menu->menu_name .'/add'] = array(
|
||||
'title' => 'Add item',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_edit_item', 'add', $menu->menu_name),
|
||||
'type' => MENU_LOCAL_TASK);
|
||||
$items['admin/build/menu/'. $menu->menu_name .'/edit'] = array(
|
||||
'title' => 'Edit menu',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_edit_menu', 'edit', $menu->menu_name),
|
||||
'type' => MENU_LOCAL_TASK);
|
||||
}
|
||||
|
||||
$items['admin/build/menu/list'] = array(
|
||||
'title' => 'List menus',
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK,
|
||||
'weight' => -10,
|
||||
);
|
||||
$items['admin/build/menu/menu/add'] = array(
|
||||
'weight' => -10);
|
||||
$items['admin/build/menu/add'] = array(
|
||||
'title' => 'Add menu',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_edit_menu', 'add'),
|
||||
'type' => MENU_LOCAL_TASK);
|
||||
$items['admin/build/menu/item/disable'] = array(
|
||||
'title' => 'Disable menu item',
|
||||
'page callback' => 'menu_flip_item',
|
||||
'page arguments' => array(TRUE),
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
$items['admin/build/menu/item/enable'] = array(
|
||||
'title' => 'Enable menu item',
|
||||
'page callback' => 'menu_flip_item',
|
||||
'page arguments' => array(FALSE),
|
||||
'type' => MENU_CALLBACK,
|
||||
);
|
||||
$items['admin/build/menu/item/edit'] = array(
|
||||
'title' => 'Edit menu item',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_edit_item', 'edit', 5),
|
||||
'type' => MENU_CALLBACK);
|
||||
$items['admin/build/menu/item/reset'] = array(
|
||||
'title' => 'Reset menu item',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_reset_item'),
|
||||
'type' => MENU_CALLBACK);
|
||||
$items['admin/build/menu/item/delete'] = array(
|
||||
'title' => 'Delete menu item',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_item_delete_form'),
|
||||
'type' => MENU_CALLBACK);
|
||||
|
||||
$items['admin/build/menu/menu/edit'] = array(
|
||||
'title' => 'Edit menu',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_edit_menu', 'edit'),
|
||||
'type' => MENU_CALLBACK);
|
||||
$items['admin/build/menu/menu/delete'] = array(
|
||||
'title' => 'Delete menu',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_item_delete_form'),
|
||||
'type' => MENU_CALLBACK);
|
||||
|
||||
$items['admin/build/menu/settings'] = array(
|
||||
'title' => 'Settings',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_configure'),
|
||||
'type' => MENU_LOCAL_TASK,
|
||||
'weight' => 5,
|
||||
);
|
||||
'weight' => 5);
|
||||
|
||||
$items['admin/build/menu-customize/%menu'] = array(
|
||||
'title' => 'Customize menu',
|
||||
'page callback' => 'menu_overview',
|
||||
'page arguments' => array(3),
|
||||
'access arguments' => array('administer menu'),
|
||||
'type' => MENU_CALLBACK);
|
||||
$items['admin/build/menu-customize/%menu/list'] = array(
|
||||
'title' => 'List items',
|
||||
'weight' => -10,
|
||||
'type' => MENU_DEFAULT_LOCAL_TASK);
|
||||
$items['admin/build/menu-customize/%menu/add'] = array(
|
||||
'title' => 'Add item',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_edit_item', 'add', NULL, 3),
|
||||
'type' => MENU_LOCAL_TASK);
|
||||
$items['admin/build/menu-customize/%menu/edit'] = array(
|
||||
'title' => 'Edit menu',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_edit_menu', 'edit', 3),
|
||||
'type' => MENU_LOCAL_TASK);
|
||||
$items['admin/build/menu/item/%menu_link/disable'] = array(
|
||||
'title' => 'Disable menu item',
|
||||
'page callback' => 'menu_flip_item',
|
||||
'page arguments' => array(TRUE, 4),
|
||||
'type' => MENU_CALLBACK);
|
||||
$items['admin/build/menu/item/%menu_link/enable'] = array(
|
||||
'title' => 'Enable menu item',
|
||||
'page callback' => 'menu_flip_item',
|
||||
'page arguments' => array(FALSE, 4),
|
||||
'type' => MENU_CALLBACK);
|
||||
$items['admin/build/menu/item/%menu_link/edit'] = array(
|
||||
'title' => 'Edit menu item',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_edit_item', 'edit', 4, NULL),
|
||||
'type' => MENU_CALLBACK);
|
||||
$items['admin/build/menu/item/%menu_link/reset'] = array(
|
||||
'title' => 'Reset menu item',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_reset_item', 4),
|
||||
'type' => MENU_CALLBACK);
|
||||
$items['admin/build/menu/item/%menu_link/delete'] = array(
|
||||
'title' => 'Delete menu item',
|
||||
'page callback' => 'drupal_get_form',
|
||||
'page arguments' => array('menu_item_delete_form', 4),
|
||||
'type' => MENU_CALLBACK);
|
||||
|
||||
return $items;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of hook_enable()
|
||||
*
|
||||
* Add a link for each custom menu.
|
||||
*/
|
||||
function menu_enable() {
|
||||
menu_rebuild();
|
||||
$result = db_query("SELECT * FROM {menu_custom}");
|
||||
$link['module'] = 'menu';
|
||||
$link['plid'] = db_result(db_query("SELECT mlid from {menu_links} WHERE menu_name = 'navigation' AND link_path = 'admin/build/menu'"));
|
||||
$link['router_path'] = 'admin/build/menu-customize/%';
|
||||
|
||||
while ($menu = db_fetch_array($result)) {
|
||||
$link['mlid'] = 0;
|
||||
$link['link_title'] = $menu['title'];
|
||||
$link['link_path'] = 'admin/build/menu-customize/'. $menu['menu_name'];
|
||||
menu_link_save($link);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the data for a single custom menu.
|
||||
*/
|
||||
function menu_load($menu_name) {
|
||||
return db_fetch_array(db_query("SELECT * FROM {menu_custom} WHERE menu_name = '%s'", $menu_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback which shows an overview page of all the custom menus and their descriptions.
|
||||
*/
|
||||
function menu_overview_page() {
|
||||
$result = db_query("SELECT * FROM {menu_custom}");
|
||||
$content = array();
|
||||
while ($menu = db_fetch_array($result)) {
|
||||
$menu['href'] = 'admin/build/menu-customize/'. $menu['menu_name'];
|
||||
$menu['options'] = array();
|
||||
$content[] = $menu;
|
||||
}
|
||||
return theme('admin_block_content', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback which displays every menu element accessible to the current
|
||||
* user and the relevant operations.
|
||||
*/
|
||||
function menu_overview($menu_name) {
|
||||
function menu_overview($menu) {
|
||||
|
||||
$header = array(t('Menu item'), t('Expanded'), array('data' => t('Operations'), 'colspan' => '3'));
|
||||
$sql ="
|
||||
SELECT *, ml.weight + 50000 AS weight FROM {menu_links} ml
|
||||
LEFT JOIN {menu_router} m ON m.path = ml.router_path
|
||||
WHERE menu_name = '%s' AND hidden >= 0
|
||||
SELECT m.*, ml.menu_name, ml.mlid, ml.plid, ml.link_path, ml.router_path, ml.hidden, ml.external, ml.has_children, ml.expanded, ml.weight + 50000 AS weight, ml.depth, ml.customized, ml.module, ml.link_title, ml.options
|
||||
FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
|
||||
WHERE ml.menu_name = '%s' AND ml.hidden >= 0
|
||||
ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC";
|
||||
$sql_count = "SELECT COUNT(*) FROM {menu_links} ml WHERE menu_name = '%s' AND hidden >= 0";
|
||||
$result = pager_query($sql, 200, 0, $sql_count, $menu_name);
|
||||
list(, $tree) = _menu_tree_data($result);
|
||||
$result = pager_query($sql, 200, 0, $sql_count, $menu['menu_name']);
|
||||
$tree = menu_tree_data($result);
|
||||
menu_tree_check_access($tree, TRUE);
|
||||
$rows = _menu_overview_tree($tree);
|
||||
$output = theme('table', $header, $rows);
|
||||
$output .= theme('pager', NULL, 200, 0);
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive helper function for menu_overview().
|
||||
*/
|
||||
function _menu_overview_tree($tree) {
|
||||
static $rows = array();
|
||||
foreach ($tree as $data) {
|
||||
$title = '';
|
||||
if ($item = $data['link']) {
|
||||
_menu_link_translate($item);
|
||||
if (!$item['access']) {
|
||||
continue;
|
||||
}
|
||||
$title = str_repeat(' ', $item['depth'] - 1) . ($item['depth'] > 1 ? '- ' : '');
|
||||
$title .= l($item['link_title'], $item['href'], $item['options']);
|
||||
// Populate the operations field.
|
||||
$operations = array();
|
||||
// Set the edit column.
|
||||
$operations[] = array('data' => l(t('edit'), 'admin/build/menu/item/edit/'. $item['mlid']));
|
||||
$operations[] = array('data' => l(t('edit'), 'admin/build/menu/item/'. $item['mlid'] .'/edit'));
|
||||
if ($item['hidden']) {
|
||||
$title .= ' ('. t('disabled') .')';
|
||||
$class = 'menu-disabled';
|
||||
$operations[] = array('data' => l(t('enable'), 'admin/build/menu/item/enable/'. $item['mlid']));
|
||||
$operations[] = array('data' => l(t('enable'), 'admin/build/menu/item/'. $item['mlid'] .'/enable'));
|
||||
}
|
||||
else {
|
||||
$class = 'menu-enabled';
|
||||
$operations[] = array('data' => l(t('disable'), 'admin/build/menu/item/disable/'. $item['mlid']));
|
||||
$operations[] = array('data' => l(t('disable'), 'admin/build/menu/item/'. $item['mlid'] .'/disable'));
|
||||
}
|
||||
// Only items created by the menu module can be deleted.
|
||||
if ($item['module'] == 'menu') {
|
||||
$operations[] = array('data' => l(t('delete'), 'admin/build/menu/item/delete/'. $item['mlid']));
|
||||
$operations[] = array('data' => l(t('delete'), 'admin/build/menu/item/'. $item['mlid'] .'/delete'));
|
||||
}
|
||||
// Set the reset column.
|
||||
else if ($item['module'] == 'system') {
|
||||
$operations[] = array('data' => l(t('reset'), 'admin/build/menu/item/reset/'. $item['mlid']));
|
||||
elseif ($item['module'] == 'system' && $item['customized']) {
|
||||
$operations[] = array('data' => l(t('reset'), 'admin/build/menu/item/'. $item['mlid'] .'/reset'));
|
||||
}
|
||||
else {
|
||||
$operations[] = array('data' => '');
|
||||
|
|
@ -211,55 +230,39 @@ function _menu_overview_tree($tree) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Menu callback; enable/disable a menu item.
|
||||
* Menu callback; enable/disable a menu link.
|
||||
*
|
||||
* @param $hide
|
||||
* TRUE to not show in the menu tree. FALSE to make the item and its children
|
||||
* reappear in menu tree.
|
||||
* @param $mlid
|
||||
* mlid of the menu item.
|
||||
* @param $item
|
||||
* The menu item.
|
||||
*/
|
||||
function menu_flip_item($hide, $mlid) {
|
||||
if (!($item = menu_link_load($mlid))) {
|
||||
drupal_not_found();
|
||||
return;
|
||||
}
|
||||
function menu_flip_item($hide, $item) {
|
||||
|
||||
$item['hidden'] = (bool)$hide;
|
||||
$item['customized'] = 1;
|
||||
menu_link_save($item);
|
||||
drupal_set_message($hide ? t('The menu item has been disabled.') : t('The menu item has been enabled.'));
|
||||
drupal_goto('admin/build/menu/'. $item['menu_name']);
|
||||
drupal_goto('admin/build/menu-customize/'. $item['menu_name']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback; present the menu item editing form.
|
||||
* Menu callback; Build the menu link editing form.
|
||||
*/
|
||||
function menu_edit_item(&$form_state, $type, $id = 0) {
|
||||
if ($type == 'edit') {
|
||||
if (!($item = menu_link_load($id))) {
|
||||
drupal_not_found();
|
||||
return;
|
||||
function menu_edit_item(&$form_state, $type, $item, $menu) {
|
||||
|
||||
if ($type == 'add' || empty($item)) {
|
||||
// This is an add form, initialize the menu link.
|
||||
$item = array('link_title' => '', 'mlid' => 0, 'plid' => 0, 'menu_name' => $menu['menu_name'], 'weight' => 0, 'link_path' => '', 'options' => array(), 'module' => 'menu', 'expanded' => 0, 'hidden' => 0, 'has_children' => 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// This is an add form.
|
||||
// The mlid argument (if set) will be the default pid to use.
|
||||
$item = array('mlid' => 0, 'plid' => 0, 'menu_name' => $id, 'weight' => 0, 'link_title' => '', 'link_path' => '', 'options' => array(), 'module' => 'menu', 'expanded' => 0, 'hidden' => 0, 'has_children' => 0);
|
||||
}
|
||||
foreach (array('link_path', 'mlid', 'module', 'hidden', 'menu_name', 'has_children') as $key) {
|
||||
foreach (array('link_path', 'mlid', 'module', 'hidden', 'menu_name', 'has_children', 'options') as $key) {
|
||||
$form[$key] = array('#type' => 'value', '#value' => $item[$key]);
|
||||
}
|
||||
// Any item created or edited via this interface is considered "customized".
|
||||
$form['customized'] = array('#type' => 'value', '#value' => 1);
|
||||
$form['original_item'] = array('#type' => 'value', '#value' => $item);
|
||||
|
||||
$form['link_title'] = array('#type' => 'textfield',
|
||||
'#title' => t('Title'),
|
||||
'#default_value' => $item['link_title'],
|
||||
'#description' => t('The name of the menu item.'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
$form['description'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Description'),
|
||||
'#default_value' => isset($item['options']['attributes']['title']) ? $item['options']['attributes']['title'] : '',
|
||||
);
|
||||
if ($item['module'] == 'menu') {
|
||||
$form['link_path'] = array(
|
||||
'#type' => 'textfield',
|
||||
|
|
@ -276,8 +279,19 @@ function menu_edit_item(&$form_state, $type, $id = 0) {
|
|||
'#description' => l($item['link_title'], $item['href'], $item['options']),
|
||||
);
|
||||
}
|
||||
$form['original_item'] = array('#type' => 'value', '#value' => $item);
|
||||
|
||||
$form['link_title'] = array('#type' => 'textfield',
|
||||
'#title' => t('Menu link title'),
|
||||
'#default_value' => $item['link_title'],
|
||||
'#description' => t('The link text corresponding to this item that should appear in the menu.'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
$form['description'] = array(
|
||||
'#type' => 'textarea',
|
||||
'#title' => t('Description'),
|
||||
'#default_value' => isset($item['options']['attributes']['title']) ? $item['options']['attributes']['title'] : '',
|
||||
'#rows' => 1,
|
||||
'#description' => t('The description displayed when hovering over a menu item.'),
|
||||
);
|
||||
$form['expanded'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Expanded'),
|
||||
|
|
@ -286,7 +300,7 @@ function menu_edit_item(&$form_state, $type, $id = 0) {
|
|||
);
|
||||
|
||||
// Generate a list of possible parents (not including this item or descendants).
|
||||
$options = menu_parent_options($item['mlid'], $item['menu_name']);
|
||||
$options = menu_parent_options($item['menu_name'], $item);
|
||||
$form['plid'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Parent item'),
|
||||
|
|
@ -296,7 +310,7 @@ function menu_edit_item(&$form_state, $type, $id = 0) {
|
|||
$form['weight'] = array(
|
||||
'#type' => 'weight',
|
||||
'#title' => t('Weight'),
|
||||
'#default_value' => isset($item['weight']) ? $item['weight'] : 0,
|
||||
'#default_value' => $item['weight'],
|
||||
'#description' => t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'),
|
||||
);
|
||||
$form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
|
||||
|
|
@ -304,14 +318,13 @@ function menu_edit_item(&$form_state, $type, $id = 0) {
|
|||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate form values for a menu link being added or edited.
|
||||
*/
|
||||
function menu_edit_item_validate($form, &$form_state) {
|
||||
$item = $form_state['values'];
|
||||
if (isset($item['link_path']) && !menu_path_is_external($item['link_path'])) {
|
||||
$path = $item['link_path'];
|
||||
$item = menu_get_item($path);
|
||||
if (!$item || !$item['access']) {
|
||||
form_set_error('path', t('This path is either invalid or you do not have access to it'));
|
||||
}
|
||||
if (!trim($item['link_path']) || !menu_valid_path($item)) {
|
||||
form_set_error('link_path', t("The path '@link_path' is either invalid or you do not have access to it.", array('@link_path' => $item['link_path'])));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -319,83 +332,56 @@ function menu_edit_item_validate($form, &$form_state) {
|
|||
* Process menu and menu item add/edit form submissions.
|
||||
*/
|
||||
function menu_edit_item_submit($form, &$form_state) {
|
||||
$form_state['values']['options']['attributes']['title'] = $form_state['values']['description'];
|
||||
menu_link_save($form_state['values']);
|
||||
$form_state['redirect'] = 'admin/build/menu/'. $form_state['values']['menu_name'];
|
||||
$form_state['redirect'] = 'admin/build/menu-customize/'. $form_state['values']['menu_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of menu items that are valid possible parents for the
|
||||
* given menu item. The list excludes the given item and its children.
|
||||
*
|
||||
* @param $mlid
|
||||
* The menu item id for which to generate a list of parents.
|
||||
* If $mlid == 0 then the complete tree is returned.
|
||||
* @param $menu_name
|
||||
* The name of the menu.
|
||||
* @param $plid
|
||||
* The menu link item id of the menu item at which to start the tree.
|
||||
* If $pid > 0 then this item will be included in the tree.
|
||||
* @param $depth
|
||||
* The current depth in the tree - used when recursing to indent the tree.
|
||||
* @param $item
|
||||
* The menu item for which to generate a list of parents.
|
||||
* If $item['mlid'] == 0 or NULL then the complete tree is returned.
|
||||
* @return
|
||||
* An array of menu titles keyed on the mlid.
|
||||
* An array of menu link titles keyed on the mlid.
|
||||
*/
|
||||
function menu_parent_options($mlid, $menu_name, $plid = 0, $depth = 0) {
|
||||
$options = array(0 => t('Root'));
|
||||
// Exclude $mlid and its children from the list unless $mlid is 0.
|
||||
if ($mlid && $mlid == $plid) {
|
||||
function menu_parent_options($menu_name, $item) {
|
||||
|
||||
$tree = menu_tree_all_data($item['menu_name'], NULL, TRUE);
|
||||
$options = array(0 => '<'. t('root') .'>');
|
||||
_menu_parents_recurse($tree, '--', $options, $item['mlid']);
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
|
||||
$sql = "SELECT * FROM {menu_links} ml LEFT JOIN {menu_router} mr ON ml.router_path = mr.path WHERE menu_name = '%s' AND hidden >= 0";
|
||||
$params = array($menu_name);
|
||||
if ($mlid && ($item = menu_link_load($mlid))) {
|
||||
$parents = array();
|
||||
for ($i = 1; $i <= 6; $i++) {
|
||||
$key = "p$i";
|
||||
$value = $item[$key];
|
||||
if ($value) {
|
||||
$parents[]= "$key != %d";
|
||||
$params[] = $value;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$sql .= ' AND (' . implode(' OR ', $parents) .')';
|
||||
}
|
||||
|
||||
$sql .= ' ORDER BY p1, p2, p3, p4, p5';
|
||||
$result = db_query($sql, $params);
|
||||
|
||||
while ($item = db_fetch_array($result)) {
|
||||
_menu_link_translate($item);
|
||||
if (!$item['access']) {
|
||||
continue;
|
||||
}
|
||||
$title = str_repeat('--', $item['depth']) .' '. $item['link_title'];
|
||||
if ($item['hidden']) {
|
||||
/**
|
||||
* Recursive helper function for menu_parent_options().
|
||||
*/
|
||||
function _menu_parents_recurse($tree, $indent, &$options, $exclude) {
|
||||
foreach ($tree as $data) {
|
||||
if ($data['link']['mlid'] != $exclude) {
|
||||
$title = $indent .' '. truncate_utf8($data['link']['title'], 30, TRUE, FALSE);
|
||||
if ($data['link']['hidden']) {
|
||||
$title .= ' ('. t('disabled') .')';
|
||||
}
|
||||
$options[$item['mlid']] = $title;
|
||||
$options[$data['link']['mlid']] = $title;
|
||||
if ($data['below'] && $data['link']['depth'] < MENU_MAX_DEPTH - 1) {
|
||||
_menu_parents_recurse($data['below'], $indent .'--', $options, $exclude);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the menu item.
|
||||
* Menu callback; Build the form that handles the adding/editing of a custom menu.
|
||||
*/
|
||||
function menu_node_form_delete($node) {
|
||||
menu_link_delete(NULL, 'node/'. $node->nid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback; handle the adding/editing of a new menu.
|
||||
*/
|
||||
function menu_edit_menu(&$form_state, $type, $menu_name = '') {
|
||||
function menu_edit_menu(&$form_state, $type, $menu = array()) {
|
||||
if ($type == 'edit') {
|
||||
$menu = db_fetch_array(db_query("SELECT * FROM {menu_custom} WHERE menu_name = '%s'", $menu_name));
|
||||
$form['menu_name'] = array('#type' => 'value', '#value' => $menu_name);
|
||||
$form['menu_name'] = array('#type' => 'value', '#value' => $menu['menu_name']);
|
||||
$form['#insert'] = FALSE;
|
||||
}
|
||||
else {
|
||||
|
|
@ -403,7 +389,7 @@ function menu_edit_menu(&$form_state, $type, $menu_name = '') {
|
|||
$form['menu_name'] = array(
|
||||
'#type' => 'textfield',
|
||||
'#title' => t('Menu name'),
|
||||
'#description' => t('The machine-readable name of this menu. This text will be used for constructing the URL of the <em>menu overwrite</em> page for this menu. This name may consist of only of lowercase letters, numbers and hyphens and must be unique.'),
|
||||
'#description' => t('The machine-readable name of this menu. This text will be used for constructing the URL of the <em>menu overview</em> page for this menu. This name may consist of only of lowercase letters, numbers and hypens and must be unique.'),
|
||||
'#required' => TRUE,
|
||||
);
|
||||
$form['#insert'] = TRUE;
|
||||
|
|
@ -428,10 +414,13 @@ function menu_edit_menu(&$form_state, $type, $menu_name = '') {
|
|||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the human and machine-readable names when adding or editing a menu.
|
||||
*/
|
||||
function menu_edit_menu_validate($form, &$form_state) {
|
||||
$item = $form_state['values'];
|
||||
if (preg_match('/[^a-z0-9-]/', $item['menu_name'])) {
|
||||
form_set_error('menu_name', t('Menu name may consist of only of lowercase letters, numbers and hyphens.'));
|
||||
form_set_error('menu_name', t('Menu name may consist only of lowercase letters, numbers and hypens.'));
|
||||
}
|
||||
if ($form['#insert'] &&
|
||||
(db_result(db_query("SELECT menu_name FROM {menu_custom} WHERE menu_name = '%s'", $item['menu_name'])) ||
|
||||
|
|
@ -440,31 +429,44 @@ function menu_edit_menu_validate($form, &$form_state) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Submit function for adding or editing a custom menu.
|
||||
*/
|
||||
function menu_edit_menu_submit($form, &$form_state) {
|
||||
$menu = $form_state['values'];
|
||||
$redirect = 'admin/build/menu/'. $menu['menu_name'];
|
||||
// Append 'menu' to the menu name to help avoid name-space conflicts.
|
||||
$menu['menu_name'] = 'menu-'. $menu['menu_name'];
|
||||
$redirect = 'admin/build/menu-customize/'. $menu['menu_name'];
|
||||
$link['link_title'] = $menu['title'];
|
||||
$link['router_path'] = 'admin/build/menu-customize/%';
|
||||
$link['module'] = 'menu';
|
||||
$link['link_path'] = $redirect;
|
||||
if ($form['#insert']) {
|
||||
$link['plid'] = db_result(db_query("SELECT mlid from {menu_links} WHERE menu_name = 'navigation' AND link_path = 'admin/build/menu'"));
|
||||
menu_link_save($link);
|
||||
db_query("INSERT INTO {menu_custom} (menu_name, title, description) VALUES ('%s', '%s', '%s')", $menu['menu_name'], $menu['title'], $menu['description']);
|
||||
}
|
||||
else {
|
||||
db_query("UPDATE {menu_custom} SET title = '%s', description = '%s' WHERE menu_name = '%s'", $menu['title'], $menu['description'], $menu['menu_name']);
|
||||
db_query("UPDATE {menu_links} SET link_title = '%s' WHERE link_title = '%s' AND router_path = '%s'", $menu['title'], $form['#title'], $redirect);
|
||||
$result = db_query("SELECT mlid FROM {menu_links} WHERE link_path = '%s'", $link['link_path']);
|
||||
while ($m = db_fetch_array($result)) {
|
||||
$link = menu_link_load($m['mlid']);
|
||||
$link['link_title'] = $menu['title'];
|
||||
menu_link_save($link);
|
||||
}
|
||||
}
|
||||
menu_rebuild();
|
||||
$form_state['redirect'] = $redirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback; delete a single custom item.
|
||||
* Menu callback; Build a confirm form for deletion of a single menu link.
|
||||
*/
|
||||
function menu_item_delete_form(&$form_state, $mlid) {
|
||||
if (!$item = menu_link_load($mlid)) {
|
||||
drupal_not_found();
|
||||
return;
|
||||
function menu_item_delete_form(&$form_state, $item) {
|
||||
if ($item['module'] == 'system') {
|
||||
drupal_access_denied();
|
||||
}
|
||||
$form['#item'] = $item;
|
||||
|
||||
return confirm_form($form, t('Are you sure you want to delete the custom menu item %item?', array('%item' => $item['link_title'])), 'admin/build/menu/'. $item['menu_name'], t('This action cannot be undone.'), t('Delete'));
|
||||
return confirm_form($form, t('Are you sure you want to delete the custom menu item %item?', array('%item' => $item['link_title'])), 'admin/build/menu-customize/'. $item['menu_name']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -476,40 +478,37 @@ function menu_item_delete_form_submit($form, &$form_state) {
|
|||
$t_args = array('%title' => $item['link_title']);
|
||||
drupal_set_message(t('The menu item %title has been deleted.', $t_args));
|
||||
watchdog('menu', 'Deleted menu item %title.', $t_args, WATCHDOG_NOTICE);
|
||||
$form_state['redirect'] = 'admin/build/menu/'. $item['menu_name'];
|
||||
$form_state['redirect'] = 'admin/build/menu-customize/'. $item['menu_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Menu callback; reset a single modified item.
|
||||
*/
|
||||
function menu_reset_item(&$form_state, $mlid) {
|
||||
if (isset($mlid) && $item = db_fetch_array(db_query('SELECT router_path, link_title FROM {menu_links} WHERE mlid = %d', $mlid))) {
|
||||
$form['#router_path'] = $item['router_path'];
|
||||
function menu_reset_item(&$form_state, $item) {
|
||||
$form['item'] = array('#type' => 'value', '#value' => $item);
|
||||
|
||||
$options = array(
|
||||
'description' => t('Any customizations will be lost. This action cannot be undone.'),
|
||||
'yes' => t('Reset')
|
||||
);
|
||||
|
||||
return confirm_form($form, t('Are you sure you want to reset the item %item to its default values?', array('%item' => $item['link_title'])), 'admin/build/menu', $options);
|
||||
}
|
||||
else {
|
||||
drupal_not_found();
|
||||
}
|
||||
return confirm_form($form, t('Are you sure you want to reset the item %item to its default values?', array('%item' => $item['link_title'])), 'admin/build/menu-customize/'. $item['menu_name'], $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process menu reset item form submissions.
|
||||
*/
|
||||
function menu_reset_item_submit($form, &$form_state) {
|
||||
$new_item = db_fetch_array(db_query("SELECT * FROM {menu_router} WHERE path = '%s'", $form['#router_path']));
|
||||
menu_link_save(_menu_link_build($new_item));
|
||||
$item = $form_state['values']['item'];
|
||||
$router = menu_router_build();
|
||||
$new_item = _menu_link_build($router[$item['router_path']]);
|
||||
foreach (array('mlid', 'has_children') as $key) {
|
||||
$new_item[$key] = $item[$key];
|
||||
}
|
||||
menu_link_save($new_item);
|
||||
drupal_set_message(t('The menu item was reset to its default settings.'));
|
||||
$form_state['redirect'] = 'admin/build/menu/navigation';
|
||||
$form_state['redirect'] = 'admin/build/menu-customize/'. $new_item['menu_name'];
|
||||
}
|
||||
|
||||
// Conversion ends here.
|
||||
|
||||
/**
|
||||
* Implementation of hook_block().
|
||||
*/
|
||||
|
|
@ -533,24 +532,47 @@ function menu_block($op = 'list', $delta = 0) {
|
|||
/**
|
||||
* Implementation of hook_nodeapi().
|
||||
*/
|
||||
function menu_nodeapi($node, $op) {
|
||||
if (user_access('administer menu') && isset($node->menu)) {
|
||||
$item = $node->menu;
|
||||
function menu_nodeapi(&$node, $op) {
|
||||
switch ($op) {
|
||||
case 'delete':
|
||||
$item['delete'] = 1;
|
||||
// Deliberate no break.
|
||||
case 'insert':
|
||||
case 'update':
|
||||
if ($item['delete']) {
|
||||
_menu_delete_item($item);
|
||||
if (isset($node->menu)) {
|
||||
$item = $node->menu;
|
||||
if (!empty($item['delete'])) {
|
||||
menu_link_delete($item['mlid']);
|
||||
}
|
||||
else {
|
||||
elseif (trim($item['link_title'])) {
|
||||
$item['link_title'] = trim($item['link_title']);
|
||||
$item['link_path'] = "node/$node->nid";
|
||||
if (!$item['customized']) {
|
||||
$item['options']['attributes']['title'] = trim($node->title);
|
||||
}
|
||||
menu_link_save($item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'delete':
|
||||
// Delete all menu module links that point to this node.
|
||||
$result = db_query("SELECT mlid FROM {menu_links} WHERE link_path = 'node/%d' AND module = 'menu'", $node->nid);
|
||||
while ($m = db_fetch_array($result)) {
|
||||
menu_link_delete($m['mlid']);
|
||||
}
|
||||
break;
|
||||
case 'prepare':
|
||||
if (empty($node->menu)) {
|
||||
// Prepare the node for the edit form so that $node->menu always exists.
|
||||
$menu_name = variable_get('menu_parent_items', 'navigation');
|
||||
$item = array();
|
||||
if (isset($node->nid)) {
|
||||
$mlid = db_result(db_query("SELECT mlid FROM {menu_links} WHERE link_path = 'node/%d' AND menu_name = '%s' AND module = 'menu' ORDER BY mlid ASC", $node->nid, $menu_name));
|
||||
if ($mlid) {
|
||||
$item = menu_link_load($mlid);
|
||||
}
|
||||
}
|
||||
// Set default values.
|
||||
$node->menu = $item + array('link_title' => '', 'mlid' => 0, 'plid' => 0, 'menu_name' => $menu_name, 'weight' => 0, 'options' => array(), 'module' => 'menu', 'expanded' => 0, 'hidden' => 0, 'has_children' => 0, 'customized' => 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -559,7 +581,10 @@ function menu_nodeapi($node, $op) {
|
|||
* Add menu item fields to the node form.
|
||||
*/
|
||||
function menu_form_alter(&$form, $form_state, $form_id) {
|
||||
if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
|
||||
if (isset($form['#node']) && $form['#node']->type .'_node_form' == $form_id) {
|
||||
// Note - doing this to make sure the delete checkbox stays in the form.
|
||||
$form['#cache'] = TRUE;
|
||||
|
||||
$form['menu'] = array(
|
||||
'#type' => 'fieldset',
|
||||
'#title' => t('Menu settings'),
|
||||
|
|
@ -567,27 +592,58 @@ function menu_form_alter(&$form, $form_state, $form_id) {
|
|||
'#collapsible' => TRUE,
|
||||
'#collapsed' => FALSE,
|
||||
'#tree' => TRUE,
|
||||
'#weight' => 30,
|
||||
'#weight' => -2,
|
||||
);
|
||||
$form_state = array();
|
||||
if ($mlid = db_result(db_query("SELECT mlid FROM {menu_links} WHERE link_path = 'node/%d' AND menu_name = '%s'", $form['nid']['#value'], variable_get('menu_parent_items', 'navigation')))) {
|
||||
$menu_form = drupal_retrieve_form('menu_edit_item', $form_state, 'edit', $mlid);
|
||||
$menu_form['delete'] = array(
|
||||
$item = $form['#node']->menu;
|
||||
|
||||
if ($item['mlid']) {
|
||||
// There is an existing link
|
||||
$form['menu']['delete'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Check to delete this menu item.'),
|
||||
'#title' => t('Check to remove this item from the menu.'),
|
||||
);
|
||||
}
|
||||
else {
|
||||
$menu_form = drupal_retrieve_form('menu_edit_item', $form_state, 'add', variable_get('menu_parent_items', 'navigation'));
|
||||
unset($menu_form['link_path']);
|
||||
$menu_form['link_title']['#required'] = FALSE;
|
||||
if (!$item['link_title']) {
|
||||
$form['menu']['#collapsed'] = TRUE;
|
||||
}
|
||||
unset($menu_form['submit']);
|
||||
$form['menu'] += $menu_form;
|
||||
|
||||
foreach (array('mlid', 'module', 'hidden', 'menu_name', 'has_children', 'customized', 'options', 'expanded', 'hidden') as $key) {
|
||||
$form['menu'][$key] = array('#type' => 'value', '#value' => $item[$key]);
|
||||
}
|
||||
|
||||
$form['menu']['link_title'] = array('#type' => 'textfield',
|
||||
'#title' => t('Menu link title'),
|
||||
'#default_value' => $item['link_title'],
|
||||
'#description' => t('The link text corresponding to this item that should appear in the menu. Leave blank if you do not wish to add this post to the menu.'),
|
||||
'#required' => FALSE,
|
||||
);
|
||||
// Generate a list of possible parents (not including this item or descendants).
|
||||
$options = menu_parent_options($item['menu_name'], $item);
|
||||
$form['menu']['plid'] = array(
|
||||
'#type' => 'select',
|
||||
'#title' => t('Parent item'),
|
||||
'#default_value' => $item['plid'],
|
||||
'#options' => $options,
|
||||
);
|
||||
$form['menu']['weight'] = array(
|
||||
'#type' => 'weight',
|
||||
'#title' => t('Weight'),
|
||||
'#default_value' => $item['weight'],
|
||||
'#description' => t('Optional. In the menu, the heavier items will sink and the lighter items will be positioned nearer the top.'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an associative array of the custom menus names.
|
||||
*
|
||||
* @param $all
|
||||
* If FALSE return only user-added menus, or if TRUE also include
|
||||
* the menus defined by the system.
|
||||
* @return
|
||||
* An array with the machine-readable names as the keys, and human-readable
|
||||
* titles as the values.
|
||||
*/
|
||||
function menu_get_menus($all = FALSE) {
|
||||
$sql = 'SELECT * FROM {menu_custom}'. ($all ? '' : " WHERE menu_name NOT IN ('navigation', 'primary-links', 'secondary-links')") . ' ORDER BY title';
|
||||
$result = db_query($sql);
|
||||
|
|
@ -600,7 +656,7 @@ function menu_get_menus($all = FALSE) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Menu callback; presents menu configuration options.
|
||||
* Menu callback; Build the form presenting menu configuration options.
|
||||
*/
|
||||
function menu_configure() {
|
||||
$form['intro'] = array(
|
||||
|
|
@ -619,3 +675,32 @@ function menu_configure() {
|
|||
|
||||
return system_settings_form($form);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the path of a menu link being created or edited.
|
||||
*
|
||||
* @return
|
||||
* TRUE if it is a valid path AND the current user has access permission,
|
||||
* FALSE otherwise.
|
||||
*/
|
||||
function menu_valid_path($form_item) {
|
||||
$item = array();
|
||||
$path = $form_item['link_path'];
|
||||
if ($path == '<front>' || menu_path_is_external($path)) {
|
||||
$item = array('access' => TRUE);
|
||||
}
|
||||
elseif (preg_match('/\/\%/', $path)) {
|
||||
// Path is dynamic (ie 'user/%'), so check directly against menu_router table.
|
||||
if ($item = db_fetch_array(db_query("SELECT * FROM {menu_router} where path = '%s' ", $path))) {
|
||||
$item['link_path'] = $form_item['link_path'];
|
||||
$item['link_title'] = $form_item['link_title'];
|
||||
$item['external'] = FALSE;
|
||||
$item['options'] = '';
|
||||
_menu_link_translate($item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
$item = menu_get_item($path);
|
||||
}
|
||||
return $item && $item['access'];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3339,6 +3339,7 @@ function system_update_6020() {
|
|||
'expanded' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
|
||||
'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
|
||||
'depth' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
|
||||
'customized' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
|
||||
'p1' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
|
||||
'p2' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
|
||||
'p3' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ function system_schema() {
|
|||
'expanded' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
|
||||
'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
|
||||
'depth' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
|
||||
'customized' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'small'),
|
||||
'p1' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
|
||||
'p2' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
|
||||
'p3' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
* An array of modules to be enabled.
|
||||
*/
|
||||
function default_profile_modules() {
|
||||
return array('color', 'comment', 'help', 'taxonomy', 'dblog');
|
||||
return array('color', 'comment', 'help', 'menu', 'taxonomy', 'dblog');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue