function path_set_alias

4.6 path.module path_set_alias($path = NULL, $alias = NULL, $pid = NULL)
4.7 path.module path_set_alias($path = NULL, $alias = NULL, $pid = NULL)
5 path.module path_set_alias($path = NULL, $alias = NULL, $pid = NULL)
6 path.module path_set_alias($path = NULL, $alias = NULL, $pid = NULL, $language = '')

Set an aliased path for a given Drupal path, preventing duplicates.

Parameters

$path: Path URL. Set to NULL to delete alias.

$alias: Alias URL. Set to NULL to delete alias.

$pid: Path id to update. Set to NULL to create a new alias or to delete a group of aliases.

$language: The language this alias is valid for.

2 calls to path_set_alias()
path_admin_form_submit in modules/path/path.admin.inc
Save a new URL alias to the database.
path_nodeapi in modules/path/path.module
Implementation of hook_nodeapi().

File

modules/path/path.module, line 96
Enables users to rename URLs.

Code

function path_set_alias($path = NULL, $alias = NULL, $pid = NULL, $language = '') {
  /* This function claimed to prevent duplicate aliases but has not done
   * so since the end of 2007.
   * The uniqueness of dst+language pairs was enforced on the database level
   * until D6.16 (march 2010); trying to insert duplicate aliass would yield a
   * database error.
   * From D6.16 onwards, duplicates would silently be inserted, and
   * drupal_lookup_path() consistently uses those newer aliases.
   * While fixing an issue in D6.23, the behavior was reverted to preventing
   * duplicates by the below code. Watchdog errors are now logged instead.
   */
  $path = urldecode($path);
  $alias = urldecode($alias);
  // First we check if we deal with an existing alias and delete or modify it based on pid.
  if ($pid) {
    // An existing alias.
    if (!$path || !$alias) {
      // Delete the alias based on pid.
      db_query('DELETE FROM {url_alias} WHERE pid = %d', $pid);
    }
    else {
      // Update the existing alias.
      // Check if the alias exists already.
      $existing = db_fetch_array(db_query("SELECT pid, src FROM {url_alias} WHERE dst = '%s' AND language = '%s' ORDER BY pid DESC", $alias, $language));
      if (!$existing || ($existing['pid'] == $pid && $existing['src'] != $path)) {
        db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE pid = %d", $path, $alias, $language, $pid);
      }
      else {
        if ($existing['src'] != $path) {
          watchdog('path', "The alias for path '@path' (language '@lang') was not updated to '@alias', because the path '@expath' already has the same alias.", array('@path' => $path, '@lang' => $language, '@alias' => $alias, '@expath' => $existing['src']), WATCHDOG_ERROR);
        }
        // Don't clear cache if we didn't change anything
        return;
      }
    }
  }
  elseif ($path && $alias) {
    // Add this alias to the database, if it's new & doesn't cause conflicts.
    $existing = db_fetch_array(db_query("SELECT src, language, pid FROM {url_alias} WHERE dst = '%s' AND language IN('%s', '') ORDER BY language DESC, pid DESC", $alias, $language));
    if (!$existing || ($existing['language'] != $language && $existing['src'] != $path)) {
      // A new alias. Add it to the database.
      db_query("INSERT INTO {url_alias} (src, dst, language) VALUES ('%s', '%s', '%s')", $path, $alias, $language);
    }
    elseif ($existing['language'] != $language) {
      // This alias already exists ONLY for 'language neutral': update language.
      // (We can only get here if $language != '')
      db_query("UPDATE {url_alias} SET language = '%s' WHERE pid = %d", $language, $existing['pid']);
    }
    else {
      if ($existing['src'] != $path) {
        watchdog('path', "The alias '@alias' for path '@path' (language '@lang') was not created, because the path '@expath' already has the same alias.", array('@path' => $path, '@lang' => $language, '@alias' => $alias, '@expath' => $existing['src']), WATCHDOG_ERROR);
      }
      // Don't clear cache if we didn't change anything
      return;
    }
  }
  else {
    // Delete the alias.
    if ($alias) {
      db_query("DELETE FROM {url_alias} WHERE dst = '%s'", $alias);
    }
    else {
      db_query("DELETE FROM {url_alias} WHERE src = '%s'", $path);
    }
  }
  drupal_clear_path_cache();
}

Comments

In Drupal 7, the analogous function is path_save
http://api.drupal.org/api/drupal/includes--path.inc/function/path_save/7

This is how I used path_set_alias to clean out some bad characters when pathauto was not an option (for various reasons).

$updated = mymodule_clean_aliases('/[^a-zA-Z0-9\/_\-.áíóéñ]/', TRUE);

/**
* Clean out bad characters from url aliases.
*
* Opens each url alias and examines each character to ensure its an approved
* character. If the character is not allowed, a clean version of the url
* alias will be generated and the current aliases replaced. Optionally a
* redirect will be established from the old corrupt alias to the new.
*
* @param string $not_pattern
*   Regex pattern. Characters not contained in the pattern will be removed.
*   If the pattern is '/[^a]/' then everything but the character 'a' will be
*   stripped.
* @param bool $redirect
*   Set to TRUE if a redirect should be setup for the old alias. Defaults to
*   FALSE.
*
* @return
*   (int) Number of aliases changed.
*/
function mymodule_clean_aliases($not_pattern, $redirect = FALSE) {
  $changed = 0;
  $result = db_query('SELECT * FROM url_alias');
  while ($url_alias = db_fetch_object($result)) {
    $new_alias = preg_replace($not_pattern, '', $url_alias->dst);
    if ($new_alias != $url_alias->dst) {
      /** Create redirect from old alias to actual node. */
      if (function_exists('path_redirect_check_alias_changed')) {
        path_redirect_check_alias_changed($url_alias->src, $new_alias);
      }
      /** Remove the old alias. */
      path_set_alias(NULL, $url_alias->dst, NULL);
      /** Create new alias. */
      path_set_alias($url_alias->src, $new_alias, NULL);
      $changed++;
    }
  }
  return $changed;
}