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) {
* Define the critical hooks that force modules to always be loaded.
*/
function bootstrap_hooks() {
return array('init', 'exit');
return array('boot', 'exit');
}
/**
......@@ -856,7 +856,7 @@ function _drupal_cache_init($phase) {
}
elseif (variable_get('cache', CACHE_DISABLED) == CACHE_NORMAL) {
require_once './includes/module.inc';
bootstrap_invoke_all('init');
bootstrap_invoke_all('boot');
drupal_page_cache_header($cache);
bootstrap_invoke_all('exit');
exit();
......
......@@ -2209,3 +2209,22 @@ function element_child($key) {
function element_children($element) {
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) {
drupal_set_message(t('Configuration saved.'));
// Changing the locale settings impacts the interface:
cache_clear_all('*', 'cache_menu', TRUE);
cache_clear_all('*', 'cache_page', TRUE);
return 'admin/settings/locale/language/overview';
......
This diff is collapsed.
......@@ -253,7 +253,6 @@ function module_enable($module_list) {
module_list(TRUE, FALSE);
// Force to regenerate the stored list of hook implementations.
module_implements('', FALSE, TRUE);
cache_clear_all('*', 'cache_menu', TRUE);
}
foreach ($invoke_modules as $module) {
......@@ -283,7 +282,6 @@ function module_disable($module_list) {
module_list(TRUE, FALSE);
// Force to regenerate the stored list of hook implementations.
module_implements('', FALSE, TRUE);
cache_clear_all('*', 'cache_menu', TRUE);
}
}
......
......@@ -145,16 +145,20 @@ function drupal_get_normal_path($path) {
* The component specified by $index, or FALSE if the specified component was
* not found.
*/
function arg($index) {
static $arguments, $q;
function arg($index = NULL, $path = NULL) {
static $arguments;
if (empty($arguments) || $q != $_GET['q']) {
$arguments = explode('/', $_GET['q']);
$q = $_GET['q'];
if (!isset($path)) {
$path = $_GET['q'];
}
if (isset($arguments[$index])) {
return $arguments[$index];
if (!isset($arguments[$path])) {
$arguments[$path] = explode('/', $path);
}
if (!isset($index)) {
return $arguments[$path];
}
if (isset($arguments[$path][$index])) {
return $arguments[$path][$index];
}
}
......
......@@ -533,6 +533,7 @@ function install_complete($profile) {
// Bootstrap newly installed Drupal, while preserving existing messages.
$messages = $_SESSION['messages'];
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
menu_rebuild();
$_SESSION['messages'] = $messages;
// Build final page.
......
......@@ -28,169 +28,162 @@ function aggregator_help($section) {
/**
* Implementation of hook_menu().
*/
function aggregator_menu($may_cache) {
$items = array();
$edit = user_access('administer news feeds');
$view = user_access('access news feeds');
if ($may_cache) {
$items[] = array('path' => 'admin/content/aggregator',
'title' => t('News aggregator'),
'description' => t("Configure which content your site aggregates from other sites, how often it polls them, and how they're categorized."),
'callback' => 'aggregator_admin_overview',
'access' => $edit);
$items[] = array('path' => 'admin/content/aggregator/add/feed',
'title' => t('Add feed'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_form_feed'),
'access' => $edit,
'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'admin/content/aggregator/add/category',
'title' => t('Add category'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_form_category'),
'access' => $edit,
'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'admin/content/aggregator/remove',
'title' => t('Remove items'),
'callback' => 'aggregator_admin_remove_feed',
'access' => $edit,
'type' => MENU_CALLBACK);
$items[] = array('path' => 'admin/content/aggregator/update',
'title' => t('Update items'),
'callback' => 'aggregator_admin_refresh_feed',
'access' => $edit,
'type' => MENU_CALLBACK);
$items[] = array('path' => 'admin/content/aggregator/list',
'title' => t('List'),
function aggregator_menu() {
$items['admin/content/aggregator'] = array(
'title' => t('News aggregator'),
'description' => t("Configure which content your site aggregates from other sites, how often it polls them, and how they're categorized."),
'page callback' => 'aggregator_admin_overview',
'access arguments' => array('administer news feeds'),
);
$items['admin/content/aggregator/add/feed'] = array(
'title' => t('Add feed'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_feed'),
'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK,
);
$items['admin/content/aggregator/add/category'] = array(
'title' => t('Add category'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_category'),
'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK,
);
$items['admin/content/aggregator/remove/%'] = array(
'title' => t('Remove items'),
'page callback' => 'aggregator_admin_remove_feed',
'page arguments' => array(4),
'map arguments' => array('aggregator_get_feed', 4),
'access arguments' => array('administer news feeds'),
'type' => MENU_CALLBACK,
);
$items['admin/content/aggregator/update/%'] = array(
'title' => t('Update items'),
'page callback' => 'aggregator_admin_refresh_feed',
'page arguments' => array(4),
'map arguments' => array('aggregator_get_feed', 4),
'access arguments' => array('administer news feeds'),
'type' => MENU_CALLBACK,
);
$items['admin/content/aggregator/list'] = array(
'title' => t('List'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/content/aggregator/settings'] = array(
'title' => t('Settings'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_admin_settings'),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
'access arguments' => array('administer news feeds'),
);
$items['aggregator'] = array(
'title' => t('News aggregator'),
'page callback' => 'aggregator_page_last',
'access arguments' => array('access news feeds'),
'weight' => 5,
);
$items['aggregator/sources'] = array(
'title' => t('Sources'),
'page callback' => 'aggregator_page_sources',
'access arguments' => array('access news feeds'));
$items['aggregator/categories'] = array(
'title' => t('Categories'),
'page callback' => 'aggregator_page_categories',
'access arguments' => array('access news feeds'),
'type' => MENU_ITEM_GROUPING,
);
$items['aggregator/rss'] = array(
'title' => t('RSS feed'),
'page callback' => 'aggregator_page_rss',
'access arguments' => array('access news feeds'),
'type' => MENU_CALLBACK,
);
$items['aggregator/opml'] = array(
'title' => t('OPML feed'),
'page callback' => 'aggregator_page_opml',
'access arguments' => array('access news feeds'),
'type' => MENU_CALLBACK,
);
$result = db_query('SELECT title, cid FROM {aggregator_category} ORDER BY title');
while ($category = db_fetch_array($result)) {
$path = 'aggregator/categories/'. $category['cid'];
$items[$path] = array(
'title' => $category['title'],
'page callback' => 'aggregator_page_category',
'access arguments' => array('access news feeds'),
);
$items[$path .'/view'] = array(
'title' => t('View'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10);
$items[] = array('path' => 'admin/content/aggregator/settings',
'title' => t('Settings'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_admin_settings'),
'weight' => -10,
);
$items[$path .'/categorize'] = array(
'title' => t('Categorize'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_page_category'),
'access arguments' => array('administer news feeds', 2),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
'access' => $edit);
$items[] = array('path' => 'aggregator',
'title' => t('News aggregator'),
'callback' => 'aggregator_page_last',
'access' => $view,
'weight' => 5);
$items[] = array('path' => 'aggregator/sources',
'title' => t('Sources'),
'callback' => 'aggregator_page_sources',
'access' => $view);
$items[] = array('path' => 'aggregator/categories',
'title' => t('Categories'),
'callback' => 'aggregator_page_categories',
'access' => $view,
'type' => MENU_ITEM_GROUPING);
$items[] = array('path' => 'aggregator/rss',
'title' => t('RSS feed'),
'callback' => 'aggregator_page_rss',
'access' => $view,
'type' => MENU_CALLBACK);
$items[] = array('path' => 'aggregator/opml',
'title' => t('OPML feed'),
'callback' => 'aggregator_page_opml',
'access' => $view,
'type' => MENU_CALLBACK);
$result = db_query('SELECT title, cid FROM {aggregator_category} ORDER BY title');
while ($category = db_fetch_array($result)) {
$items[] = array('path' => 'aggregator/categories/'. $category['cid'],
'title' => $category['title'],
'callback' => 'aggregator_page_category',
'access' => $view);
}
}
else {
// Add the CSS for this module
// We put this in !$may_cache so it's only added once per request
drupal_add_css(drupal_get_path('module', 'aggregator') .'/aggregator.css');
if (arg(0) == 'aggregator' && is_numeric(arg(2))) {
if (arg(1) == 'sources') {
$feed = aggregator_get_feed(arg(2));
if ($feed) {
$items[] = array('path' => 'aggregator/sources/'. $feed['fid'],
'title' => $feed['title'],
'callback' => 'aggregator_page_source',
'access' => $view,
'type' => MENU_CALLBACK);
$items[] = array('path' => 'aggregator/sources/'. $feed['fid'] .'/view',
'title' => t('View'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10);
$items[] = array('path' => 'aggregator/sources/'. $feed['fid'] .'/categorize',
'title' => t('Categorize'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_page_source'),
'access' => $edit,
'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'aggregator/sources/'. $feed['fid'] .'/configure',
'title' => t('Configure'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_form_feed', $feed),
'access' => $edit,
'type' => MENU_LOCAL_TASK,
'weight' => 1);
}
}
else if (arg(1) == 'categories') {
$category = aggregator_get_category(arg(2));
if ($category) {
$items[] = array('path' => 'aggregator/categories/'. $category['cid'] .'/view',
'title' => t('View'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10);
$items[] = array('path' => 'aggregator/categories/'. $category['cid'] .'/categorize',
'title' => t('Categorize'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_page_category'),
'access' => $edit,
'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'aggregator/categories/'. $category['cid'] .'/configure',
'title' => t('Configure'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_form_category', $category),
'access' => $edit,
'type' => MENU_LOCAL_TASK,
'weight' => 1);
}
}
}
else if (arg(2) == 'aggregator' && is_numeric(arg(5))) {
if (arg(4) == 'feed') {
$feed = aggregator_get_feed(arg(5));
if ($feed) {
$items[] = array('path' => 'admin/content/aggregator/edit/feed/'. $feed['fid'],
'title' => t('Edit feed'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_form_feed', $feed),
'access' => $edit,
'type' => MENU_CALLBACK);
}
}
else {
$category = aggregator_get_category(arg(5));
if ($category) {
$items[] = array('path' => 'admin/content/aggregator/edit/category/'. $category['cid'],
'title' => t('Edit category'),
'callback' => 'drupal_get_form',
'callback arguments' => array('aggregator_form_category', $category),
'access' => $edit,
'type' => MENU_CALLBACK);
}
}
}
);
$items[$path .'/configure'] = array(
'title' => t('Configure'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_category', 2),
'access arguments' => array('administer news feeds', 2),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
}
$items['aggregator/sources/%'] = array(
'page callback' => 'aggregator_page_source',
'map arguments' => array('aggregator_get_feed', 2),
'type' => MENU_CALLBACK,
);
$items['aggregator/sources/%/view'] = array(
'title' => t('View'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['aggregator/sources/%/categorize'] = array(
'title' => t('Categorize'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_page_source'),
'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK,
);
$items['aggregator/sources/%/configure'] = array(
'title' => t('Configure'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_feed', 2),
'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items['admin/content/aggregator/edit/feed/%'] = array(
'title' => t('Edit feed'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_feed', 5),
'access arguments' => array('administer news feeds'),
'map arguments' => array('aggregator_get_feed', 5),
'type' => MENU_CALLBACK,
);
$items['admin/content/aggregator/edit/category/%'] = array(
'title' => t('Edit category'),
'page callback' => 'drupal_get_form',
'page arguments' => array('aggregator_form_category', 5),
'access arguments' => array('administer news feeds'),
'map arguments' => array('aggregator_get_category', 5),
'type' => MENU_CALLBACK,
);
return $items;
}
function aggregator_init() {
drupal_add_css(drupal_get_path('module', 'aggregator') .'/aggregator.css');
}
function aggregator_admin_settings() {
$items = array(0 => t('none')) + drupal_map_assoc(array(3, 5, 10, 15, 20, 25), '_aggregator_items');
$period = drupal_map_assoc(array(3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800, 1209600, 2419200, 4838400, 9676800), 'format_interval');
......@@ -1005,7 +998,7 @@ function aggregator_view() {
* Menu callback; removes all items from a feed, then redirects to the overview page.
*/
function aggregator_admin_remove_feed($feed) {
aggregator_remove(aggregator_get_feed($feed));
aggregator_remove($feed);
drupal_goto('admin/content/aggregator');
}
......@@ -1013,7 +1006,7 @@ function aggregator_admin_remove_feed($feed) {
* Menu callback; refreshes a feed, then redirects to the overview page.
*/
function aggregator_admin_refresh_feed($feed) {
aggregator_refresh(aggregator_get_feed($feed));
aggregator_refresh($feed);
drupal_goto('admin/content/aggregator');
}
......@@ -1038,6 +1031,7 @@ function aggregator_page_last() {
*/
function aggregator_page_source() {
$feed = db_fetch_object(db_query('SELECT * FROM {aggregator_feed} WHERE fid = %d', arg(2)));
drupal_set_title($feed->title);
$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);
......
......@@ -58,48 +58,43 @@ function block_perm() {
/**
* Implementation of hook_menu().
*/
function block_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'admin/build/block',
'title' => t('Blocks'),
'access' => user_access('administer blocks'),
'description' => t('Configure what block content appears in your site\'s sidebars and other regions.'),
'callback' => 'drupal_get_form',
'callback arguments' => array('block_admin_display'));
$items[] = array('path' => 'admin/build/block/list', 'title' => t('List'),
'type' => MENU_DEFAULT_LOCAL_TASK, 'weight' => -10);
$items[] = array('path' => 'admin/build/block/configure', 'title' => t('Configure block'),
'access' => user_access('administer blocks'),
'callback' => 'drupal_get_form',
'callback arguments' => array('block_admin_configure'),
'type' => MENU_CALLBACK);
$items[] = array('path' => 'admin/build/block/delete', 'title' => t('Delete block'),
'access' => user_access('administer blocks'),
'callback' => 'drupal_get_form',
'callback arguments' => array('block_box_delete'),
'type' => MENU_CALLBACK);
$items[] = array('path' => 'admin/build/block/add', 'title' => t('Add block'),
'access' => user_access('administer blocks'),
'callback' => 'drupal_get_form',
'callback arguments' => array('block_add_block_form'),
'type' => MENU_LOCAL_TASK);
$default = variable_get('theme_default', 'garland');
foreach (list_themes() as $key => $theme) {
$items[] = array(
'path' => 'admin/build/block/list/'. $key,
'title' => t('!key settings', array('!key' => $key)),
'callback' => 'drupal_get_form',
'callback arguments' => array('block_admin_display', $key),
'access' => user_access('administer blocks'),
'type' => $key == $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'weight' => $key == $default ? -10 : 0,
);
}
function block_menu() {
$items['admin/build/block'] = array(
'title' => t('Blocks'),
'description' => t('Configure what block content appears in your site\'s sidebars and other regions.'),
'page callback' => 'drupal_get_form',
'page arguments' => array('block_admin_display'),
'access arguments' => array('administer blocks'),
);
$items['admin/build/block/list'] = array(
'title' => t('List'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/build/block/configure'] = array(
'title' => t('Configure block'),
'page arguments' => array('block_admin_configure'),
'type' => MENU_CALLBACK,
);
$items['admin/build/block/delete'] = array(
'title' => t('Delete block'),
'page arguments' => array('block_box_delete'),
'type' => MENU_CALLBACK,
);
$items['admin/build/block/add'] = array(
'title' => t('Add block'),
'page arguments' => array('block_add_block_form'),
'type' => MENU_LOCAL_TASK,
);
$default = variable_get('theme_default', 'garland');
foreach (list_themes() as $key => $theme) {
$items['admin/build/block/list/'. $key] = array(
'title' => t('!key settings', array('!key' => $key)),
'page arguments' => array('block_admin_display', $key),
'type' => $key== $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'weight' => $key == $default ? -10 : 0,
);
}
return $items;
}
......
......@@ -249,19 +249,18 @@ function blog_link($type, $node = NULL, $teaser = FALSE) {
/**
* Implementation of hook_menu().
*/
function blog_menu($may_cache) {
global $user;
$items = array();
if ($may_cache) {
$items[] = array('path' => 'blog', 'title' => t('Blogs'),
'callback' => 'blog_page',
'access' => user_access('access content'),
'type' => MENU_SUGGESTED_ITEM);
$items[] = array('path' => 'blog/'. $user->uid, 'title' => t('My blog'),
'access' => user_access('edit own blog'),
'type' => MENU_DYNAMIC_ITEM);
}
function blog_menu() {
$items['blog'] = array(
'title' => t('Blogs'),
'page callback' => 'blog_page',
'access arguments' => array('access content'),
'type' => MENU_SUGGESTED_ITEM,
);
$items['blog/%'] = array(
'title' => t('My blog'),
'page arguments' => array(1),
'access arguments' => array('edit own blog'),
);
return $items;
}
......
......@@ -551,46 +551,32 @@ function blogapi_admin_settings() {
return system_settings_form($form);
}
function blogapi_menu($may_cache) {
$items = array();
function blogapi_menu() {
$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;