function drupal_lookup_path

You are here

7 path.inc drupal_lookup_path($action, $path = '', $path_language = NULL)
4.7 path.inc drupal_lookup_path($action, $path = '')
5 path.inc drupal_lookup_path($action, $path = '')
6 path.inc drupal_lookup_path($action, $path = '', $path_language = '')

Given an alias, return its Drupal system URL if one exists. Given a Drupal system URL return one of its aliases if such a one exists. Otherwise, return FALSE.

Parameters

$action: One of the following values:

  • wipe: delete the alias cache.
  • alias: return an alias for a given Drupal system path (if one exists).
  • source: return the Drupal system URL for a path alias (if one exists).

$path: The path to investigate for corresponding aliases or system URLs.

$path_language: Optional language code to search the path with. Defaults to the page language. If there's no path defined for that language it will search paths without language.

Return value

Either a Drupal system path, an aliased path, or FALSE if no path was found.

3 calls to drupal_lookup_path()
drupal_clear_path_cache in includes/common.inc
Reset the static variable which holds the aliases mapped for this request.
drupal_get_normal_path in includes/path.inc
Given a path alias, return the internal path it represents.
drupal_get_path_alias in includes/path.inc
Given an internal Drupal path, return the alias set by the administrator.

File

includes/path.inc, line 45
Functions to handle paths in Drupal, including path aliasing.

Code

function drupal_lookup_path($action, $path = '', $path_language = '') {
  global $language;
  // $map is an array with language keys, holding arrays of Drupal paths to alias relations
  static $map = array(), $no_src = array(), $count;

  $path_language = $path_language ? $path_language : $language->language;

  // Use $count to avoid looking up paths in subsequent calls if there simply are no aliases
  if (!isset($count)) {
    $count = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}'));
  }

  if ($action == 'wipe') {
    $map = array();
    $no_src = array();
    $count = NULL;
  }
  elseif ($count > 0 && $path != '') {
    if ($action == 'alias') {
      if (isset($map[$path_language][$path])) {
        return $map[$path_language][$path];
      }
      // Get the most fitting result falling back with alias without language
      $alias = db_result(db_query("SELECT dst FROM {url_alias} WHERE src = '%s' AND language IN('%s', '') ORDER BY language DESC, pid DESC", $path, $path_language));
      $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
    elseif ($action == 'source' && !isset($no_src[$path_language][$path])) {
      // Look for the value $path within the cached $map
      $src = FALSE;
      if (!isset($map[$path_language]) || !($src = array_search($path, $map[$path_language]))) {
        // Get the most fitting result falling back with alias without language
        if ($src = db_result(db_query("SELECT src FROM {url_alias} WHERE dst = '%s' AND language IN('%s', '') ORDER BY language DESC, pid DESC", $path, $path_language))) {
          $map[$path_language][$src] = $path;
        }
        else {
          // We can't record anything into $map because we do not have a valid
          // index and there is no need because we have not learned anything
          // about any Drupal path. Thus cache to $no_src.
          $no_src[$path_language][$path] = TRUE;
        }
      }
      return $src;
    }
  }

  return FALSE;
}

Comments

You can break all your aliases by changing your language table - say you change "en" to "en_GB" because you want to send a proper locale header for dates and numbers. This function would survive that if the sql were changed to:

SELECT src, CASE language
WHEN '%s' THEN 2
WHEN '' THEN 1
ELSE 0
END as languageall
FROM url_alias
WHERE src = '%s'
ORDER BY
languageall DESC, pid DESC

I think D7 is the same..

<?php
 
// Use $count to avoid looking up paths in subsequent calls if there simply are no aliases
 
if (!isset($count)) {
   
$count = db_result(db_query('SELECT COUNT(pid) FROM {url_alias}'));
  }
?>

I guess the above is supposed to be for performance reasons. However, with a big database it's the opposite - it takes my Mysql db 0.3 seconds to run this query - on every page load. It would be much smarter to run something like "SELECT pid FROM url_alias LIMIT 1". That takes 0.00 seconds.