- Patch #113603 by chx: first crack at re-implementing tabs.

6.x
Dries Buytaert 2007-02-11 09:30:51 +00:00
parent 373a071fc4
commit a1e6728a46
18 changed files with 397 additions and 214 deletions

View File

@ -171,6 +171,19 @@ define('MENU_SITE_OFFLINE', 4);
* @} End of "Menu status codes". * @} End of "Menu status codes".
*/ */
/**
* @Name Menu operations
* @{
* Menu helper possible operations.
*/
define('MENU_HANDLE_REQUEST', 0);
define('MENU_RENDER_LINK', 1);
/**
* @} End of "Menu helper directions
*/
/** /**
* Returns the ancestors (and relevant placeholders) for any given path. * Returns the ancestors (and relevant placeholders) for any given path.
* *
@ -195,7 +208,7 @@ define('MENU_SITE_OFFLINE', 4);
* array('node', '12345', 'edit'). * array('node', '12345', 'edit').
* @return * @return
* An array which contains the ancestors and placeholders. Placeholders * An array which contains the ancestors and placeholders. Placeholders
* simply contain as many %s as the ancestors. * simply contain as many '%s' as the ancestors.
*/ */
function menu_get_ancestors($parts) { function menu_get_ancestors($parts) {
$n1 = count($parts); $n1 = count($parts);
@ -273,10 +286,10 @@ function menu_unserialize($data, $map) {
* with keys like title, access callback, access arguments etc. * with keys like title, access callback, access arguments etc.
*/ */
function menu_set_item($path, $item) { function menu_set_item($path, $item) {
menu_get_item($path, TRUE, $item); menu_get_item($path, $item);
} }
function menu_get_item($path = NULL, $execute = TRUE, $item = NULL) { function menu_get_item($path = NULL, $item = NULL) {
static $items; static $items;
if (!isset($path)) { if (!isset($path)) {
$path = $_GET['q']; $path = $_GET['q'];
@ -289,14 +302,13 @@ function menu_get_item($path = NULL, $execute = TRUE, $item = NULL) {
$parts = array_slice($map, 0, 6); $parts = array_slice($map, 0, 6);
list($ancestors, $placeholders) = menu_get_ancestors($parts); list($ancestors, $placeholders) = menu_get_ancestors($parts);
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))) {
$item->access = _menu_access($item, $map); list($item->access, $map) = _menu_translate($item, $map);
if ($map === FALSE) { if ($map === FALSE) {
$items[$path] = FALSE; $items[$path] = FALSE;
return FALSE; return FALSE;
} }
if ($execute) { $item->map = $map;
$item->page_arguments = array_merge(menu_unserialize($item->page_arguments, $map), array_slice($parts, $item->number_parts)); $item->page_arguments = array_merge(menu_unserialize($item->page_arguments, $map), array_slice($parts, $item->number_parts));
}
} }
$items[$path] = $item; $items[$path] = $item;
} }
@ -313,45 +325,113 @@ function menu_execute_active_handler() {
return MENU_NOT_FOUND; return MENU_NOT_FOUND;
} }
function _menu_access($item, &$map) { /**
if ($item->map_callback) { * Handles dynamic path translation and menu access control.
$map = call_user_func_array($item->map_callback, array_merge(array($map), unserialize($item->map_arguments))); *
if ($map === FALSE) { * When a user arrives on a page such as node/5, this function determines
return FALSE; * what "5" corresponds to, by inspecting the page's menu path definition,
* node/%node. This will call node_load(5) to load the corresponding node
* object.
*
* It also works in reverse, to allow the display of tabs and menu items which
* contain these dynamic arguments, translating node/%node to node/5.
* This operation is called MENU_RENDER_LINK.
*
* @param $item
* A menu item object
* @param $map
* An array of path arguments (ex: array('node', '5'))
* @param $operation
* The path translation operation to perform:
* - MENU_HANDLE_REQUEST: An incoming page reqest; map with appropriate callback.
* - MENU_RENDER_LINK: Render an internal path as a link.
* @return
* Returns an array. The first value is the access, the second is the map
* with objects loaded where appropriate and the third is the path ready for
* printing.
*/
function _menu_translate($item, $map, $operation = MENU_HANDLE_REQUEST) {
$path = '';
// Check if there are dynamic arguments in the path that need to be calculated.
if ($item->load_functions || ($operation == MENU_RENDER_LINK && $item->to_arg_functions)) {
$load_functions = unserialize($item->load_functions);
$to_arg_functions = unserialize($item->to_arg_functions);
$path_map = ($operation == MENU_HANDLE_REQUEST) ? $map : explode('/', $item->path);
foreach ($load_functions as $index => $load_function) {
// Translate place-holders into real values.
if ($operation == MENU_RENDER_LINK) {
if (isset($to_arg_functions[$index])) {
$to_arg_function = $to_arg_functions[$index];
$return = $to_arg_function(!empty($map[$index]) ? $map[$index] : '');
if (!empty($map[$index]) || isset($return)) {
$path_map[$index] = $return;
}
else {
unset($path_map[$index]);
}
}
else {
$path_map[$index] = isset($map[$index]) ? $map[$index] : '';
}
}
// We now have a real path regardless of operation, map it.
if ($load_function) {
$return = $load_function(isset($path_map[$index]) ? $path_map[$index] : '');
// If callback returned an error or there is no callback, trigger 404.
if ($return === FALSE) {
return array(FALSE, FALSE, '');
}
$map[$index] = $return;
}
}
if ($operation != MENU_HANDLE_REQUEST) {
// Re-join the path with the new replacement value.
$path = implode('/', $path_map);
} }
} }
else {
$path = $item->path;
}
// Determine access callback, which will decide whether or not the current user has
// access to this path.
$callback = $item->access_callback; $callback = $item->access_callback;
// Check for a TRUE or FALSE value.
if (is_numeric($callback)) { if (is_numeric($callback)) {
return $callback; return array($callback, $map, $path);
} }
$arguments = menu_unserialize($item->access_arguments, $map); $arguments = menu_unserialize($item->access_arguments, $map);
// As call_user_func_array is quite slow and user_access is a very common // As call_user_func_array is quite slow and user_access is a very common
// callback, it is worth making a special case for it. // callback, it is worth making a special case for it.
if ($callback == 'user_access') { if ($callback == 'user_access') {
return (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]); $access = (count($arguments) == 1) ? user_access($arguments[0]) : user_access($arguments[0], $arguments[1]);
return array($access, $map, $path);
} }
return call_user_func_array($callback, $arguments); return array(call_user_func_array($callback, $arguments), $map, $path);
} }
/** /**
* Returns a rendered menu tree. * Returns a rendered menu tree.
*/ */
function menu_tree() { function menu_tree() {
$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 vancode')); list(, $menu) = _menu_tree(db_query('SELECT * FROM {menu} WHERE pid IN ('. $item->parents .') AND visible = 1 ORDER BY vancode'));
return $menu; return $menu;
}
} }
function _menu_tree($result = NULL, $depth = 0, $link = array('link' => '', 'has_children' => FALSE)) { function _menu_tree($result = NULL, $depth = 0, $link = array('link' => '', 'has_children' => FALSE)) {
static $original_map; static $original_map;
$remnant = array('link' => '', 'has_children' => FALSE); $remnant = array('link' => '', 'has_children' => FALSE);
$tree = ''; $tree = '';
$map = arg(NULL);
while ($item = db_fetch_object($result)) { while ($item = db_fetch_object($result)) {
$map = arg(NULL, $item->path); list($access, , $path) = _menu_translate($item, $map, MENU_RENDER_LINK);
if (!_menu_access($item, $map)) { if (!$access) {
continue; continue;
} }
$menu_link = array('link' => $item->menu_link, 'has_children' => $item->has_children); $menu_link = array('link' => l($item->title, $path), 'has_children' => $item->has_children);
if ($item->depth > $depth) { if ($item->depth > $depth) {
list($remnant, $menu) = _menu_tree($result, $item->depth, $menu_link); list($remnant, $menu) = _menu_tree($result, $item->depth, $menu_link);
$tree .= theme('menu_tree', $link, $menu); $tree .= theme('menu_tree', $link, $menu);
@ -385,7 +465,11 @@ function theme_menu_tree($link, $tree) {
* Generate the HTML for a menu link. * Generate the HTML for a menu link.
*/ */
function theme_menu_link($link, $menu = '') { function theme_menu_link($link, $menu = '') {
return '<li class="'. ($menu ? 'expanded' : ($link['has_children'] ? 'collapsed' : 'leaf')) .'">'. $link['link'] . $menu .'</li>' . "\n"; return '<li class="'. ($menu ? 'expanded' : (empty($link['has_children']) ? 'leaf': 'collapsed')) .'">'. $link['link'] . $menu .'</li>' . "\n";
}
function theme_menu_local_task($link, $active = FALSE) {
return '<li '. ($active ? 'class="active" ' : ''). '>'. $link .'</li>';
} }
/** /**
@ -430,47 +514,96 @@ function menu_rebuild() {
$function($menu); $function($menu);
} }
$mid = 1; $mid = 1;
// First pass. // First pass: separate callbacks from pathes, making pathes ready for
// matching. Calculate fitness, and fill some default values.
foreach ($menu as $path => $item) { foreach ($menu as $path => $item) {
$item = &$menu[$path];
$parts = explode('/', $path, 6); $parts = explode('/', $path, 6);
$number_parts = count($parts); $number_parts = count($parts);
// We store the highest index of parts here to save some work in the weight // We store the highest index of parts here to save some work in the fit
// calculation loop. // calculation loop.
$slashes = $number_parts - 1; $slashes = $number_parts - 1;
// If there is no %, it fits maximally. $fit = 0;
if (strpos($path, '%') === FALSE) { $load_functions = array();
$fit = (1 << $number_parts) - 1; $to_arg_functions = array();
} // extract functions
else { foreach ($parts as $k => $part) {
// We need to calculate the fitness. $match = FALSE;
$fit = 0; if (preg_match('/^%([a-z_]*)$/', $part, $matches)) {
foreach ($parts as $k => $part) { if (empty($matches[1])) {
// ($part != '%') is the bit we want and we shift it to its place $match = TRUE;
// by shifting to left by ($slashes - $k) bits. }
$fit |= ($part != '%') << ($slashes - $k); else {
if (function_exists($matches[1] .'_load')) {
$load_functions[$k] = $matches[1] .'_load';
$match = TRUE;
}
if (function_exists($matches[1] .'_to_arg')) {
$to_arg_functions[$k] = $matches[1].'_to_arg';
$match = TRUE;
}
if (!isset($load_functions[$k]) && isset($to_arg_functions[$k])) {
$load_functions[$k] = FALSE;
}
}
}
if ($match) {
$parts[$k] = '%';
}
else {
$fit |= 1 << ($slashes - $k);
} }
} }
if (!isset($item['_visible'])) { $item['load_functions'] = empty($load_functions) ? '' : serialize($load_functions);
$item['_visible'] = (!isset($item['type']) || ($item['type'] & MENU_VISIBLE_IN_TREE)) ? 1 : 0; $item['to_arg_functions'] = empty($to_arg_functions) ? '' : serialize($to_arg_functions);
// If there is no %, it fits maximally.
if (!$fit) {
$fit = (1 << $number_parts) - 1;
$move = FALSE;
}
else {
$move = TRUE;
}
$item += array(
'title' => '',
'weight' => 0,
'type' => MENU_NORMAL_ITEM,
'_number_parts' => $number_parts,
'_parts' => $parts,
'_fit' => $fit,
'_mid' => $mid++,
);
$item += array(
'_visible' => (bool)($item['type'] & MENU_VISIBLE_IN_TREE),
'_tab' => (bool)($item['type'] & MENU_IS_LOCAL_TASK),
);
if ($move) {
$new_path = implode('/', $item['_parts']);
unset($menu[$path]);
}
else {
$new_path = $path;
}
$menu[$new_path] = $item;
}
// Second pass: find visible parents and prepare for sorting.
foreach ($menu as $path => $item) {
$item = &$menu[$path];
$number_parts = $item['_number_parts'];
$parents = array($item['_mid']);
if ($item['_visible'] && isset($item['parent'])) {
$parent_parts = explode('/', $item['parent'], 6);
$slashes = count($parent_parts) - 1;
}
else {
$parent_parts = $item['_parts'];
$slashes = $number_parts -1;
} }
$depth = 1; $depth = 1;
if (!isset($item['_mid'])) {
$item['_mid'] = $mid++;
}
$parents = array($item['_mid']);
for ($i = $slashes; $i; $i--) { for ($i = $slashes; $i; $i--) {
$parent_path = implode('/', array_slice($parts, 0, $i)); $parent_path = implode('/', array_slice($parent_parts, 0, $i));
// We need to calculate depth to be able to sort. depth needs visibility. // We need to calculate depth to be able to sort. depth needs visibility.
if (isset($menu[$parent_path])) { if (isset($menu[$parent_path])) {
$parent = &$menu[$parent_path]; $parent = &$menu[$parent_path];
// It's possible that the parent was not processed yet.
if (!isset($parent['_mid'])) {
$parent['_mid'] = $mid++;
}
if (!isset($parent['_visible'])) {
$parent['_visible'] = (!isset($parent['type']) || ($parent['type'] & MENU_VISIBLE_IN_TREE)) ? 1 : 0;
}
if ($item['_visible'] && $parent['_visible']) { if ($item['_visible'] && $parent['_visible']) {
$parent['_has_children'] = 1; $parent['_has_children'] = 1;
$depth++; $depth++;
@ -487,22 +620,16 @@ function menu_rebuild() {
$parents = implode(',', array_reverse($parents)); $parents = implode(',', array_reverse($parents));
// Store variables and set defaults. // Store variables and set defaults.
$item += array( $item += array(
'_fit' => $fit,
'_number_parts' => $number_parts,
'_parts' => $parts,
'_pid' => 0, '_pid' => 0,
'_depth' => $depth, '_depth' => $item['_visible'] ? $depth : $number_parts,
'_parents' => $parents, '_parents' => $parents,
'_has_children' => 0, '_has_children' => 0,
'title' => '',
'weight' => 0,
'type' => MENU_NORMAL_ITEM,
); );
$sort[$path] = ($item['_visible'] ? $depth : $number_parts) . sprintf('%05d', $item['weight']) . $item['title']; $sort[$path] = $item['_depth'] . sprintf('%05d', $item['weight']) . $item['title'];
unset($item); unset($item);
} }
array_multisort($sort, $menu); array_multisort($sort, $menu);
// Second pass: calculate ancestors, vancode and store into the database. // Third pass: calculate ancestors, vancode and store into the database.
foreach ($menu as $path => $item) { foreach ($menu as $path => $item) {
$item = &$menu[$path]; $item = &$menu[$path];
for ($i = $item['_number_parts'] - 1; $i; $i--) { for ($i = $item['_number_parts'] - 1; $i; $i--) {
@ -512,7 +639,7 @@ function menu_rebuild() {
// If a callback is not found, we try to find the first parent that // If a callback is not found, we try to find the first parent that
// has this callback. When found, its callback argument will also be // has this callback. When found, its callback argument will also be
// copied but only if there is none in the current item. // copied but only if there is none in the current item.
foreach (array('access', 'map', 'page') as $type) { foreach (array('access', 'page') as $type) {
if (!isset($item["$type callback"]) && isset($parent["$type callback"])) { if (!isset($item["$type callback"]) && isset($parent["$type callback"])) {
$item["$type callback"] = $parent["$type callback"]; $item["$type callback"] = $parent["$type callback"];
if (!isset($item["$type arguments"]) && isset($parent["$type arguments"])) { if (!isset($item["$type arguments"]) && isset($parent["$type arguments"])) {
@ -525,9 +652,6 @@ function menu_rebuild() {
if (!isset($item['access callback'])) { if (!isset($item['access callback'])) {
$menu[$path]['access callback'] = isset($item['access arguments']) ? 'user_access' : 0; $menu[$path]['access callback'] = isset($item['access arguments']) ? 'user_access' : 0;
} }
if (!isset($item['map callback']) && isset($item['map arguments'])) {
$item['map callback'] = 'menu_map';
}
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']);
} }
@ -538,42 +662,39 @@ function menu_rebuild() {
} }
$vancode = $prefix . int2vancode($next[$prefix]++); $vancode = $prefix . int2vancode($next[$prefix]++);
$menu[$path]['_prefix'] = $vancode .'.'; $menu[$path]['_prefix'] = $vancode .'.';
$link = l($item['title'], $path, isset($item['attributes']) ? $item['attributes'] : array(), isset($item['query']) ? $item['query'] : NULL, isset($item['fragment']) ? $item['fragment'] : NULL);
} }
else { else {
$vancode = ''; $vancode = '';
$link = '';
} }
$tab = ($item['type'] & MENU_IS_LOCAL_TASK) ? 1 : 0; if ($item['_tab']) {
$default_tab = $item['type'] == MENU_DEFAULT_LOCAL_TASK; if (!isset($item['parent'])) {
if (!isset($item['parent'])) {
if ($tab) {
$item['parent'] = implode('/', array_slice($item['_parts'], 0, $item['_number_parts'] - 1)); $item['parent'] = implode('/', array_slice($item['_parts'], 0, $item['_number_parts'] - 1));
} }
else { }
$item['parent'] = $path; else {
} // Non-tab items specified the parent for visible links, and it's
// stored in parents, parent stores the tab parent.
$item['parent'] = $path;
} }
$insert_item = $item + array( $insert_item = $item + array(
'access arguments' => array(), 'access arguments' => array(),
'access callback' => '', 'access callback' => '',
'page arguments' => array(), 'page arguments' => array(),
'page callback' => '', 'page callback' => '',
'map arguments' => array(),
'map callback' => '',
); );
db_query("INSERT INTO {menu} ( db_query("INSERT INTO {menu} (
mid, pid, path, mid, pid, path, load_functions, to_arg_functions,
access_callback, access_arguments, page_callback, page_arguments, map_callback, map_arguments, fit, access_callback, access_arguments, page_callback, page_arguments, fit,
number_parts, vancode, menu_link, visible, parents, depth, has_children, tab, default_tab, title, parent) number_parts, vancode, visible, parents, depth, has_children, tab, title, parent, type)
VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', '%s', %d, '%s', %d, %d, %d, %d, '%s', '%s')", VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, %d, '%s', '%s', '%s')",
$insert_item['_mid'], $insert_item['_pid'], $path, $insert_item['access callback'], $insert_item['_mid'], $insert_item['_pid'], $path,
serialize($insert_item['access arguments']), $insert_item['page callback'], $insert_item['load_functions'], $insert_item['to_arg_functions'],
serialize($insert_item['page arguments']), $insert_item['map callback'], $insert_item['access callback'], serialize($insert_item['access arguments']),
serialize($insert_item['map arguments']), $insert_item['_fit'], $insert_item['page callback'], serialize($insert_item['page arguments']),
$insert_item['_number_parts'], $vancode .'+', $link, $insert_item['_visible'], $insert_item['_fit'], $insert_item['_number_parts'], $vancode .'+',
$insert_item['_parents'], $insert_item['_depth'], $insert_item['_has_children'], $insert_item['_visible'], $insert_item['_parents'], $insert_item['_depth'],
$tab, $default_tab, $insert_item['title'], $insert_item['parent']); $insert_item['_has_children'], $item['_tab'], $insert_item['title'],
$insert_item['parent'], $insert_item['type']);
unset($item); unset($item);
} }
} }
@ -590,32 +711,79 @@ function menu_primary_links() {
function menu_secondary_links() { function menu_secondary_links() {
} }
function menu_primary_local_tasks() { /**
$router_item = menu_get_item(); * Collects the local tasks (tabs) for a given level.
$result = db_query("SELECT * FROM {menu} WHERE parent = '%s' AND tab = 1 ORDER BY vancode", $router_item->parent); *
$tabs = array(); * @param $level
while ($item = db_fetch_object($result)) { The level of tasks you ask for. Primary tasks are 0, secondary are 1...
$map = explode('/', $item->path); * @return
foreach ($map as $key => $value) { * An array of links to the tabs.
if ($value == '%') { */
$map[$key] = arg($key); function menu_local_tasks($level = 0) {
static $tabs = array(), $parents = array(), $parents_done = array();
if (empty($tabs)) {
$router_item = menu_get_item();
$map = arg(NULL);
do {
// Tabs are router items that have the same parent. If there is a new
// parent, let's add it the queue.
if (!empty($router_item->parent)) {
$parents[] = $router_item->parent;
// Do not add the same item twice.
$router_item->parent = '';
} }
} $parent = array_shift($parents);
$path = implode('/', $map); // Do not process the same parent twice.
if (_menu_access($item, $map, TRUE)) { if (isset($parents_done[$parent])) {
$link = l($item->title, $path); continue;
if ((!$router_item->tab && $item->default_tab) || ($path == $_GET['q'])) {
$tabs[] = array('class' => 'active', 'data' => $link);
} }
else { // This loads all the tabs.
$tabs[] = $link; $result = db_query("SELECT * FROM {menu} WHERE parent = '%s' AND tab = 1 ORDER BY vancode", $parent);
$tabs_current = '';
while ($item = db_fetch_object($result)) {
// This call changes the path from for example user/% to user/123 and
// also determines whether we are allowed to access it.
list($access, , $path) = _menu_translate($item, $map, MENU_RENDER_LINK);
if ($access) {
$depth = $item->depth;
$link = l($item->title, $path);
// We check for the active tab.
if ($item->path == $router_item->path || (!$router_item->tab && $item->type == MENU_DEFAULT_LOCAL_TASK) || $path == $_GET['q']) {
$tabs_current .= theme('menu_local_task', $link, TRUE);
// Let's try to find the router item one level up.
$next_router_item = db_fetch_object(db_query("SELECT path, tab, parent FROM {menu} WHERE path = '%s'", $item->parent));
// We will need to inspect one level down.
$parents[] = $item->path;
}
else {
$tabs_current .= theme('menu_local_task', $link);
}
}
} }
} // If there are tabs, let's add them
if ($tabs_current) {
$tabs[$depth] = $tabs_current;
}
$parents_done[$parent] = TRUE;
if (isset($next_router_item)) {
$router_item = $next_router_item;
}
unset($next_router_item);
} while ($parents);
// Sort by depth
ksort($tabs);
// Remove the depth, we are interested only in their relative placement.
$tabs = array_values($tabs);
} }
return theme('item_list', $tabs, NULL, 'ul', array('class' => 'tabs primary')); return isset($tabs[$level]) ? $tabs[$level] : array();
}
function menu_primary_local_tasks() {
return menu_local_tasks();
} }
function menu_secondary_local_tasks() { function menu_secondary_local_tasks() {
return menu_local_tasks(1);
} }
function menu_set_active_item() { function menu_set_active_item() {
@ -631,4 +799,4 @@ function menu_get_active_breadcrumb() {
function menu_get_active_title() { function menu_get_active_title() {
$item = menu_get_item(); $item = menu_get_item();
return $item->title; return $item->title;
} }

View File

@ -34,4 +34,4 @@ elseif (isset($return)) {
} }
drupal_page_footer(); drupal_page_footer();

View File

@ -51,19 +51,17 @@ function aggregator_menu() {
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'parent' => 'admin/content/aggregator', 'parent' => 'admin/content/aggregator',
); );
$items['admin/content/aggregator/remove/%'] = array( $items['admin/content/aggregator/remove/%aggregator_feed'] = array(
'title' => t('Remove items'), 'title' => t('Remove items'),
'page callback' => 'aggregator_admin_remove_feed', 'page callback' => 'aggregator_admin_remove_feed',
'page arguments' => array(4), 'page arguments' => array(4),
'map arguments' => array('aggregator_get_feed', 4),
'access arguments' => array('administer news feeds'), 'access arguments' => array('administer news feeds'),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['admin/content/aggregator/update/%'] = array( $items['admin/content/aggregator/update/%aggregator_feed'] = array(
'title' => t('Update items'), 'title' => t('Update items'),
'page callback' => 'aggregator_admin_refresh_feed', 'page callback' => 'aggregator_admin_refresh_feed',
'page arguments' => array(4), 'page arguments' => array(4),
'map arguments' => array('aggregator_get_feed', 4),
'access arguments' => array('administer news feeds'), 'access arguments' => array('administer news feeds'),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
@ -137,24 +135,23 @@ function aggregator_menu() {
'weight' => 1, 'weight' => 1,
); );
} }
$items['aggregator/sources/%'] = array( $items['aggregator/sources/%aggregator_feed'] = array(
'page callback' => 'aggregator_page_source', 'page callback' => 'aggregator_page_source',
'map arguments' => array('aggregator_get_feed', 2),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['aggregator/sources/%/view'] = array( $items['aggregator/sources/%aggregator_feed/view'] = array(
'title' => t('View'), 'title' => t('View'),
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10, 'weight' => -10,
); );
$items['aggregator/sources/%/categorize'] = array( $items['aggregator/sources/%aggregator_feed/categorize'] = array(
'title' => t('Categorize'), 'title' => t('Categorize'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_page_source'), 'page arguments' => array('aggregator_page_source'),
'access arguments' => array('administer news feeds'), 'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
); );
$items['aggregator/sources/%/configure'] = array( $items['aggregator/sources/%aggregator_feed/configure'] = array(
'title' => t('Configure'), 'title' => t('Configure'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_feed', 2), 'page arguments' => array('aggregator_form_feed', 2),
@ -162,20 +159,18 @@ function aggregator_menu() {
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'weight' => 1, 'weight' => 1,
); );
$items['admin/content/aggregator/edit/feed/%'] = array( $items['admin/content/aggregator/edit/feed/%aggregator_feed'] = array(
'title' => t('Edit feed'), 'title' => t('Edit feed'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_feed', 5), 'page arguments' => array('aggregator_form_feed', 5),
'access arguments' => array('administer news feeds'), 'access arguments' => array('administer news feeds'),
'map arguments' => array('aggregator_get_feed', 5),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['admin/content/aggregator/edit/category/%'] = array( $items['admin/content/aggregator/edit/category/%aggregator_category'] = array(
'title' => t('Edit category'), 'title' => t('Edit category'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_category', 5), 'page arguments' => array('aggregator_form_category', 5),
'access arguments' => array('administer news feeds'), 'access arguments' => array('administer news feeds'),
'map arguments' => array('aggregator_get_category', 5),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
@ -964,11 +959,11 @@ function aggregator_save_item($edit) {
} }
} }
function aggregator_get_feed($fid) { function aggregator_feed_load($fid) {
return db_fetch_array(db_query('SELECT * FROM {aggregator_feed} WHERE fid = %d', $fid)); return db_fetch_array(db_query('SELECT * FROM {aggregator_feed} WHERE fid = %d', $fid));
} }
function aggregator_get_category($cid) { function aggregator_category_load($cid) {
return db_fetch_array(db_query('SELECT * FROM {aggregator_category} WHERE cid = %d', $cid)); return db_fetch_array(db_query('SELECT * FROM {aggregator_category} WHERE cid = %d', $cid));
} }
@ -1035,7 +1030,7 @@ function aggregator_page_last() {
*/ */
function aggregator_page_source() { function aggregator_page_source() {
$feed = db_fetch_object(db_query('SELECT * FROM {aggregator_feed} WHERE fid = %d', arg(2))); $feed = db_fetch_object(db_query('SELECT * FROM {aggregator_feed} WHERE fid = %d', arg(2)));
drupal_set_title($feed->title); drupal_set_title(check_plain($feed->title));
$info = theme('aggregator_feed', $feed); $info = theme('aggregator_feed', $feed);
return _aggregator_page_list('SELECT * FROM {aggregator_item} WHERE fid = '. $feed->fid .' ORDER BY timestamp DESC, iid DESC', arg(3), $info); return _aggregator_page_list('SELECT * FROM {aggregator_item} WHERE fid = '. $feed->fid .' ORDER BY timestamp DESC, iid DESC', arg(3), $info);

View File

@ -105,6 +105,9 @@ function blog_feed_last() {
* Menu callback; displays a Drupal page containing recent blog entries. * Menu callback; displays a Drupal page containing recent blog entries.
*/ */
function blog_page($a = NULL, $b = NULL) { function blog_page($a = NULL, $b = NULL) {
if (is_object($a)) {
$a = $a->uid;
}
if (is_numeric($a)) { // $a is a user ID if (is_numeric($a)) { // $a is a user ID
if ($b == 'feed') { if ($b == 'feed') {
@ -256,7 +259,7 @@ function blog_menu() {
'access arguments' => array('access content'), 'access arguments' => array('access content'),
'type' => MENU_SUGGESTED_ITEM, 'type' => MENU_SUGGESTED_ITEM,
); );
$items['blog/%'] = array( $items['blog/%user_current'] = array(
'title' => t('My blog'), 'title' => t('My blog'),
'page arguments' => array(1), 'page arguments' => array(1),
'access arguments' => array('edit own blog'), 'access arguments' => array('edit own blog'),

View File

@ -114,13 +114,12 @@ function book_menu() {
'page arguments' => array(2, 3), 'page arguments' => array(2, 3),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['node/%/outline'] = array( $items['node/%node/outline'] = array(
'title' => t('Outline'), 'title' => t('Outline'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('book_outline', 1), 'page arguments' => array('book_outline', 1),
'access callback' => '_book_outline_access', 'access callback' => '_book_outline_access',
'access arguments' => array(1), 'access arguments' => array(1),
'map arguments' => array('node_load', 1),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'weight' => 2, 'weight' => 2,
); );

View File

@ -195,15 +195,14 @@ function comment_menu() {
'access arguments' => array('post comments'), 'access arguments' => array('post comments'),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['comment/reply'] = array( $items['comment/reply/%node'] = array(
'title' => t('Reply to comment'), 'title' => t('Reply to comment'),
'page callback' => 'comment_reply', 'page callback' => 'comment_reply',
'access callback' => 'node_access', 'access callback' => 'node_access',
'access arguments' => array('view', 2), 'access arguments' => array('view', 2),
'map arguments' => array('node_load', 2),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['node/%/%'] = array( $items['node/%node/%'] = array(
'title' => t('View'), 'title' => t('View'),
'page callback' => 'node_page_view', 'page callback' => 'node_page_view',
'page arguments' => array(1, 2), 'page arguments' => array(1, 2),

View File

@ -84,14 +84,13 @@ function contact_menu() {
'access arguments' => array('access site-wide contact form'), 'access arguments' => array('access site-wide contact form'),
'type' => MENU_SUGGESTED_ITEM, 'type' => MENU_SUGGESTED_ITEM,
); );
$items['user/%/contact'] = array( $items['user/%user/contact'] = array(
'title' => t('Contact'), 'title' => t('Contact'),
'page callback' => 'contact_user_page', 'page callback' => 'contact_user_page',
'page arguments' => array(1), 'page arguments' => array(1),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'access callback' => '_contact_user_tab_access', 'access callback' => '_contact_user_tab_access',
'access arguments' => array(1), 'access arguments' => array(1),
'map arguments' => array('user_load', 1),
'weight' => 2, 'weight' => 2,
); );
return $items; return $items;

View File

@ -81,26 +81,25 @@ function filter_menu() {
'access callback' => TRUE, 'access callback' => TRUE,
'type' => MENU_SUGGESTED_ITEM, 'type' => MENU_SUGGESTED_ITEM,
); );
$items['admin/settings/filters/%'] = array( $items['admin/settings/filters/%filter_format'] = array(
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
'page arguments' => array('filter_admin_format_form', 3), 'page arguments' => array('filter_admin_format_form', 3),
'access arguments' => array('administer filters'), 'access arguments' => array('administer filters'),
'map arguments' => array('filter_formats', 3),
); );
$items['admin/settings/filters/%/list'] = array( $items['admin/settings/filters/%filter_format/list'] = array(
'title' => t('View'), 'title' => t('View'),
'page arguments' => array('filter_admin_format_form', 3), 'page arguments' => array('filter_admin_format_form', 3),
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0, 'weight' => 0,
); );
$items['admin/settings/filters/%/configure'] = array( $items['admin/settings/filters/%filter_format/configure'] = array(
'title' => t('Configure'), 'title' => t('Configure'),
'page arguments' => array('filter_admin_configure', 3), 'page arguments' => array('filter_admin_configure', 3),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'weight' => 1, 'weight' => 1,
); );
$items['admin/settings/filters/%/order'] = array( $items['admin/settings/filters/%filter_format/order'] = array(
'title' => t('Rearrange'), 'title' => t('Rearrange'),
'page arguments' => array('filter_admin_order', 3), 'page arguments' => array('filter_admin_order', 3),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
@ -109,6 +108,10 @@ function filter_menu() {
return $items; return $items;
} }
function filter_format_load($arg) {
return filter_formats($arg);
}
/** /**
* Implementation of hook_perm(). * Implementation of hook_perm().
*/ */

View File

@ -75,19 +75,21 @@ function forum_menu() {
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'parent' => 'admin/content/forum', 'parent' => 'admin/content/forum',
); );
$items['admin/content/forum/edit'] = array( $items['admin/content/forum/edit/%forum_term'] = array(
'page callback' => 'forum_form_main', 'page callback' => 'forum_form_main',
'map arguments' => array('_forum_get_term', 5, array()),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['admin/content/forum/edit/container/%'] = array( $items['admin/content/forum/edit/container/%forum_term'] = array(
'title' => t('Edit container'), 'title' => t('Edit container'),
'page callback' => 'forum_form_main',
'page arguments' => array('container', 5), 'page arguments' => array('container', 5),
'type' => MENU_CALLBACK,
); );
$items['admin/content/forum/edit/forum/%'] = array( $items['admin/content/forum/edit/forum/%forum_term'] = array(
'title' => t('Edit forum'), 'title' => t('Edit forum'),
'page callback' => 'forum_form_main', 'page callback' => 'forum_form_main',
'page arguments' => array('forum', 5), 'page arguments' => array('forum', 5),
'type' => MENU_CALLBACK,
); );
return $items; return $items;
} }
@ -96,7 +98,7 @@ function forum_init() {
drupal_add_css(drupal_get_path('module', 'forum') .'/forum.css'); drupal_add_css(drupal_get_path('module', 'forum') .'/forum.css');
} }
function _forum_get_term($tid) { function forum_term_load($tid) {
return (array)taxonomy_get_term($tid); return (array)taxonomy_get_term($tid);
} }
@ -295,7 +297,7 @@ function forum_block($op = 'list', $delta = 0, $edit = array()) {
*/ */
function forum_view(&$node, $teaser = FALSE, $page = FALSE) { function forum_view(&$node, $teaser = FALSE, $page = FALSE) {
if ($page) { if ($page) {
$vocabulary = taxonomy_get_vocabulary(variable_get('forum_nav_vocabulary', '')); $vocabulary = taxonomy_vocabulary_load(variable_get('forum_nav_vocabulary', ''));
// Breadcrumb navigation // Breadcrumb navigation
$breadcrumb = array(); $breadcrumb = array();
$breadcrumb[] = array('path' => 'forum', 'title' => $vocabulary->name); $breadcrumb[] = array('path' => 'forum', 'title' => $vocabulary->name);
@ -876,7 +878,7 @@ function theme_forum_display($forums, $topics, $parents, $tid, $sortby, $forum_p
global $user; global $user;
// forum list, topics list, topic browser and 'add new topic' link // forum list, topics list, topic browser and 'add new topic' link
$vocabulary = taxonomy_get_vocabulary(variable_get('forum_nav_vocabulary', '')); $vocabulary = taxonomy_vocabulary_load(variable_get('forum_nav_vocabulary', ''));
$title = $vocabulary->name; $title = $vocabulary->name;
// Breadcrumb navigation: // Breadcrumb navigation:

View File

@ -1166,33 +1166,32 @@ function node_menu() {
} }
} }
$items['node/%'] = array( $items['node/%node'] = array(
'title' => t('View'), 'title' => t('View'),
'page callback' => 'node_page_view', 'page callback' => 'node_page_view',
'page arguments' => array(1), 'page arguments' => array(1),
'access callback' => 'node_access', 'access callback' => 'node_access',
'access arguments' => array('view', 1), 'access arguments' => array('view', 1),
'map arguments' => array('node_load', 1),
'type' => MENU_CALLBACK); 'type' => MENU_CALLBACK);
$items['node/%/view'] = array( $items['node/%node/view'] = array(
'title' => t('View'), 'title' => t('View'),
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10); 'weight' => -10);
$items['node/%/edit'] = array( $items['node/%node/edit'] = array(
'title' => t('Edit'), 'title' => t('Edit'),
'page callback' => 'node_page_edit', 'page callback' => 'node_page_edit',
'page arguments' => array(1), 'page arguments' => array(1),
'access arguments' => array('update', 1), 'access arguments' => array('update', 1),
'weight' => 1, 'weight' => 1,
'type' => MENU_LOCAL_TASK); 'type' => MENU_LOCAL_TASK);
$items['node/%/delete'] = array( $items['node/%node/delete'] = array(
'title' => t('Delete'), 'title' => t('Delete'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('node_delete_confirm', 1), 'page arguments' => array('node_delete_confirm', 1),
'access arguments' => array('delete', 1), 'access arguments' => array('delete', 1),
'weight' => 1, 'weight' => 1,
'type' => MENU_CALLBACK); 'type' => MENU_CALLBACK);
$items['node/%/revisions'] = array( $items['node/%node/revisions'] = array(
'title' => t('Revisions'), 'title' => t('Revisions'),
'page callback' => 'node_revisions', 'page callback' => 'node_revisions',
'access callback' => '_node_revision_access', 'access callback' => '_node_revision_access',
@ -2464,7 +2463,7 @@ function node_update_index() {
*/ */
function node_form_alter($form_id, &$form) { function node_form_alter($form_id, &$form) {
// Advanced node search form // Advanced node search form
if ($form_id == 'search_form' && arg(1) == 'node' && user_access('use advanced search')) { if ($form_id == 'search_form' && $form['module']['#value'] == 'node' && user_access('use advanced search')) {
// Keyword boxes: // Keyword boxes:
$form['advanced'] = array( $form['advanced'] = array(
'#type' => 'fieldset', '#type' => 'fieldset',

View File

@ -239,14 +239,14 @@ function poll_menu() {
'type' => MENU_SUGGESTED_ITEM, 'type' => MENU_SUGGESTED_ITEM,
); );
$items['poll/cancel/%'] = array( $items['poll/cancel/%node'] = array(
'title' => t('Cancel'), 'title' => t('Cancel'),
'page callback' => 'poll_cancel', 'page callback' => 'poll_cancel',
'page arguments' => array(2), 'page arguments' => array(2),
'access arguments' => array('cancel own vote'), 'access arguments' => array('cancel own vote'),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['node/%/votes'] = array( $items['node/%node/votes'] = array(
'title' => t('Votes'), 'title' => t('Votes'),
'page callback' => 'poll_votes', 'page callback' => 'poll_votes',
'access callback' => '_poll_menu_access', 'access callback' => '_poll_menu_access',
@ -254,7 +254,7 @@ function poll_menu() {
'weight' => 3, 'weight' => 3,
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
); );
$items['node/%/results'] = array( $items['node/%node/results'] = array(
'title' => t('Results'), 'title' => t('Results'),
'page callback' => 'poll_results', 'page callback' => 'poll_results',
'access callback' => '_poll_menu_access', 'access callback' => '_poll_menu_access',

View File

@ -355,6 +355,7 @@ function profile_field_form_submit($form_id, $form_values) {
drupal_set_message(t('The field has been updated.')); drupal_set_message(t('The field has been updated.'));
} }
cache_clear_all(); cache_clear_all();
menu_rebuild();
return 'admin/user/profile'; return 'admin/user/profile';
} }

View File

@ -140,7 +140,6 @@ function search_menu() {
$items['search'] = array( $items['search'] = array(
'title' => t('Search'), 'title' => t('Search'),
'page callback' => 'search_view', 'page callback' => 'search_view',
'page arguments' => array('node'),
'access arguments' => array('search content'), 'access arguments' => array('search content'),
'type' => MENU_SUGGESTED_ITEM, 'type' => MENU_SUGGESTED_ITEM,
); );
@ -167,13 +166,14 @@ function search_menu() {
); );
foreach (module_implements('search') as $name) { foreach (module_implements('search') as $name) {
$items['search/'. $name] = array( $items['search/'. $name .'/%search'] = array(
'title' => module_invoke($name, 'search', 'name', TRUE), 'title' => module_invoke($name, 'search', 'name', TRUE),
'page callback' => 'search_view', 'page callback' => 'search_view',
'page arguments' => array($name), 'page arguments' => array($name),
'access callback' => '_search_menu', 'access callback' => '_search_menu',
'access arguments' => array($name), 'access arguments' => array($name),
'type' => $name == 'node' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, 'type' => $name == 'node' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'parent' => 'search',
); );
} }
return $items; return $items;
@ -183,6 +183,10 @@ function _search_menu($name) {
return user_access('search content') && module_invoke($name, 'search', 'name'); return user_access('search content') && module_invoke($name, 'search', 'name');
} }
function search_to_arg() {
return search_get_keys();
}
/** /**
* Validate callback. * Validate callback.
*/ */
@ -882,16 +886,21 @@ function do_search($keywords, $type, $join1 = '', $where1 = '1', $arguments1 = a
* Helper function for grabbing search keys. * Helper function for grabbing search keys.
*/ */
function search_get_keys() { function search_get_keys() {
// Extract keys as remainder of path static $return;
// Note: support old GET format of searches for existing links. if (!isset($return)) {
$path = explode('/', $_GET['q'], 3); // Extract keys as remainder of path
return count($path) == 3 ? $path[2] : $_REQUEST['keys']; // Note: support old GET format of searches for existing links.
$path = explode('/', $_GET['q'], 3);
$keys = empty($_REQUEST['keys']) ? '' : $_REQUEST['keys'];
$return = count($path) == 3 ? $path[2] : $keys;
}
return $return;
} }
/** /**
* Menu callback; presents the search form and/or search results. * Menu callback; presents the search form and/or search results.
*/ */
function search_view($type = '') { function search_view($type = 'node') {
// Search form submits with POST but redirects to GET. This way we can keep // Search form submits with POST but redirects to GET. This way we can keep
// the search query URL clean as a whistle: // the search query URL clean as a whistle:
// search/type/keyword+keyword // search/type/keyword+keyword
@ -905,6 +914,7 @@ function search_view($type = '') {
$keys = search_get_keys(); $keys = search_get_keys();
// Only perform search if there is non-whitespace search term: // Only perform search if there is non-whitespace search term:
$results = '';
if (trim($keys)) { if (trim($keys)) {
// Log the search keys: // Log the search keys:
watchdog('search', t('%keys (@type).', array('%keys' => $keys, '@type' => module_invoke($type, 'search', 'name'))), WATCHDOG_NOTICE, l(t('results'), 'search/'. $type .'/'. $keys)); watchdog('search', t('%keys (@type).', array('%keys' => $keys, '@type' => module_invoke($type, 'search', 'name'))), WATCHDOG_NOTICE, l(t('results'), 'search/'. $type .'/'. $keys));

View File

@ -143,14 +143,15 @@ function statistics_menu() {
'type' => MENU_NORMAL_ITEM, 'type' => MENU_NORMAL_ITEM,
'weight' => 3, 'weight' => 3,
); );
$items['user/%/track/navigation'] = array( $items['user/%user/track/navigation'] = array(
'title' => t('Track page visits'), 'title' => t('Track page visits'),
'page callback' => 'statistics_user_tracker', 'page callback' => 'statistics_user_tracker',
'access callback' => 'user_access',
'access arguments' => array('access statistics'), 'access arguments' => array('access statistics'),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'weight' => 2, 'weight' => 2,
); );
$items['node/%/track'] = array( $items['node/%node/track'] = array(
'title' => t('Track'), 'title' => t('Track'),
'page callback' => 'statistics_node_tracker', 'page callback' => 'statistics_node_tracker',
'access callback' => 'user_access', 'access callback' => 'user_access',

View File

@ -327,31 +327,32 @@ function system_install() {
) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
db_query("CREATE TABLE {menu} ( db_query("CREATE TABLE {menu} (
mid int NOT NULL default '0',
pid int NOT NULL default '0',
path varchar(255) NOT NULL default '', path varchar(255) NOT NULL default '',
load_functions varchar(255) NOT NULL default '',
to_arg_functions varchar(255) NOT NULL default '',
access_callback varchar(255) NOT NULL default '', access_callback varchar(255) NOT NULL default '',
access_arguments text, access_arguments text,
page_callback varchar(255) NOT NULL default '', page_callback varchar(255) NOT NULL default '',
page_arguments text, page_arguments text,
map_callback varchar(255) NOT NULL default '',
map_arguments text,
fit int NOT NULL default '0', fit int NOT NULL default '0',
number_parts int NOT NULL default '0', number_parts int NOT NULL default '0',
vancode varchar(255) NOT NULL default '', vancode varchar(255) NOT NULL default '',
mid int NOT NULL default '0',
pid int NOT NULL default '0',
visible int NOT NULL default '0', visible int NOT NULL default '0',
menu_link varchar(255) NOT NULL default '',
parents varchar(255) NOT NULL default '', parents varchar(255) NOT NULL default '',
depth int NOT NULL default '0', depth int NOT NULL default '0',
has_children int NOT NULL default '0', has_children int NOT NULL default '0',
tab int NOT NULL default 0, tab int NOT NULL default 0,
title varchar(255) NOT NULL default '', title varchar(255) NOT NULL default '',
default_tab int NOT NULL default '0',
parent varchar(255) NOT NULL default '', parent varchar(255) NOT NULL default '',
type int NOT NULL default 0,
PRIMARY KEY (path), PRIMARY KEY (path),
KEY vancode (vancode), KEY vancode (vancode),
KEY fit (fit), KEY fit (fit),
KEY visible (visible) KEY visible (visible),
KEY pid (pid),
KEY parent (parent)
) /*!40100 DEFAULT CHARACTER SET UTF8 */ "); ) /*!40100 DEFAULT CHARACTER SET UTF8 */ ");
db_query("CREATE TABLE {node} ( db_query("CREATE TABLE {node} (
@ -801,30 +802,31 @@ function system_install() {
mid int NOT NULL default '0', mid int NOT NULL default '0',
pid int NOT NULL default '0', pid int NOT NULL default '0',
path varchar(255) NOT NULL default '', path varchar(255) NOT NULL default '',
load_functions varchar(255) NOT NULL default '',
to_arg_functions varchar(255) NOT NULL default '',
access_callback varchar(255) NOT NULL default '', access_callback varchar(255) NOT NULL default '',
access_arguments text, access_arguments text,
page_callback varchar(255) NOT NULL default '', page_callback varchar(255) NOT NULL default '',
page_arguments text, page_arguments text,
map_callback varchar(255) NOT NULL default '', fit int NOT NULL default '0',
map_arguments text, number_parts int NOT NULL default '0',
fit int NOT NULL default 0,
number_parts int NOT NULL default 0,
vancode varchar(255) NOT NULL default '', vancode varchar(255) NOT NULL default '',
visible int NOT NULL default '0', visible int NOT NULL default '0',
menu_link varchar(255) NOT NULL default '',
parents varchar(255) NOT NULL default '', parents varchar(255) NOT NULL default '',
depth int NOT NULL default '0', depth int NOT NULL default '0',
has_children int NOT NULL default '0', has_children int NOT NULL default '0',
tab int NOT NULL default '0', tab int NOT NULL default 0,
title varchar(255) NOT NULL default '', title varchar(255) NOT NULL default '',
default_tab int NOT NULL default '0',
parent varchar(255) NOT NULL default '', parent varchar(255) NOT NULL default '',
type int NOT NULL default 0,
PRIMARY KEY (path) PRIMARY KEY (path)
)"); )");
db_query("CREATE INDEX {menu}_vancode_idx ON {menu} (vancode)"); db_query("CREATE INDEX {menu}_vancode_idx ON {menu} (vancode)");
db_query("CREATE INDEX {menu}_fit_idx ON {menu} (fit)"); db_query("CREATE INDEX {menu}_fit_idx ON {menu} (fit)");
db_query("CREATE INDEX {menu}_visible_idx ON {menu} (visible)"); db_query("CREATE INDEX {menu}_visible_idx ON {menu} (visible)");
db_query("CREATE INDEX {menu}_parent_idx ON {menu} (parent)");
db_query("CREATE INDEX {menu}_pid_idx ON {menu} (parent)");
db_query("CREATE TABLE {node} ( db_query("CREATE TABLE {node} (
nid serial CHECK (nid >= 0), nid serial CHECK (nid >= 0),

View File

@ -59,7 +59,7 @@ function taxonomy_link($type, $node = NULL) {
*/ */
function taxonomy_term_path($term) { function taxonomy_term_path($term) {
$vocabulary = taxonomy_get_vocabulary($term->vid); $vocabulary = taxonomy_vocabulary_load($term->vid);
if ($vocabulary->module != 'taxonomy' && $path = module_invoke($vocabulary->module, 'term_path', $term)) { if ($vocabulary->module != 'taxonomy' && $path = module_invoke($vocabulary->module, 'term_path', $term)) {
return $path; return $path;
} }
@ -91,7 +91,7 @@ function taxonomy_menu() {
'parent' => 'admin/content/taxonomy', 'parent' => 'admin/content/taxonomy',
); );
$items['admin/content/taxonomy/edit/vocabulary/%'] = array( $items['admin/content/taxonomy/edit/vocabulary/%taxonomy_vocabulary'] = array(
'title' => t('Edit vocabulary'), 'title' => t('Edit vocabulary'),
'page callback' => 'taxonomy_admin_vocabulary_edit', 'page callback' => 'taxonomy_admin_vocabulary_edit',
'page arguments' => array(5), 'page arguments' => array(5),
@ -117,27 +117,26 @@ function taxonomy_menu() {
'access arguments' => array('access content'), 'access arguments' => array('access content'),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['admin/content/taxonomy/%'] = array( $items['admin/content/taxonomy/%taxonomy_vocabulary'] = array(
'title' => t('List terms'), 'title' => t('List terms'),
'page callback' => 'taxonomy_overview_terms', 'page callback' => 'taxonomy_overview_terms',
'page arguments' => array(3), 'page arguments' => array(3),
'access arguments' => array('administer taxonomy'), 'access arguments' => array('administer taxonomy'),
'map arguments' => array('taxonomy_get_vocabulary', 3),
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['admin/content/taxonomy/%/list'] = array( $items['admin/content/taxonomy/%taxonomy_vocabulary/list'] = array(
'title' => t('List'), 'title' => t('List'),
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10, 'weight' => -10,
); );
$items['admin/content/taxonomy/%/add/term'] = array( $items['admin/content/taxonomy/%taxonomy_vocabulary/add/term'] = array(
'title' => t('Add term'), 'title' => t('Add term'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('taxonomy_form_term', 3), 'page arguments' => array('taxonomy_form_term', 3),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'parent' => 'admin/content/taxonomy/%', 'parent' => 'admin/content/taxonomy/%taxonomy_vocabulary',
); );
return $items; return $items;
@ -334,7 +333,7 @@ function taxonomy_save_vocabulary(&$edit) {
* Constant indicating items were deleted. * Constant indicating items were deleted.
*/ */
function taxonomy_del_vocabulary($vid) { function taxonomy_del_vocabulary($vid) {
$vocabulary = (array) taxonomy_get_vocabulary($vid); $vocabulary = (array) taxonomy_vocabulary_load($vid);
db_query('DELETE FROM {vocabulary} WHERE vid = %d', $vid); db_query('DELETE FROM {vocabulary} WHERE vid = %d', $vid);
db_query('DELETE FROM {vocabulary_node_types} WHERE vid = %d', $vid); db_query('DELETE FROM {vocabulary_node_types} WHERE vid = %d', $vid);
@ -351,7 +350,7 @@ function taxonomy_del_vocabulary($vid) {
} }
function taxonomy_vocabulary_confirm_delete($vid) { function taxonomy_vocabulary_confirm_delete($vid) {
$vocabulary = taxonomy_get_vocabulary($vid); $vocabulary = taxonomy_vocabulary_load($vid);
$form['type'] = array('#type' => 'value', '#value' => 'vocabulary'); $form['type'] = array('#type' => 'value', '#value' => 'vocabulary');
$form['vid'] = array('#type' => 'value', '#value' => $vid); $form['vid'] = array('#type' => 'value', '#value' => $vid);
@ -593,7 +592,7 @@ function taxonomy_term_confirm_delete_submit($form_id, $form_values) {
* Generate a form element for selecting terms from a vocabulary. * Generate a form element for selecting terms from a vocabulary.
*/ */
function taxonomy_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') { function taxonomy_form($vid, $value = 0, $help = NULL, $name = 'taxonomy') {
$vocabulary = taxonomy_get_vocabulary($vid); $vocabulary = taxonomy_vocabulary_load($vid);
$help = ($help) ? $help : $vocabulary->help; $help = ($help) ? $help : $vocabulary->help;
if ($vocabulary->required) { if ($vocabulary->required) {
$blank = 0; $blank = 0;
@ -764,7 +763,7 @@ function taxonomy_node_validate(&$node) {
$terms = $node->taxonomy; $terms = $node->taxonomy;
if ($terms['tags']) { if ($terms['tags']) {
foreach ($terms['tags'] as $vid => $vid_value) { foreach ($terms['tags'] as $vid => $vid_value) {
$vocabulary = taxonomy_get_vocabulary($vid); $vocabulary = taxonomy_vocabulary_load($vid);
if (empty($vocabulary->tags)) { if (empty($vocabulary->tags)) {
// see form_get_error $key = implode('][', $element['#parents']); // see form_get_error $key = implode('][', $element['#parents']);
// on why this is the key // on why this is the key
@ -1109,7 +1108,7 @@ function taxonomy_get_term_by_name($name) {
* The vocabulary object with all of its metadata. * The vocabulary object with all of its metadata.
* Results are statically cached. * Results are statically cached.
*/ */
function taxonomy_get_vocabulary($vid) { function taxonomy_vocabulary_load($vid) {
static $vocabularies = array(); static $vocabularies = array();
if (!array_key_exists($vid, $vocabularies)) { if (!array_key_exists($vid, $vocabularies)) {
@ -1388,14 +1387,11 @@ function taxonomy_term_page($str_tids = '', $depth = 0, $op = 'page') {
/** /**
* Page to edit a vocabulary. * Page to edit a vocabulary.
*/ */
function taxonomy_admin_vocabulary_edit($vid = NULL) { function taxonomy_admin_vocabulary_edit($vocabulary) {
if ($_POST['op'] == t('Delete') || $_POST['confirm']) { if ($_POST['op'] == t('Delete') || $_POST['confirm']) {
return drupal_get_form('taxonomy_vocabulary_confirm_delete', $vid); return drupal_get_form('taxonomy_vocabulary_confirm_delete', $vocabulary->vid);
} }
if ($vocabulary = (array)taxonomy_get_vocabulary($vid)) { return drupal_get_form('taxonomy_form_vocabulary', (array)$vocabulary);
return drupal_get_form('taxonomy_form_vocabulary', $vocabulary);
}
return drupal_not_found();
} }
/** /**

View File

@ -35,18 +35,22 @@ function tracker_menu() {
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
'access callback' => 'user_is_logged_in', 'access callback' => 'user_is_logged_in',
); );
$items['tracker/%'] = array(
$items['tracker/%user_current'] = array(
'title' => t('My recent posts'), 'title' => t('My recent posts'),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
'access callback' => 'user_is_logged_in', 'access callback' => 'user_is_logged_in',
'access arguments' => array(1),
); );
$items['user/%/track'] = array(
$items['user/%user/track'] = array(
'title' => t('Track'), 'title' => t('Track'),
'page callback' => 'tracker_track_user', 'page callback' => 'tracker_track_user',
'access callback' => 'user_access',
'access arguments' => array('access content'), 'access arguments' => array('access content'),
'type' => MENU_LOCAL_TASK, 'type' => MENU_LOCAL_TASK,
); );
$items['user/%/track/posts'] = array( $items['user/%user/track/posts'] = array(
'title' => t('Track posts'), 'title' => t('Track posts'),
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
); );

View File

@ -730,11 +730,15 @@ function user_menu() {
); );
// Registration and login pages. // Registration and login pages.
$items['user/login'] = array( $items['user'] = array(
'title' => t('Log in'), 'title' => t('Log in'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('user_login'), 'page arguments' => array('user_login'),
'access callback' => 'user_is_anonymous', 'access callback' => 'user_is_anonymous',
);
$items['user/login'] = array(
'title' => t('Log in'),
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
); );
@ -857,7 +861,6 @@ function user_menu() {
'page callback' => 'user_admin', 'page callback' => 'user_admin',
'page arguments' => array('search'), 'page arguments' => array('search'),
'access arguments' => array('administer users'), 'access arguments' => array('administer users'),
'type' => MENU_NORMAL_ITEM,
); );
} }
@ -868,32 +871,22 @@ function user_menu() {
'weight' => 10, 'weight' => 10,
); );
$items['user'] = array( $items['user/%user_current'] = array(
'title' => t('My account'), 'title' => t('My account'),
'page callback' => 'user_view', 'page callback' => 'user_view',
'page arguments' => array(1), 'page arguments' => array(1),
'access callback' => 'user_view_access', 'access callback' => 'user_view_access',
'access arguments' => array(1), 'access arguments' => array(1),
'map callback' => 'user_load_self', 'parent' => '',
); );
$items['user/%'] = array( $items['user/%user/view'] = array(
'title' => t('My account'),
'page callback' => 'user_view',
'page arguments' => array(1),
'access callback' => 'user_view_access',
'access arguments' => array(1),
'map arguments' => array('user_load', 1),
'type' => MENU_CALLBACK,
);
$items['user/%/view'] = array(
'title' => t('View'), 'title' => t('View'),
'type' => MENU_DEFAULT_LOCAL_TASK, 'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10, 'weight' => -10,
); );
$items['user/%/delete'] = array( $items['user/%user/delete'] = array(
'title' => t('Delete'), 'title' => t('Delete'),
'page callback' => 'user_edit', 'page callback' => 'user_edit',
'access callback' => 'user_access', 'access callback' => 'user_access',
@ -901,7 +894,7 @@ function user_menu() {
'type' => MENU_CALLBACK, 'type' => MENU_CALLBACK,
); );
$items['user/%/edit'] = array( $items['user/%user/edit'] = array(
'title' => t('Edit'), 'title' => t('Edit'),
'page callback' => 'drupal_get_form', 'page callback' => 'drupal_get_form',
'page arguments' => array('user_edit'), 'page arguments' => array('user_edit'),
@ -913,7 +906,7 @@ function user_menu() {
$empty_account = new stdClass(); $empty_account = new stdClass();
if (($categories = _user_categories($empty_account)) && (count($categories) > 1)) { if (($categories = _user_categories($empty_account)) && (count($categories) > 1)) {
foreach ($categories as $key => $category) { foreach ($categories as $key => $category) {
$items['user/%/edit/'. $category['name']] = array( $items['user/%user/edit/'. $category['name']] = array(
'title' => $category['title'], 'title' => $category['title'],
'page arguments' => array('user_edit', 3), 'page arguments' => array('user_edit', 3),
'type' => $category['name'] == 'account' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, 'type' => $category['name'] == 'account' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
@ -928,6 +921,14 @@ function user_init() {
drupal_add_css(drupal_get_path('module', 'user') .'/user.css', 'module'); drupal_add_css(drupal_get_path('module', 'user') .'/user.css', 'module');
} }
function user_current_load($arg) {
return user_load($arg);
}
function user_current_to_arg() {
return $GLOBALS['user']->uid;
}
/** /**
* Accepts an user object, $account, or a DA name and returns an associative * Accepts an user object, $account, or a DA name and returns an associative
* array of modules and DA names. Called at external login. * array of modules and DA names. Called at external login.
@ -1588,6 +1589,7 @@ function user_edit_submit($form_id, $form_values) {
function user_view($account) { function user_view($account) {
global $user; global $user;
drupal_set_title(check_plain($account->name));
// Retrieve and merge all profile fields: // Retrieve and merge all profile fields:
$fields = array(); $fields = array();
foreach (module_list() as $module) { foreach (module_list() as $module) {