#130991: Custom menu items, part 1
parent
c504141f45
commit
f3cd2da113
|
@ -2292,22 +2292,3 @@ function element_child($key) {
|
||||||
function element_children($element) {
|
function element_children($element) {
|
||||||
return array_filter(array_keys((array) $element), 'element_child');
|
return array_filter(array_keys((array) $element), 'element_child');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate vancode.
|
|
||||||
*
|
|
||||||
* Consists of a leading character indicating length, followed by N digits
|
|
||||||
* with a numerical value in base 36. Vancodes can be sorted as strings
|
|
||||||
* without messing up numerical order.
|
|
||||||
*
|
|
||||||
* It goes:
|
|
||||||
* 00, 01, 02, ..., 0y, 0z,
|
|
||||||
* 110, 111, ... , 1zy, 1zz,
|
|
||||||
* 2100, 2101, ..., 2zzy, 2zzz,
|
|
||||||
* 31000, 31001, ...
|
|
||||||
*/
|
|
||||||
function int2vancode($i = 0) {
|
|
||||||
$num = base_convert((int)$i, 10, 36);
|
|
||||||
$length = strlen($num);
|
|
||||||
return chr($length + ord('0') - 1) . $num;
|
|
||||||
}
|
|
||||||
|
|
|
@ -312,4 +312,3 @@ function db_escape_table($string) {
|
||||||
* @} End of "defgroup database".
|
* @} End of "defgroup database".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,27 @@ define('MENU_HANDLE_REQUEST', 0);
|
||||||
define('MENU_RENDER_LINK', 1);
|
define('MENU_RENDER_LINK', 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @} End of "Menu helper directions
|
* @} End of "Menu operations."
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Name Menu alterations
|
||||||
|
* @{
|
||||||
|
* Menu alter phases
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alter the menu as defined in modules, keys are like user/%user.
|
||||||
|
*/
|
||||||
|
define('MENU_ALTER_MODULE_DEFINED', 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alter the menu after the first preprocessing phase, keys are like user/%.
|
||||||
|
*/
|
||||||
|
define('MENU_ALTER_PREPROCESSED', 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @} End of "Menu alterations".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -290,7 +310,9 @@ function menu_get_item($path = NULL, $item = NULL) {
|
||||||
if ($item = db_fetch_object(db_query_range('SELECT * FROM {menu} WHERE path IN ('. implode (',', $placeholders) .') ORDER BY fit DESC', $ancestors, 0, 1))) {
|
if ($item = db_fetch_object(db_query_range('SELECT * FROM {menu} WHERE path IN ('. implode (',', $placeholders) .') ORDER BY fit DESC', $ancestors, 0, 1))) {
|
||||||
// We need to access check the parents to match the navigation tree
|
// We need to access check the parents to match the navigation tree
|
||||||
// behaviour. The last parent is always the item itself.
|
// behaviour. The last parent is always the item itself.
|
||||||
$result = db_query('SELECT * FROM {menu} WHERE mid IN ('. $item->parents .') ORDER BY mleft');
|
$args = explode(',', $item->parents);
|
||||||
|
$placeholders = implode(', ', array_fill(0, count($args), '%d'));
|
||||||
|
$result = db_query('SELECT * FROM {menu} WHERE mid IN ('. $placeholders .') ORDER BY mleft', $args);
|
||||||
$item->access = TRUE;
|
$item->access = TRUE;
|
||||||
while ($item->access && ($parent = db_fetch_object($result))) {
|
while ($item->access && ($parent = db_fetch_object($result))) {
|
||||||
$map = _menu_translate($parent, $original_map);
|
$map = _menu_translate($parent, $original_map);
|
||||||
|
@ -379,7 +401,8 @@ function _menu_translate(&$item, $map, $operation = MENU_HANDLE_REQUEST) {
|
||||||
$return = $load_function(isset($path_map[$index]) ? $path_map[$index] : '');
|
$return = $load_function(isset($path_map[$index]) ? $path_map[$index] : '');
|
||||||
// If callback returned an error or there is no callback, trigger 404.
|
// If callback returned an error or there is no callback, trigger 404.
|
||||||
if ($return === FALSE) {
|
if ($return === FALSE) {
|
||||||
return array(FALSE, FALSE, '');
|
$item->access = FALSE;
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
$map[$index] = $return;
|
$map[$index] = $return;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +437,9 @@ function _menu_translate(&$item, $map, $operation = MENU_HANDLE_REQUEST) {
|
||||||
*/
|
*/
|
||||||
function menu_tree() {
|
function menu_tree() {
|
||||||
if ($item = menu_get_item()) {
|
if ($item = menu_get_item()) {
|
||||||
list(, $menu) = _menu_tree(db_query('SELECT * FROM {menu} WHERE pid IN ('. $item->parents .') AND visible = 1 ORDER BY mleft'));
|
$args = explode(',', $item->parents);
|
||||||
|
$placeholders = implode(', ', array_fill(0, count($args), '%d'));
|
||||||
|
list(, $menu) = _menu_tree(db_query('SELECT * FROM {menu} WHERE pid IN ('. $placeholders .') AND visible = 1 ORDER BY mleft', $args));
|
||||||
return $menu;
|
return $menu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -552,8 +577,11 @@ function menu_rebuild() {
|
||||||
// TODO: split menu and menu links storage.
|
// TODO: split menu and menu links storage.
|
||||||
db_query('DELETE FROM {menu}');
|
db_query('DELETE FROM {menu}');
|
||||||
$menu = module_invoke_all('menu');
|
$menu = module_invoke_all('menu');
|
||||||
drupal_alter('menu', $menu);
|
|
||||||
|
// Alter the menu as defined in modules, keys are like user/%user.
|
||||||
|
drupal_alter('menu', $menu, MENU_ALTER_MODULE_DEFINED);
|
||||||
$mid = 1;
|
$mid = 1;
|
||||||
|
|
||||||
// First pass: separate callbacks from pathes, making pathes ready for
|
// First pass: separate callbacks from pathes, making pathes ready for
|
||||||
// matching. Calculate fitness, and fill some default values.
|
// matching. Calculate fitness, and fill some default values.
|
||||||
foreach ($menu as $path => $item) {
|
foreach ($menu as $path => $item) {
|
||||||
|
@ -626,15 +654,21 @@ function menu_rebuild() {
|
||||||
$menu_path_map[$path] = $new_path;
|
$menu_path_map[$path] = $new_path;
|
||||||
$menu[$new_path] = $item;
|
$menu[$new_path] = $item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Alter the menu after the first preprocessing phase, keys are like user/%.
|
||||||
|
drupal_alter('menu', $menu, MENU_ALTER_PREPROCESSED);
|
||||||
|
|
||||||
$menu_path_map[''] = '';
|
$menu_path_map[''] = '';
|
||||||
// Second pass: prepare for sorting and find parents.
|
// Second pass: prepare for sorting and find parents.
|
||||||
foreach ($menu as $path => $item) {
|
foreach ($menu as $path => $item) {
|
||||||
$item = &$menu[$path];
|
$item = &$menu[$path];
|
||||||
$number_parts = $item['_number_parts'];
|
$number_parts = $item['_number_parts'];
|
||||||
if (isset($item['parent'])) {
|
if (isset($item['parent'])) {
|
||||||
|
if (isset($menu_path_map[$item['parent']])) {
|
||||||
$item['parent'] = $menu_path_map[$item['parent']];
|
$item['parent'] = $menu_path_map[$item['parent']];
|
||||||
|
}
|
||||||
$parent_parts = explode('/', $item['parent'], 6);
|
$parent_parts = explode('/', $item['parent'], 6);
|
||||||
$slashes = count($parent_parts) - 1;
|
$slashes = count($parent_parts);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$parent_parts = $item['_parts'];
|
$parent_parts = $item['_parts'];
|
||||||
|
@ -670,6 +704,7 @@ function menu_rebuild() {
|
||||||
unset($item);
|
unset($item);
|
||||||
}
|
}
|
||||||
array_multisort($sort, $menu);
|
array_multisort($sort, $menu);
|
||||||
|
|
||||||
// We are now sorted, so let's build the tree.
|
// We are now sorted, so let's build the tree.
|
||||||
$children = array();
|
$children = array();
|
||||||
foreach ($menu as $path => $item) {
|
foreach ($menu as $path => $item) {
|
||||||
|
@ -678,6 +713,7 @@ function menu_rebuild() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
menu_renumber($menu);
|
menu_renumber($menu);
|
||||||
|
|
||||||
// Apply inheritance rules.
|
// Apply inheritance rules.
|
||||||
foreach ($menu as $path => $item) {
|
foreach ($menu as $path => $item) {
|
||||||
$item = &$menu[$path];
|
$item = &$menu[$path];
|
||||||
|
@ -719,6 +755,9 @@ function menu_rebuild() {
|
||||||
if (is_bool($item['access callback'])) {
|
if (is_bool($item['access callback'])) {
|
||||||
$item['access callback'] = intval($item['access callback']);
|
$item['access callback'] = intval($item['access callback']);
|
||||||
}
|
}
|
||||||
|
if (empty($item['page callback'])) {
|
||||||
|
$item['access callback'] = 0;
|
||||||
|
}
|
||||||
if ($item['_tab']) {
|
if ($item['_tab']) {
|
||||||
if (!isset($item['parent'])) {
|
if (!isset($item['parent'])) {
|
||||||
$item['parent'] = implode('/', array_slice($item['_parts'], 0, $item['_number_parts'] - 1));
|
$item['parent'] = implode('/', array_slice($item['_parts'], 0, $item['_number_parts'] - 1));
|
||||||
|
@ -764,7 +803,11 @@ function menu_rebuild() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// We remove disabled items here -- this way they will be numbered in the
|
||||||
|
// tree so the menu overview screen can show them.
|
||||||
|
if (!empty($item['disabled'])) {
|
||||||
|
$item['_visible'] = FALSE;
|
||||||
|
}
|
||||||
db_query("INSERT INTO {menu} (
|
db_query("INSERT INTO {menu} (
|
||||||
mid, pid, path, load_functions, to_arg_functions,
|
mid, pid, path, load_functions, to_arg_functions,
|
||||||
access_callback, access_arguments, page_callback, page_arguments, fit,
|
access_callback, access_arguments, page_callback, page_arguments, fit,
|
||||||
|
@ -914,3 +957,23 @@ function menu_get_active_title() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a menu item by its mid, access checked and link translated for
|
||||||
|
* rendering.
|
||||||
|
*
|
||||||
|
* @param $mid
|
||||||
|
* The mid of the menu item.
|
||||||
|
* @return
|
||||||
|
* A menu object, with $item->access filled and link translated for
|
||||||
|
* rendering.
|
||||||
|
*/
|
||||||
|
function menu_get_item_by_mid($mid) {
|
||||||
|
if ($item = db_fetch_object(db_query('SELECT * FROM {menu} WHERE mid = %d', $mid))) {
|
||||||
|
_menu_translate($item, arg(), MENU_RENDER_LINK);
|
||||||
|
if ($item->access) {
|
||||||
|
return $item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
@ -1989,6 +1989,26 @@ function comment_invoke_comment(&$comment, $op) {
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate vancode.
|
||||||
|
*
|
||||||
|
* Consists of a leading character indicating length, followed by N digits
|
||||||
|
* with a numerical value in base 36. Vancodes can be sorted as strings
|
||||||
|
* without messing up numerical order.
|
||||||
|
*
|
||||||
|
* It goes:
|
||||||
|
* 00, 01, 02, ..., 0y, 0z,
|
||||||
|
* 110, 111, ... , 1zy, 1zz,
|
||||||
|
* 2100, 2101, ..., 2zzy, 2zzz,
|
||||||
|
* 31000, 31001, ...
|
||||||
|
*/
|
||||||
|
function int2vancode($i = 0) {
|
||||||
|
$num = base_convert((int)$i, 10, 36);
|
||||||
|
$length = strlen($num);
|
||||||
|
return chr($length + ord('0') - 1) . $num;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decode vancode back to an integer.
|
* Decode vancode back to an integer.
|
||||||
*/
|
*/
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -527,7 +527,7 @@ function node_load($param = array(), $revision = NULL, $reset = NULL) {
|
||||||
$node = db_fetch_object(db_query('SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond, $arguments));
|
$node = db_fetch_object(db_query('SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM {node} n INNER JOIN {users} u ON u.uid = n.uid INNER JOIN {node_revisions} r ON r.vid = n.vid WHERE '. $cond, $arguments));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($node->nid) {
|
if ($node && $node->nid) {
|
||||||
// Call the node specific callback (if any) and piggy-back the
|
// Call the node specific callback (if any) and piggy-back the
|
||||||
// results to the node or overwrite some values.
|
// results to the node or overwrite some values.
|
||||||
if ($extra = node_invoke($node, 'load')) {
|
if ($extra = node_invoke($node, 'load')) {
|
||||||
|
|
|
@ -378,7 +378,7 @@ function system_main_admin_page($arg = NULL) {
|
||||||
function system_admin_menu_block($item) {
|
function system_admin_menu_block($item) {
|
||||||
$map = arg(NULL);
|
$map = arg(NULL);
|
||||||
$content = array();
|
$content = array();
|
||||||
$result = db_query('SELECT * FROM {menu} WHERE depth = %d AND %d < mleft AND mright < %d ORDER BY mleft', $item->depth + 1, $item->mleft, $item->mright);
|
$result = db_query('SELECT * FROM {menu} WHERE depth = %d AND %d < mleft AND mright < %d AND visible = 1 ORDER BY mleft', $item->depth + 1, $item->mleft, $item->mright);
|
||||||
while ($item = db_fetch_object($result)) {
|
while ($item = db_fetch_object($result)) {
|
||||||
_menu_translate($item, $map, MENU_RENDER_LINK);
|
_menu_translate($item, $map, MENU_RENDER_LINK);
|
||||||
if (!$item->access) {
|
if (!$item->access) {
|
||||||
|
|
Loading…
Reference in New Issue