Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.893 diff -u -p -r1.893 common.inc --- includes/common.inc 7 May 2009 15:29:07 -0000 1.893 +++ includes/common.inc 8 May 2009 14:50:46 -0000 @@ -1873,6 +1873,7 @@ function drupal_page_footer() { module_implements(MODULE_IMPLEMENTS_WRITE_CACHE); _registry_check_code(REGISTRY_WRITE_LOOKUP_CACHE); + drupal_cache_system_paths(); } /** Index: includes/path.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/path.inc,v retrieving revision 1.35 diff -u -p -r1.35 path.inc --- includes/path.inc 7 May 2009 15:49:57 -0000 1.35 +++ includes/path.inc 8 May 2009 14:50:46 -0000 @@ -49,6 +49,8 @@ function drupal_lookup_path($action, $pa $map = &drupal_static(__FUNCTION__, array()); $no_src = &drupal_static(__FUNCTION__ . ':no_src', array()); $count = &drupal_static(__FUNCTION__ . ':count'); + $system_paths = &drupal_static(__FUNCTION__ . ':system_paths'); + $no_aliases = &drupal_static(__FUNCTION__ . ':no_alias', array()); $path_language = $path_language ? $path_language : $language->language; @@ -61,19 +63,47 @@ function drupal_lookup_path($action, $pa $map = array(); $no_src = array(); $count = NULL; + $system_paths = array(); + $no_aliases = array(); } elseif ($count > 0 && $path != '') { if ($action == 'alias') { + // During the first call to drupal_lookup_path() per language, load the + // expected system paths for the page from cache. + if (!isset($map[$path_language])) { + $map[$path_language] = array(); + // Load system paths from cache. + $cid = 'path:system:' . current_path(); + if ($cache = cache_get($cid, 'cache_path')) { + $system_paths = $cache->data; + // Now fetch the aliases corresponding to these system paths. + // We order by ASC and overwrite array keys to ensure the correct + // alias is used when there are multiple aliases per path. + $result = db_query("SELECT src, dst FROM {url_alias} WHERE src IN(:system) AND language IN(:language, '') ORDER BY language ASC", array( + ':system' => $system_paths, + ':language' => $path_language)); + foreach ($result as $record) { + $map[$path_language][$record->src] = $record->dst; + } + // Keep a record of paths with no alias to avoid querying twice. + $no_aliases[$path_language] = array_flip(array_diff_key($system_paths, array_keys($map[$path_language]))); + } + } + // If the alias has already been loaded, return it. if (isset($map[$path_language][$path])) { return $map[$path_language][$path]; } - // Get the most fitting result falling back with alias without language - $alias = db_query("SELECT dst FROM {url_alias} WHERE src = :src AND language IN(:language, '') ORDER BY language DESC", array( - ':src' => $path, - ':language' => $path_language)) - ->fetchField(); - $map[$path_language][$path] = $alias; - return $alias; + // For system paths which were not cached, query aliases individually. + // individually. + else if (!isset($no_aliases[$path_language][$path])) { + // Get the most fitting result falling back with alias without language + $alias = db_query("SELECT dst FROM {url_alias} WHERE src = :src AND language IN(:language, '') ORDER BY language DESC", array( + ':src' => $path, + ':language' => $path_language)) + ->fetchField(); + $map[$path_language][$path] = $alias; + return $alias; + } } // Check $no_src for this $path in case we've already determined that there // isn't a path that has this alias @@ -103,6 +133,33 @@ function drupal_lookup_path($action, $pa } /** + * Cache system paths for a page. + * + * Cache an array of the system paths available on each page. We assume that + * expect that aiases will be needed for the majority of these paths during + * subsequent requests, and load them in a single query during + * drupal_lookup_path(). + */ +function drupal_cache_system_paths() { + // Check if the system paths for this page were loaded from cache in this + // request to avoid writing to cache on every request. + $system_paths = &drupal_static('drupal_lookup_path:system_paths', array()); + if (!$system_paths) { + // The static $map array used by drupal_lookup_path() includes all + // system paths for the page request. + $map = &drupal_static('drupal_lookup_path', array()); + + // Generate a cache ID (cid) specific for this page. + $cid = 'path:system:' . current_path(); + if ($paths = current($map)) { + $data = array_keys($paths); + $expire = REQUEST_TIME + (60 * 60 * 24); + cache_set($cid, $data, 'cache_path', $expire); + } + } +} + +/** * Given an internal Drupal path, return the alias set by the administrator. * * If no path is provided, the function will return the alias of the current Index: modules/node/node.admin.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.admin.inc,v retrieving revision 1.45 diff -u -p -r1.45 node.admin.inc --- modules/node/node.admin.inc 26 Apr 2009 19:44:38 -0000 1.45 +++ modules/node/node.admin.inc 8 May 2009 14:50:47 -0000 @@ -620,7 +620,6 @@ function theme_node_admin_nodes($form) { } function node_multiple_delete_confirm(&$form_state, $nodes) { - $form['nodes'] = array('#prefix' => '', '#tree' => TRUE); // array_filter returns only elements with TRUE values foreach ($nodes as $nid => $value) { @@ -642,10 +641,10 @@ function node_multiple_delete_confirm(&$ function node_multiple_delete_confirm_submit($form, &$form_state) { if ($form_state['values']['confirm']) { - foreach ($form_state['values']['nodes'] as $nid => $value) { - node_delete($nid); - } - drupal_set_message(t('The items have been deleted.')); + node_delete_multiple(array_keys($form_state['values']['nodes'])); + $count = count($form_state['values']['nodes']); + watchdog('content', 'Deleted @count posts.', array('@count' => $count)); + drupal_set_message(t('Deleted @count posts.', array('@count' => $count))); } $form_state['redirect'] = 'admin/content/node'; return; Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1044 diff -u -p -r1.1044 node.module --- modules/node/node.module 3 May 2009 10:11:34 -0000 1.1044 +++ modules/node/node.module 8 May 2009 14:50:49 -0000 @@ -1160,39 +1160,49 @@ function _node_save_revision(&$node, $ui /** * Delete a node. + * + * @param $nid + * A node ID. */ function node_delete($nid) { + node_delete_multiple(array($nid)); +} - $node = node_load($nid); - - if (node_access('delete', $node)) { - db_delete('node') - ->condition('nid', $node->nid) - ->execute(); - db_delete('node_revision') - ->condition('nid', $node->nid) - ->execute(); - db_delete('history') - ->condition('nid', $node->nid) - ->execute(); +/** + * Delete multiple nodes. + * + * @param $nids + * An array of node IDs. + */ +function node_delete_multiple($nids) { + $nodes = node_load_multiple($nids); + + db_delete('node') + ->condition('nid', $nids, 'IN') + ->execute(); + db_delete('node_revision') + ->condition('nid', $nids, 'IN') + ->execute(); + db_delete('history') + ->condition('nid', $nids, 'IN') + ->execute(); + foreach ($nodes as $nid => $node) { // Call the node-specific callback (if any): node_invoke($node, 'delete'); module_invoke_all('node_delete', $node); - // Clear the page and block caches. - cache_clear_all(); - // Remove this node from the search index if needed. // This code is implemented in node module rather than in search module, // because node module is implementing search module's API, not the other // way around. if (module_exists('search')) { - search_wipe($node->nid, 'node'); + search_wipe($nid, 'node'); } - watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title)); - drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_types('name', $node), '%title' => $node->title))); } + + // Clear the page and block caches. + cache_clear_all(); } /** Index: modules/node/node.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.pages.inc,v retrieving revision 1.63 diff -u -p -r1.63 node.pages.inc --- modules/node/node.pages.inc 6 May 2009 11:27:47 -0000 1.63 +++ modules/node/node.pages.inc 8 May 2009 14:50:49 -0000 @@ -521,7 +521,10 @@ function node_delete_confirm(&$form_stat */ function node_delete_confirm_submit($form, &$form_state) { if ($form_state['values']['confirm']) { + $node = node_load($form_state['values']['nid']); node_delete($form_state['values']['nid']); + watchdog('content', '@type: deleted %title.', array('@type' => $node->type, '%title' => $node->title)); + drupal_set_message(t('@type %title has been deleted.', array('@type' => node_get_types('name', $node), '%title' => $node->title))); } $form_state['redirect'] = ''; Index: modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.321 diff -u -p -r1.321 system.install --- modules/system/system.install 7 May 2009 15:29:08 -0000 1.321 +++ modules/system/system.install 8 May 2009 14:50:52 -0000 @@ -606,6 +606,8 @@ function system_schema() { $schema['cache_page']['description'] = 'Cache table used to store compressed pages for anonymous users, if page caching is enabled.'; $schema['cache_menu'] = $schema['cache']; $schema['cache_menu']['description'] = 'Cache table for the menu system to store router information as well as generated link trees for various menu/page/user combinations.'; + $schema['cache_path'] = $schema['cache']; + $schema['cache_path']['description'] = 'Cache table for path alias lookup.'; $schema['cache_registry'] = $schema['cache']; $schema['cache_registry']['description'] = 'Cache table for the code registry system to remember what code files need to be loaded on any given page.'; @@ -3439,6 +3441,17 @@ function system_update_7023() { } /** + * Create the cache_path table. + */ +function system_update_7024() { + $ret = array(); + $schema['cache_path'] = drupal_get_schema_unprocessed('system', 'cache'); + $schema['cache_path']['description'] = t('Cache table used for path alias lookups.'); + db_create_table($ret, 'cache_path', $schema['cache_path']); + return $ret; +} + +/** * @} End of "defgroup updates-6.x-to-7.x" * The next series of updates should start at 8000. */