summaryrefslogtreecommitdiff
path: root/includes/path.inc
diff options
context:
space:
mode:
Diffstat (limited to 'includes/path.inc')
-rw-r--r--includes/path.inc70
1 files changed, 63 insertions, 7 deletions
diff --git a/includes/path.inc b/includes/path.inc
index a4659d7c0..a6abc19b9 100644
--- a/includes/path.inc
+++ b/includes/path.inc
@@ -49,6 +49,9 @@ function drupal_lookup_path($action, $path = '', $path_language = '') {
$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());
+ $first_call = &drupal_static(__FUNCTION__ . ':first_call', TRUE);
$path_language = $path_language ? $path_language : $language->language;
@@ -61,19 +64,45 @@ function drupal_lookup_path($action, $path = '', $path_language = '') {
$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 ($first_call) {
+ $first_call = FALSE;
+ $map[$path_language] = array();
+ // Load system paths from cache.
+ $cid = 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.
+ $map[$path_language] = 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
+ ))->fetchAllKeyed();
+ // 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.
+ 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 +132,33 @@ function drupal_lookup_path($action, $path = '', $path_language = '') {
}
/**
+ * Cache system paths for a page.
+ *
+ * Cache an array of the system paths available on each page. We assume
+ * 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) specifically for this page.
+ $cid = 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