Commit 03752e35 authored by Dries's avatar Dries

- Patch #34755 by chx et al: faster menu system. HEAD is temporary broken and...

- Patch #34755 by chx et al: faster menu system.  HEAD is temporary broken and there is no upgrade path yet.
parent d407de4c
...@@ -550,7 +550,7 @@ function drupal_page_cache_header($cache) { ...@@ -550,7 +550,7 @@ function drupal_page_cache_header($cache) {
* Define the critical hooks that force modules to always be loaded. * Define the critical hooks that force modules to always be loaded.
*/ */
function bootstrap_hooks() { function bootstrap_hooks() {
return array('init', 'exit'); return array('boot', 'exit');
} }
/** /**
...@@ -856,7 +856,7 @@ function _drupal_cache_init($phase) { ...@@ -856,7 +856,7 @@ function _drupal_cache_init($phase) {
} }
elseif (variable_get('cache', CACHE_DISABLED) == CACHE_NORMAL) { elseif (variable_get('cache', CACHE_DISABLED) == CACHE_NORMAL) {
require_once './includes/module.inc'; require_once './includes/module.inc';
bootstrap_invoke_all('init'); bootstrap_invoke_all('boot');
drupal_page_cache_header($cache); drupal_page_cache_header($cache);
bootstrap_invoke_all('exit'); bootstrap_invoke_all('exit');
exit(); exit();
......
...@@ -2209,3 +2209,22 @@ function element_child($key) { ...@@ -2209,3 +2209,22 @@ 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;
}
...@@ -119,7 +119,6 @@ function _locale_admin_manage_screen_submit($form_id, $form_values) { ...@@ -119,7 +119,6 @@ function _locale_admin_manage_screen_submit($form_id, $form_values) {
drupal_set_message(t('Configuration saved.')); drupal_set_message(t('Configuration saved.'));
// Changing the locale settings impacts the interface: // Changing the locale settings impacts the interface:
cache_clear_all('*', 'cache_menu', TRUE);
cache_clear_all('*', 'cache_page', TRUE); cache_clear_all('*', 'cache_page', TRUE);
return 'admin/settings/locale/language/overview'; return 'admin/settings/locale/language/overview';
......
This diff is collapsed.
...@@ -253,7 +253,6 @@ function module_enable($module_list) { ...@@ -253,7 +253,6 @@ function module_enable($module_list) {
module_list(TRUE, FALSE); module_list(TRUE, FALSE);
// Force to regenerate the stored list of hook implementations. // Force to regenerate the stored list of hook implementations.
module_implements('', FALSE, TRUE); module_implements('', FALSE, TRUE);
cache_clear_all('*', 'cache_menu', TRUE);
} }
foreach ($invoke_modules as $module) { foreach ($invoke_modules as $module) {
...@@ -283,7 +282,6 @@ function module_disable($module_list) { ...@@ -283,7 +282,6 @@ function module_disable($module_list) {
module_list(TRUE, FALSE); module_list(TRUE, FALSE);
// Force to regenerate the stored list of hook implementations. // Force to regenerate the stored list of hook implementations.
module_implements('', FALSE, TRUE); module_implements('', FALSE, TRUE);
cache_clear_all('*', 'cache_menu', TRUE);
} }
} }
......
...@@ -145,16 +145,20 @@ function drupal_get_normal_path($path) { ...@@ -145,16 +145,20 @@ function drupal_get_normal_path($path) {
* The component specified by $index, or FALSE if the specified component was * The component specified by $index, or FALSE if the specified component was
* not found. * not found.
*/ */
function arg($index) { function arg($index = NULL, $path = NULL) {
static $arguments, $q; static $arguments;
if (empty($arguments) || $q != $_GET['q']) { if (!isset($path)) {
$arguments = explode('/', $_GET['q']); $path = $_GET['q'];
$q = $_GET['q'];
} }
if (!isset($arguments[$path])) {
if (isset($arguments[$index])) { $arguments[$path] = explode('/', $path);
return $arguments[$index]; }
if (!isset($index)) {
return $arguments[$path];
}
if (isset($arguments[$path][$index])) {
return $arguments[$path][$index];
} }
} }
......
...@@ -533,6 +533,7 @@ function install_complete($profile) { ...@@ -533,6 +533,7 @@ function install_complete($profile) {
// Bootstrap newly installed Drupal, while preserving existing messages. // Bootstrap newly installed Drupal, while preserving existing messages.
$messages = $_SESSION['messages']; $messages = $_SESSION['messages'];
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
menu_rebuild();
$_SESSION['messages'] = $messages; $_SESSION['messages'] = $messages;
// Build final page. // Build final page.
......
This diff is collapsed.
...@@ -58,48 +58,43 @@ function block_perm() { ...@@ -58,48 +58,43 @@ function block_perm() {
/** /**
* Implementation of hook_menu(). * Implementation of hook_menu().
*/ */
function block_menu($may_cache) { function block_menu() {
$items = array(); $items['admin/build/block'] = array(
'title' => t('Blocks'),
if ($may_cache) { 'description' => t('Configure what block content appears in your site\'s sidebars and other regions.'),
$items[] = array( 'page callback' => 'drupal_get_form',
'path' => 'admin/build/block', 'page arguments' => array('block_admin_display'),
'title' => t('Blocks'), 'access arguments' => array('administer blocks'),
'access' => user_access('administer blocks'), );
'description' => t('Configure what block content appears in your site\'s sidebars and other regions.'), $items['admin/build/block/list'] = array(
'callback' => 'drupal_get_form', 'title' => t('List'),
'callback arguments' => array('block_admin_display')); 'type' => MENU_DEFAULT_LOCAL_TASK,
$items[] = array('path' => 'admin/build/block/list', 'title' => t('List'), 'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10); );
$items[] = array('path' => 'admin/build/block/configure', 'title' => t('Configure block'), $items['admin/build/block/configure'] = array(
'access' => user_access('administer blocks'), 'title' => t('Configure block'),
'callback' => 'drupal_get_form', 'page arguments' => array('block_admin_configure'),
'callback arguments' => array('block_admin_configure'), 'type' => MENU_CALLBACK,
'type' => MENU_CALLBACK); );
$items[] = array('path' => 'admin/build/block/delete', 'title' => t('Delete block'), $items['admin/build/block/delete'] = array(
'access' => user_access('administer blocks'), 'title' => t('Delete block'),
'callback' => 'drupal_get_form', 'page arguments' => array('block_box_delete'),
'callback arguments' => array('block_box_delete'), 'type' => MENU_CALLBACK,
'type' => MENU_CALLBACK); );
$items[] = array('path' => 'admin/build/block/add', 'title' => t('Add block'), $items['admin/build/block/add'] = array(
'access' => user_access('administer blocks'), 'title' => t('Add block'),
'callback' => 'drupal_get_form', 'page arguments' => array('block_add_block_form'),
'callback arguments' => array('block_add_block_form'), 'type' => MENU_LOCAL_TASK,
'type' => MENU_LOCAL_TASK); );
$default = variable_get('theme_default', 'garland'); $default = variable_get('theme_default', 'garland');
foreach (list_themes() as $key => $theme) { foreach (list_themes() as $key => $theme) {
$items[] = array( $items['admin/build/block/list/'. $key] = array(
'path' => 'admin/build/block/list/'. $key, 'title' => t('!key settings', array('!key' => $key)),
'title' => t('!key settings', array('!key' => $key)), 'page arguments' => array('block_admin_display', $key),
'callback' => 'drupal_get_form', 'type' => $key== $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'callback arguments' => array('block_admin_display', $key), 'weight' => $key == $default ? -10 : 0,
'access' => user_access('administer blocks'), );
'type' => $key == $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'weight' => $key == $default ? -10 : 0,
);
}
} }
return $items; return $items;
} }
......
...@@ -249,19 +249,18 @@ function blog_link($type, $node = NULL, $teaser = FALSE) { ...@@ -249,19 +249,18 @@ function blog_link($type, $node = NULL, $teaser = FALSE) {
/** /**
* Implementation of hook_menu(). * Implementation of hook_menu().
*/ */
function blog_menu($may_cache) { function blog_menu() {
global $user; $items['blog'] = array(
$items = array(); 'title' => t('Blogs'),
'page callback' => 'blog_page',
if ($may_cache) { 'access arguments' => array('access content'),
$items[] = array('path' => 'blog', 'title' => t('Blogs'), 'type' => MENU_SUGGESTED_ITEM,
'callback' => 'blog_page', );
'access' => user_access('access content'), $items['blog/%'] = array(
'type' => MENU_SUGGESTED_ITEM); 'title' => t('My blog'),
$items[] = array('path' => 'blog/'. $user->uid, 'title' => t('My blog'), 'page arguments' => array(1),
'access' => user_access('edit own blog'), 'access arguments' => array('edit own blog'),
'type' => MENU_DYNAMIC_ITEM); );
}
return $items; return $items;
} }
......
...@@ -551,46 +551,32 @@ function blogapi_admin_settings() { ...@@ -551,46 +551,32 @@ function blogapi_admin_settings() {
return system_settings_form($form); return system_settings_form($form);
} }
function blogapi_menu($may_cache) { function blogapi_menu() {
$items = array(); $items['blogapi/rsd'] = array(
'title' => t('RSD'),
'page callback' => 'blogapi_rsd',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['admin/settings/blogapi'] = array(
'title' => t('Blog APIs'),
'description' => t('Configure which content types and engines external blog clients can use.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('blogapi_admin_settings'),
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function blogapi_init() {
if (drupal_is_front_page()) { if (drupal_is_front_page()) {
drupal_add_link(array('rel' => 'EditURI', drupal_add_link(array('rel' => 'EditURI',
'type' => 'application/rsd+xml', 'type' => 'application/rsd+xml',
'title' => t('RSD'), 'title' => t('RSD'),
'href' => url('blogapi/rsd', NULL, NULL, TRUE))); 'href' => url('blogapi/rsd', NULL, NULL, TRUE)));
} }
if ($may_cache) {
$items[] = array(
'path' => 'blogapi',
'title' => t('RSD'),
'callback' => 'blogapi_blogapi',
'access' => user_access('access content'),
'type' => MENU_CALLBACK);
$items[] = array(
'path' => 'admin/settings/blogapi',
'title' => t('Blog APIs'),
'description' => t('Configure which content types and engines external blog clients can use.'),
'callback' => 'drupal_get_form',
'callback arguments' => array('blogapi_admin_settings'),
'access' => user_access('administer site configuration'),
'type' => MENU_NORMAL_ITEM
);
}
return $items;
}
function blogapi_blogapi() {
switch (arg(1)) {
case 'rsd':
blogapi_rsd();
break;
default:
drupal_not_found();
break;
}
} }
function blogapi_rsd() { function blogapi_rsd() {
......
...@@ -85,65 +85,58 @@ function book_link($type, $node = NULL, $teaser = FALSE) { ...@@ -85,65 +85,58 @@ function book_link($type, $node = NULL, $teaser = FALSE) {
/** /**
* Implementation of hook_menu(). * Implementation of hook_menu().
*/ */
function book_menu($may_cache) { function book_menu() {
$items = array(); $items['admin/content/book'] = array(
'title' => t('Books'),
if ($may_cache) { 'description' => t("Manage site's books and orphaned book pages."),
$items[] = array( 'page callback' => 'book_admin',
'path' => 'admin/content/book', 'access arguments' => array('administer nodes'),
'title' => t('Books'), );
'description' => t("Manage site's books and orphaned book pages."), $items['admin/content/book/list'] = array(
'callback' => 'book_admin', 'title' => t('List'),
'access' => user_access('administer nodes')); 'type' => MENU_DEFAULT_LOCAL_TASK,
$items[] = array( );
'path' => 'admin/content/book/list', $items['admin/content/book/orphan'] = array(
'title' => t('List'), 'title' => t('Orphan pages'),
'type' => MENU_DEFAULT_LOCAL_TASK); 'page callback' => 'drupal_get_form',
$items[] = array( 'page arguments' => array('book_admin_orphan'),
'path' => 'admin/content/book/orphan', 'type' => MENU_LOCAL_TASK,
'title' => t('Orphan pages'), 'weight' => 8,
'callback' => 'drupal_get_form', );
'callback arguments' => array('book_admin_orphan'), $items['book'] = array(
'type' => MENU_LOCAL_TASK, 'title' => t('Books'),
'weight' => 8); 'page callback' => 'book_render',
$items[] = array( 'access arguments' => array('access content'),
'path' => 'book', 'type' => MENU_SUGGESTED_ITEM,
'title' => t('Books'), );
'callback' => 'book_render', $items['book/export/%/%'] = array(
'access' => user_access('access content'), 'page callback' => 'book_export',
'type' => MENU_SUGGESTED_ITEM); 'page arguments' => array(2, 3),
$items[] = array( 'type' => MENU_CALLBACK,
'path' => 'book/export', );
'callback' => 'book_export', $items['node/%/outline'] = array(
'access' => user_access('access content'), 'title' => t('Outline'),
'type' => MENU_CALLBACK); 'page callback' => 'drupal_get_form',
} 'page arguments' => array('book_outline', 1),
else { 'access callback' => '_book_outline_access',
// Add the CSS for this module 'access arguments' => array(1),
// We put this in !$may_cache so it's only added once per request 'map arguments' => array('node_load', 1),
drupal_add_css(drupal_get_path('module', 'book') .'/book.css'); 'type' => MENU_LOCAL_TASK,
'weight' => 2,
// To avoid SQL overhead, check whether we are on a node page and whether the );
// user is allowed to outline posts in books.
if (arg(0) == 'node' && is_numeric(arg(1)) && user_access('outline posts in books')) {
// Only add the outline-tab for non-book pages:
$result = db_query(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.nid = %d AND n.type != 'book'"), arg(1));
if (db_num_rows($result) > 0) {
$items[] = array(
'path' => 'node/'. arg(1) .'/outline',
'title' => t('Outline'),
'callback' => 'drupal_get_form',
'callback arguments' => array('book_outline', arg(1)),
'access' => user_access('outline posts in books'),
'type' => MENU_LOCAL_TASK,
'weight' => 2);
}
}
}
return $items; return $items;
} }
function _book_outline_access($node) {
// Only add the outline-tab for non-book pages:
return user_access('outline posts in books') && $node && ($node->type != 'book');
}
function book_init() {
drupal_add_css(drupal_get_path('module', 'book') .'/book.css');
}
/** /**
* Implementation of hook_block(). * Implementation of hook_block().
* *
...@@ -256,9 +249,7 @@ function book_form(&$node) { ...@@ -256,9 +249,7 @@ function book_form(&$node) {
* Implementation of function book_outline() * Implementation of function book_outline()
* Handles all book outline operations. * Handles all book outline operations.
*/ */
function book_outline($nid) { function book_outline($node) {
$node = node_load($nid);
$form['parent'] = array('#type' => 'select', $form['parent'] = array('#type' => 'select',
'#title' => t('Parent'), '#title' => t('Parent'),
'#default_value' => $node->parent, '#default_value' => $node->parent,
...@@ -637,7 +628,7 @@ function book_render() { ...@@ -637,7 +628,7 @@ function book_render() {
* - an integer representing the node id (nid) of the node to export * - an integer representing the node id (nid) of the node to export
* *
*/ */
function book_export($type = 'html', $nid = 0) { function book_export($type, $nid) {
$type = drupal_strtolower($type); $type = drupal_strtolower($type);
$node_result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d'), $nid); $node_result = db_query(db_rewrite_sql('SELECT n.nid, n.title, b.parent FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE n.nid = %d'), $nid);
if (db_num_rows($node_result) > 0) { if (db_num_rows($node_result) > 0) {
......
...@@ -140,70 +140,77 @@ function comment_help($section) { ...@@ -140,70 +140,77 @@ function comment_help($section) {
} }
} }
function _comment_view_access($node, $cid) {
return $node && $cid;
}
/** /**
* Implementation of hook_menu(). * Implementation of hook_menu().
*/ */
function comment_menu($may_cache) { function comment_menu() {
$items = array(); $items['admin/content/comment'] = array(
'title' => t('Comments'),
'description' => t('List and edit site comments and the comment moderation queue.'),
'page callback' => 'comment_admin',
'access arguments' => array('administer comments'),
);
if ($may_cache) { // Tabs:
$access = user_access('administer comments'); $items['admin/content/comment/list'] = array(
$items[] = array( 'title' => t('List'),
'path' => 'admin/content/comment', 'type' => MENU_DEFAULT_LOCAL_TASK,
'title' => t('Comments'), 'weight' => -10,
'description' => t('List and edit site comments and the comment moderation queue.'), );
'callback' => 'comment_admin',
'access' => $access
);
// Tabs: // Subtabs:
$items[] = array('path' => 'admin/content/comment/list', 'title' => t('List'), $items['admin/content/comment/list/new'] = array(
'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10); 'title' => t('Published comments'),
'type' => MENU_DEFAULT_LOCAL_TASK,
// Subtabs: 'weight' => -10,
$items[] = array('path' => 'admin/content/comment/list/new', 'title' => t('Published comments'), );
'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10); $items['admin/content/comment/list/approval'] = array(
$items[] = array('path' => 'admin/content/comment/list/approval', 'title' => t('Approval queue'), 'title' => t('Approval queue'),
'callback' => 'comment_admin', 'page arguments' => array('approval'),
'callback arguments' => array('approval'), 'type' => MENU_LOCAL_TASK,
'access' => $access, );
'type' => MENU_LOCAL_TASK);
$items['admin/content/comment/settings'] = array(
$items[] = array( 'title' => t('Settings'),
'path' => 'admin/content/comment/settings', 'page callback' => 'drupal_get_form',
'title' => t('Settings'), 'page arguments' => array('comment_admin_settings'),
'callback' => 'drupal_get_form', 'weight' => 10,
'callback arguments' => array('comment_admin_settings'), 'type' => MENU_LOCAL_TASK,
'access' => $access, );
'weight' => 10,
'type' => MENU_LOCAL_TASK); $items['comment/delete'] = array(
'title' => t('Delete comment'),
$items[] = array('path' => 'comment/delete', 'title' => t('Delete comment'), 'page callback' => 'comment_delete',
'callback' => 'comment_delete', 'access' => $access, 'type' => MENU_CALLBACK); 'access arguments' => array('administer comments'),
'type' => MENU_CALLBACK,
$access = user_access('post comments'); );
$items[] = array('path' => 'comment/edit', 'title' => t('Edit comment'),
'callback' => 'comment_edit', $items['comment/edit'] = array(
'access' => $access, 'type' => MENU_CALLBACK); 'title' => t('Edit comment'),
} 'page callback' => 'comment_edit',
else { 'access arguments' => array('post comments'),
if (arg(0) == 'comment' && arg(1) == 'reply' && is_numeric(arg(2))) { 'type' => MENU_CALLBACK,
$node = node_load(arg(2)); );
if ($node->nid) { $items['comment/reply'] = array(
$items[] = array('path' => 'comment/reply', 'title' => t('Reply to comment'), 'title' => t('Reply to comment'),
'callback' => 'comment_reply', 'access' => node_access('view', $node), 'type' => MENU_CALLBACK); 'page callback' => 'comment_reply',
} 'access callback' => 'node_access',
} 'access arguments' => array('view', 2),
if ((arg(0) == 'node') && is_numeric(arg(1)) && is_numeric(arg(2))) { 'map arguments' => array('node_load', 2),
$items[] = array( 'type' => MENU_CALLBACK,
'path' => ('node/'. arg(1) .'/'. arg(2)), );
'title' => t('View'), $items['node/%/%'] = array(
'callback' => 'node_page_view', 'title' => t('View'),
'callback arguments' => array(node_load(arg(1)), arg(2)), 'page callback' => 'node_page_view',
'type' => MENU_CALLBACK, 'page arguments' => array(1, 2),
); 'access callback' => '_comment_view_access',
} 'access arguments' => array(1, 2),
} 'type' => MENU_CALLBACK,
);
return $items; return $items;
} }
...@@ -1980,25 +1987,6 @@ function comment_invoke_comment(&$comment, $op) { ...@@ -1980,25 +1987,6 @@ function comment_invoke_comment(&$comment, $op) {
return $return; return $return;
} }
/**
* Generate vancode.
*