drupal_lookup_path does not return localized alias

Created on 3 May 2021, over 3 years ago
Updated 24 April 2024, 8 months ago

Problem/Motivation

drupal_lookup_path() and drupal_get_path_alias() do not return the
localized path alias, if there is an alias for undefined language.

Steps to reproduce

  • Create a localized alias for some path, eg. /abc for /node/1 with langcode de.
  • Create another alias for the same path, eg. /xyz with undefined language.
  • When visiting the aliased localized page (eg. /de/node/1), use drupal_get_path_alias() without arguments to retrieve the alias for the current page (via hook_page() or something).

In the last step, drupal_get_path_alias() will not return the correct alias, the localized one, but the language-undefined alias.

Proposed resolution

Retrieving the alias from the database is done via drupal_lookup_path() in includes/path.inc. There in lines 108 till 119 is the following code:

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();

The results of the query are ordered by language. If $path_language is smaller
than LANGUAGE_NONE the results are ordered by language in ascending order.
When fetched via fetchAllKeyed(), the localized results are therefore first in
the returned array and it seems they are overwritten by the values with the
same key coming later.

Example: node/1 has the aliases abc (de) and xyz (und), fetchAllKeyed() will
return an array:

node/1 => abc
node/1 => xyz

Here xyz takes precedence over abc and therefore the localized alias is
discarded and the one with undefined language is used.

To fix this it should suffice to change the ordering of the results.

🐛 Bug report
Status

Active

Version

11.0 🔥

Component
Routing 

Last updated 3 days ago

Created by

🇩🇪Germany lukas_w

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024