summaryrefslogtreecommitdiff
path: root/includes/path.inc
diff options
context:
space:
mode:
Diffstat (limited to 'includes/path.inc')
-rw-r--r--includes/path.inc64
1 files changed, 51 insertions, 13 deletions
diff --git a/includes/path.inc b/includes/path.inc
index 3b5549656..83ebcb0c9 100644
--- a/includes/path.inc
+++ b/includes/path.inc
@@ -94,13 +94,30 @@ function drupal_lookup_path($action, $path = '', $path_language = NULL) {
if ($cached = cache_get($cid, 'cache_path')) {
$cache['system_paths'] = $cached->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.
- $cache['map'][$path_language] = db_query("SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND language IN (:language, :language_none) ORDER BY language ASC, pid ASC", array(
+ $args = array(
':system' => $cache['system_paths'],
':language' => $path_language,
':language_none' => LANGUAGE_NONE,
- ))->fetchAllKeyed();
+ );
+ // Always get the language-specific alias before the language-neutral
+ // one. For example 'de' is less than 'und' so the order needs to be
+ // ASC, while 'xx-lolspeak' is more than 'und' so the order needs to
+ // be DESC. We also order by pid ASC so that fetchAllKeyed() returns
+ // the most recently created alias for each source. Subsequent queries
+ // using fetchField() must use pid DESC to have the same effect.
+ // For performance reasons, the query builder is not used here.
+ if ($path_language == LANGUAGE_NONE) {
+ // Prevent PDO from complaining about a token the query doesn't use.
+ unset($args[':language']);
+ $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND language = :language_none ORDER BY pid ASC', $args);
+ }
+ elseif ($path_language < LANGUAGE_NONE) {
+ $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND language IN (:language, :language_none) ORDER BY language ASC, pid ASC', $args);
+ }
+ else {
+ $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND language IN (:language, :language_none) ORDER BY language DESC, pid ASC', $args);
+ }
+ $cache['map'][$path_language] = $result->fetchAllKeyed();
// Keep a record of paths with no alias to avoid querying twice.
$cache['no_aliases'][$path_language] = array_flip(array_diff_key($cache['system_paths'], array_keys($cache['map'][$path_language])));
}
@@ -117,12 +134,22 @@ function drupal_lookup_path($action, $path = '', $path_language = NULL) {
}
// For system paths which were not cached, query aliases individually.
elseif (!isset($cache['no_aliases'][$path_language][$path])) {
- // Get the most fitting result falling back with alias without language
- $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND language IN (:language, :language_none) ORDER BY language DESC, pid DESC", array(
+ $args = array(
':source' => $path,
':language' => $path_language,
':language_none' => LANGUAGE_NONE,
- ))->fetchField();
+ );
+ // See the queries above.
+ if ($path_language == LANGUAGE_NONE) {
+ unset($args[':language']);
+ $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND language = :language_none ORDER BY pid DESC", $args)->fetchField();
+ }
+ elseif ($path_language > LANGUAGE_NONE) {
+ $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND language IN (:language, :language_none) ORDER BY language DESC, pid DESC", $args)->fetchField();
+ }
+ else {
+ $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND language IN (:language, :language_none) ORDER BY language ASC, pid DESC", $args)->fetchField();
+ }
$cache['map'][$path_language][$path] = $alias;
return $alias;
}
@@ -133,12 +160,23 @@ function drupal_lookup_path($action, $path = '', $path_language = NULL) {
// Look for the value $path within the cached $map
$source = FALSE;
if (!isset($cache['map'][$path_language]) || !($source = array_search($path, $cache['map'][$path_language]))) {
- // Get the most fitting result falling back with alias without language
- if ($source = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND language IN (:language, :language_none) ORDER BY language DESC, pid DESC", array(
- ':alias' => $path,
- ':language' => $path_language,
- ':language_none' => LANGUAGE_NONE))
- ->fetchField()) {
+ $args = array(
+ ':alias' => $path,
+ ':language' => $path_language,
+ ':language_none' => LANGUAGE_NONE,
+ );
+ // See the queries above.
+ if ($path_language == LANGUAGE_NONE) {
+ unset($args[':language']);
+ $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND language = :language_none ORDER BY pid DESC", $args);
+ }
+ elseif ($path_language > LANGUAGE_NONE) {
+ $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND language IN (:language, :language_none) ORDER BY language DESC, pid DESC", $args);
+ }
+ else {
+ $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND language IN (:language, :language_none) ORDER BY language ASC, pid DESC", $args);
+ }
+ if ($source = $result->fetchField()) {
$cache['map'][$path_language][$source] = $path;
}
else {