1 path.inc backdrop_lookup_path($action, $path = '', $langcode = NULL)

Given an alias, return its Backdrop system URL if one exists. Given a Backdrop 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 Backdrop system path (if one exists).
  • source: return the Backdrop system path for a URL alias (if one exists).

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

$langcode: 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 Backdrop system path, an aliased path, or FALSE if no path was: found.

File

core/includes/path.inc, line 44
Functions to handle paths in Backdrop, including URL aliasing.

Code

function backdrop_lookup_path($action, $path = '', $langcode = NULL) {
  global $language_url;
  // Use the advanced backdrop_static() pattern, since this is called very often.
  static $backdrop_static_fast;
  if (!isset($backdrop_static_fast)) {
    $backdrop_static_fast['cache'] = &backdrop_static(__FUNCTION__);
  }
  $cache = &$backdrop_static_fast['cache'];

  if (!isset($cache)) {
    $cache = array(
      'map' => array(),
      'no_source' => array(),
      'allowlist' => NULL,
      'system_paths' => array(),
      'no_aliases' => array(),
      'first_call' => TRUE,
    );
  }

  // If no language is explicitly specified we default to the current URL
  // language. If we used a language different from the one conveyed by the
  // requested URL, we might end up being unable to check if there is a URL
  // alias matching the system path.
  $langcode = $langcode ? $langcode : $language_url->langcode;

  if ($action == 'wipe') {
    $cache = array();
  }
  elseif ($path != '') {
    if ($action == 'alias') {
      // During the first call to backdrop_lookup_path() per language, load the
      // expected system paths for the page from cache.
      if (!empty($cache['first_call'])) {
        $cache['first_call'] = FALSE;

        $cache['map'][$langcode] = array();
        // Load system paths from cache.
        $cid = current_path();
        if ($cached = cache('path')->get($cid)) {
          $cache['system_paths'] = $cached->data;
          // Now fetch the aliases corresponding to these system paths.
          $args = array(
            ':system' => $cache['system_paths'],
            ':langcode' => $langcode,
            ':language_none' => LANGUAGE_NONE,
          );
          // 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 ($langcode == LANGUAGE_NONE) {
            // Prevent PDO from complaining about a token the query doesn't use.
            unset($args[':langcode']);
            $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode = :language_none ORDER BY pid ASC', $args);
          }
          elseif ($langcode < LANGUAGE_NONE) {
            $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode IN (:langcode, :language_none) ORDER BY langcode ASC, pid ASC', $args);
          }
          else {
            $result = db_query('SELECT source, alias FROM {url_alias} WHERE source IN (:system) AND langcode IN (:langcode, :language_none) ORDER BY langcode DESC, pid ASC', $args);
          }
          $cache['map'][$langcode] = $result->fetchAllKeyed();
          // Keep a record of paths with no alias to avoid querying twice.
          $cache['no_aliases'][$langcode] = array_flip(array_diff_key($cache['system_paths'], array_keys($cache['map'][$langcode])));
        }
      }
      // If the alias has already been loaded, return it.
      if (isset($cache['map'][$langcode][$path])) {
        return $cache['map'][$langcode][$path];
      }
      // For system paths which were not cached, query aliases individually.
      elseif (!isset($cache['no_aliases'][$langcode][$path])) {
        $args = array(
          ':source' => $path,
          ':langcode' => $langcode,
          ':language_none' => LANGUAGE_NONE,
        );
        // See the queries above.
        if ($langcode == LANGUAGE_NONE) {
          unset($args[':langcode']);
          $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode = :language_none ORDER BY pid DESC", $args)->fetchField();
        }
        elseif ($langcode > LANGUAGE_NONE) {
          $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode IN (:langcode, :language_none) ORDER BY langcode DESC, pid DESC", $args)->fetchField();
        }
        else {
          $alias = db_query("SELECT alias FROM {url_alias} WHERE source = :source AND langcode IN (:langcode, :language_none) ORDER BY langcode ASC, pid DESC", $args)->fetchField();
        }
        $cache['map'][$langcode][$path] = $alias;
        return $alias;
      }
    }
    // Check $no_source for this $path in case we've already determined that there
    // isn't a path that has this alias
    elseif ($action == 'source' && !isset($cache['no_source'][$langcode][$path])) {
      // Look for the value $path within the cached $map
      if (!isset($cache['map'][$langcode]) || !($source = array_search($path, $cache['map'][$langcode]))) {
        $args = array(
          ':alias' => $path,
          ':langcode' => $langcode,
          ':language_none' => LANGUAGE_NONE,
        );
        // See the queries above.
        if ($langcode == LANGUAGE_NONE) {
          unset($args[':langcode']);
          $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode = :language_none ORDER BY pid DESC", $args);
        }
        elseif ($langcode > LANGUAGE_NONE) {
          $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode IN (:langcode, :language_none) ORDER BY langcode DESC, pid DESC", $args);
        }
        else {
          $result = db_query("SELECT source FROM {url_alias} WHERE alias = :alias AND langcode IN (:langcode, :language_none) ORDER BY langcode ASC, pid DESC", $args);
        }
        if ($source = $result->fetchField()) {
          $cache['map'][$langcode][$source] = $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 Backdrop path. Thus cache to $no_source.
          $cache['no_source'][$langcode][$path] = TRUE;
        }
      }
      return $source;
    }
  }

  return FALSE;
}