path.module 8.97 KB
Newer Older
Steven Wittens's avatar
Steven Wittens committed
1 2 3 4 5 6 7 8 9 10 11
<?php
// $Id$

/**
 * @file
 * Enables users to rename URLs.
 */

/**
 * Implementation of hook_help().
 */
12 13
function path_help($path, $arg) {
  switch ($path) {
Steven Wittens's avatar
Steven Wittens committed
14
    case 'admin/help#path':
15 16 17 18 19 20 21 22 23
      $output = '<p>' . t('The path module allows you to specify aliases for Drupal URLs. Such aliases improve readability of URLs for your users and may help internet search engines to index your content more effectively. More than one alias may be created for a given page.') . '</p>';
      $output .= '<p>' . t('Some examples of URL aliases are:') . '</p>';
      $output .= '<ul><li>' . t('%alias for the path %path', array('%alias' => 'login', '%path' => 'user/login')) . '</li>';
      $output .= '<li>' . t('%alias for the path %path', array('%alias' => 'store', '%path' => 'image/tid/16')) . '</li>';
      $output .= '<li>' . t('%alias for the path %path', array('%alias' => 'store/products/whirlygigs', '%path' => 'taxonomy/term/7+19+20+21')) . '</li>';
      $output .= '<li>' . t('%alias for the path %path', array('%alias' => 'contact', '%path' => 'node/3')) . '</li></ul>';
      $output .= '<p>' . t('The path module enables appropriately permissioned users to specify an optional alias in all node input and editing forms, and provides an interface to view and edit all URL aliases. The two permissions related to URL aliasing are <em>administer url aliases</em> and <em>create url aliases</em>. ') . '</p>';
      $output .= '<p>' . t('This module also provides user-defined mass URL aliasing capabilities, which is useful if you wish to uniformly use URLs different from the default. For example, you may want to have your URLs presented in a different language. Access to the Drupal source code on the web server is required to set up mass URL aliasing. ') . '</p>';
      $output .= '<p>' . t('For more information, see the online handbook entry for <a href="@path">Path module</a>.', array('@path' => 'http://drupal.org/handbook/modules/path/')) . '</p>';
Steven Wittens's avatar
Steven Wittens committed
24 25
      return $output;
    case 'admin/build/path':
26
      return '<p>' . t("Drupal provides complete control over URLs through aliasing, which is often used to make URLs more readable or easy to remember. For example, the alias 'about' may be mapped onto the post at the system path 'node/1', creating a more meaningful URL. Each system path can have multiple aliases.") . '</p>';
Steven Wittens's avatar
Steven Wittens committed
27
    case 'admin/build/path/add':
28
      return '<p>' . t('Enter the path you wish to create the alias for, followed by the name of the new alias.') . '</p>';
Steven Wittens's avatar
Steven Wittens committed
29 30 31 32 33 34
  }
}

/**
 * Implementation of hook_menu().
 */
35 36
function path_menu() {
  $items['admin/build/path'] = array(
37 38
    'title' => 'URL aliases',
    'description' => "Change your site's URL paths by aliasing them.",
39
    'page callback' => 'path_admin_overview',
40 41 42
    'access arguments' => array('administer url aliases'),
  );
  $items['admin/build/path/edit'] = array(
43
    'title' => 'Edit alias',
44
    'page callback' => 'path_admin_edit',
45
    'access arguments' => array('administer url aliases'),
46 47 48
    'type' => MENU_CALLBACK,
  );
  $items['admin/build/path/delete'] = array(
49
    'title' => 'Delete alias',
50 51
    'page callback' => 'drupal_get_form',
    'page arguments' => array('path_admin_delete_confirm'),
52
    'access arguments' => array('administer url aliases'),
53 54 55
    'type' => MENU_CALLBACK,
  );
  $items['admin/build/path/list'] = array(
56
    'title' => 'List',
57 58 59 60
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => -10,
  );
  $items['admin/build/path/add'] = array(
61
    'title' => 'Add alias',
62
    'page callback' => 'path_admin_edit',
63 64 65
    'access arguments' => array('administer url aliases'),
    'type' => MENU_LOCAL_TASK,
  );
Steven Wittens's avatar
Steven Wittens committed
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

  return $items;
}

/**
 * Post-confirmation; delete an URL alias.
 */
function path_admin_delete($pid = 0) {
  db_query('DELETE FROM {url_alias} WHERE pid = %d', $pid);
  drupal_set_message(t('The alias has been deleted.'));
}

/**
 * Set an aliased path for a given Drupal path, preventing duplicates.
 */
81
function path_set_alias($path = NULL, $alias = NULL, $pid = NULL, $language = '') {
82 83 84 85 86 87 88 89 90 91 92 93 94
  $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.
      db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE pid = %d", $path, $alias, $language, $pid);
    }
Steven Wittens's avatar
Steven Wittens committed
95
  }
96
  elseif ($path && $alias) {
97 98 99 100 101
    // Check for existing aliases.
    if ($alias == drupal_get_path_alias($path, $language)) {
      // There is already such an alias, neutral or in this language.
      // Update the alias based on alias; setting the language if not yet done.
      db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE dst = '%s'", $path, $alias, $language, $alias);
Steven Wittens's avatar
Steven Wittens committed
102
    }
103
    else {
104 105
      // A new alias. Add it to the database.
      db_query("INSERT INTO {url_alias} (src, dst, language) VALUES ('%s', '%s', '%s')", $path, $alias, $language);
Steven Wittens's avatar
Steven Wittens committed
106
    }
107 108 109 110 111
  }
  else {
    // Delete the alias.
    if ($alias) {
      db_query("DELETE FROM {url_alias} WHERE dst = '%s'", $alias);
Steven Wittens's avatar
Steven Wittens committed
112
    }
113 114
    else {
      db_query("DELETE FROM {url_alias} WHERE src = '%s'", $path);
115
    }
Steven Wittens's avatar
Steven Wittens committed
116
  }
