Index: includes/path.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/path.inc,v retrieving revision 1.37 diff -u -F^f -r1.37 path.inc --- includes/path.inc 26 May 2009 09:12:28 -0000 1.37 +++ includes/path.inc 30 May 2009 17:54:44 -0000 @@ -66,8 +66,16 @@ function drupal_lookup_path($action, $pa $count = NULL; $system_paths = array(); $no_aliases = array(); + + $whitelist = drupal_path_alias_whitelist_rebuild(); + variable_set('path_alias_whitelist', $whitelist); } elseif ($count > 0 && $path != '') { + // Retrieve the path alias whitelist + $whitelist = variable_get('path_alias_whitelist', array()); + // And derive the top level component of the path + $top_level = strtok($path, '/'); + if ($action == 'alias') { // During the first call to drupal_lookup_path() per language, load the // expected system paths for the page from cache. @@ -93,6 +101,12 @@ function drupal_lookup_path($action, $pa if (isset($map[$path_language][$path])) { return $map[$path_language][$path]; } + elseif (!isset($whitelist[$top_level])) { + // Check the path whitelist, if the top_level part before the first / + // is not in the list, then there is no need to do anything further, + // it is not in the database + return FALSE; + } // For system paths which were not cached, query aliases individually. else if (!isset($no_aliases[$path_language][$path])) { // Get the most fitting result falling back with alias without language @@ -347,3 +361,32 @@ function drupal_match_path($path, $patte function current_path() { return $_GET['q']; } + +/** + * Rebuild the path alias white list. + * + * @return + * An array containing a white list of path aliases. + */ +function drupal_path_alias_whitelist_rebuild() { + // For each alias in the database, get the top level component. This is the portion of the + // alias before the first /, if present, otherwise, the whole alias itself. + $whitelist = array(); + switch(db_driver()) { + case 'mysql': + // Use SUBSTRING_INDEX on MySQL + $sql = "SELECT SUBSTRING_INDEX(src, '/', 1) AS path FROM {url_alias} GROUP BY path"; + break; + case 'pgsql': + // USe REGEX_REPLACE on PostgreSQL + $sql = "SELECT REGEX_REPLACE(src, '/.*$', '') AS path FROM {url_alias} GROUP BY path"; + break; + case 'sqlite': + // TODO Need chx or someone's input here + break; + } + foreach (db_query($sql) as $row) { + $whitelist[$row->src] = TRUE; + } + return $whitelist; +}