117
  drupal_clear_path_cache();
Steven Wittens's avatar
Steven Wittens committed
118 119 120
}

/**
121
 * Implementation of hook_nodeapi_validate().
Steven Wittens's avatar
Steven Wittens committed
122
 */
123 124 125 126 127 128 129 130 131 132 133
function path_nodeapi_validate(&$node, $arg) {
  if (user_access('create url aliases') || user_access('administer url aliases')) {
    if (isset($node->path)) {
      $language = isset($node->language) ? $node->language : '';
      $node->path = trim($node->path);
      if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE dst = '%s' AND src != '%s' AND language = '%s'", $node->path, "node/$node->nid", $language))) {
        form_set_error('path', t('The path is already in use.'));
      }
    }
  }
}
Steven Wittens's avatar
Steven Wittens committed
134

135 136 137 138 139 140 141 142 143 144 145
/**
 * Implementation of hook_nodeapi_load().
 */
function path_nodeapi_load(&$node, $arg) {
  $language = isset($node->language) ? $node->language : '';
  $path = 'node/' . $node->nid;
  $alias = drupal_get_path_alias($path, $language);
  if ($path != $alias) {
    $node->path = $alias;
  }
}
Steven Wittens's avatar
Steven Wittens committed
146

147 148 149 150 151 152 153 154 155 156 157 158 159
/**
 * Implementation of hook_nodeapi_insert().
 */
function path_nodeapi_insert(&$node, $arg) {
  if (user_access('create url aliases') || user_access('administer url aliases')) {
    $language = isset($node->language) ? $node->language : '';
    // Don't try to insert if path is NULL. We may have already set
    // the alias ahead of time.
    if (isset($node->path)) {
      path_set_alias('node/' . $node->nid, $node->path, NULL, $language);
    }
  }
}
Steven Wittens's avatar
Steven Wittens committed
160

161 162 163 164 165 166 167 168 169
/**
 * Implementation of hook_nodeapi_update().
 */
function path_nodeapi_update(&$node, $arg) {
  if (user_access('create url aliases') || user_access('administer url aliases')) {
    $language = isset($node->language) ? $node->language : '';
    path_set_alias('node/' . $node->nid, isset($node->path) ? $node->path : NULL, isset($node->pid) ? $node->pid : NULL, $language);
  }
}
Steven Wittens's avatar
Steven Wittens committed
170

171 172 173 174 175 176 177 178 179
/**
 * Implementation of hook_nodeapi_delete().
 */
function path_nodeapi_delete(&$node, $arg) {
  if (user_access('create url aliases') || user_access('administer url aliases')) {
    $language = isset($node->language) ? $node->language : '';
    $path = 'node/' . $node->nid;
    if (drupal_get_path_alias($path) != $path) {
      path_set_alias($path);
Steven Wittens's avatar
Steven Wittens committed
180 181 182 183 184 185 186
    }
  }
}

/**
 * Implementation of hook_form_alter().
 */
187
function path_form_alter(&$form, $form_state, $form_id) {
188
  if (!empty($form['#node_edit_form'])) {
189
    $path = isset($form['#node']->path) ? $form['#node']->path : NULL;
Steven Wittens's avatar
Steven Wittens committed
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
    $form['path'] = array(
      '#type' => 'fieldset',
      '#title' => t('URL path settings'),
      '#collapsible' => TRUE,
      '#collapsed' => empty($path),
      '#access' => user_access('create url aliases'),
      '#weight' => 30,
    );
    $form['path']['path'] = array(
      '#type' => 'textfield',
      '#default_value' => $path,
      '#maxlength' => 250,
      '#collapsible' => TRUE,
      '#collapsed' => TRUE,
      '#description' => t('Optionally specify an alternative URL by which this node can be accessed. For example, type "about" when writing an about page. Use a relative path and don\'t add a trailing slash or the URL alias won\'t work.'),
    );
    if ($path) {
      $form['path']['pid'] = array(
        '#type' => 'value',
209
        '#value' => db_result(db_query("SELECT pid FROM {url_alias} WHERE dst = '%s' AND language = '%s'", $path, $form['#node']->language))
Steven Wittens's avatar
Steven Wittens committed
210 211 212 213 214 215 216 217 218
      );
    }
  }
}

/**
 * Implementation of hook_perm().
 */
function path_perm() {
219
  return array(
220 221 222 223 224 225 226 227
    'administer url aliases' => array(
      'title' => t('Administer URL aliases'),
      'description' => t('Manage URL aliases across the entire website.'),
    ),
    'create url aliases' => array(
      'title' => t('Create URL aliases'),
      'description' => t('Manage URL aliases on content.'),
    ),
228
  );
Steven Wittens's avatar
Steven Wittens committed
229 230 231 232 233 234 235 236
}

/**
 * Fetch a specific URL alias from the database.
 */
function path_load($pid) {
  return db_fetch_array(db_query('SELECT * FROM {url_alias} WHERE pid = %d', $pid));
}