389 lines
13 KiB
Plaintext
389 lines
13 KiB
Plaintext
<?php
|
|
// $Id$
|
|
|
|
/**
|
|
* @file
|
|
* Enables users to rename URLs.
|
|
*/
|
|
|
|
/**
|
|
* Implement hook_help().
|
|
*/
|
|
function path_help($path, $arg) {
|
|
switch ($path) {
|
|
case 'admin/help#path':
|
|
$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>';
|
|
return $output;
|
|
case 'admin/config/search/path':
|
|
return '<p>' . t("An alias defines a different name for an existing URL path - for example, the alias 'about' for the URL path 'node/1'. A URL path can have multiple aliases.") . '</p>';
|
|
case 'admin/config/search/path/add':
|
|
return '<p>' . t('Enter the path you wish to create the alias for, followed by the name of the new alias.') . '</p>';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implement hook_menu().
|
|
*/
|
|
function path_menu() {
|
|
$items['admin/config/search/path'] = array(
|
|
'title' => 'URL aliases',
|
|
'description' => "Change your site's URL paths by aliasing them.",
|
|
'page callback' => 'path_admin_overview',
|
|
'access arguments' => array('administer url aliases'),
|
|
'file' => 'path.admin.inc',
|
|
);
|
|
$items['admin/config/search/path/edit/%path'] = array(
|
|
'title' => 'Edit alias',
|
|
'page callback' => 'path_admin_edit',
|
|
'page arguments' => array(5),
|
|
'access arguments' => array('administer url aliases'),
|
|
'type' => MENU_CALLBACK,
|
|
'file' => 'path.admin.inc',
|
|
);
|
|
$items['admin/config/search/path/delete/%path'] = array(
|
|
'title' => 'Delete alias',
|
|
'page callback' => 'drupal_get_form',
|
|
'page arguments' => array('path_admin_delete_confirm', 5),
|
|
'access arguments' => array('administer url aliases'),
|
|
'type' => MENU_CALLBACK,
|
|
'file' => 'path.admin.inc',
|
|
);
|
|
$items['admin/config/search/path/list'] = array(
|
|
'title' => 'List',
|
|
'type' => MENU_DEFAULT_LOCAL_TASK,
|
|
'weight' => -10,
|
|
);
|
|
$items['admin/config/search/path/add'] = array(
|
|
'title' => 'Add alias',
|
|
'page callback' => 'path_admin_edit',
|
|
'access arguments' => array('administer url aliases'),
|
|
'type' => MENU_LOCAL_ACTION,
|
|
'file' => 'path.admin.inc',
|
|
);
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Fetch a specific URL alias from the database.
|
|
*
|
|
* @param $criteria
|
|
* A string representing the source, a number representing the pid, or an
|
|
* array of criteria.
|
|
*/
|
|
function path_load($criteria) {
|
|
if (is_numeric($criteria)) {
|
|
$criteria = array('pid' => $criteria);
|
|
}
|
|
else if (is_string($criteria)) {
|
|
$criteria = array('source' => $criteria);
|
|
}
|
|
else if (!is_array($criteria)) {
|
|
return FALSE;
|
|
}
|
|
$select = db_select('url_alias');
|
|
foreach ($criteria as $field => $value) {
|
|
$select->condition($field, $value);
|
|
}
|
|
return $select
|
|
->fields('url_alias', array('source', 'alias', 'language', 'pid'))
|
|
->execute()
|
|
->fetchAssoc();
|
|
}
|
|
|
|
/**
|
|
* Save a path alias to the database.
|
|
*
|
|
* @param $path
|
|
* A path array containing the following keys:
|
|
* - source: the initial path.
|
|
* - alias: the aliased path.
|
|
* - language: the language of the alias.
|
|
* - pid: unique path alias identifier (optional).
|
|
*/
|
|
function path_save($path) {
|
|
$path += array('language' => '', 'pid' => 0);
|
|
$pid = empty($path['pid']) ? 0 : $path['pid'];
|
|
$new = (bool) $pid;
|
|
unset($path['pid']);
|
|
// Make sure that this combination of source, alias, language wasn't save before.
|
|
$loaded_path = path_load($path);
|
|
if ($loaded_path) {
|
|
return $loaded_path;
|
|
}
|
|
if ($pid) {
|
|
db_update('url_alias')
|
|
->fields($path)
|
|
->condition('pid', $pid)
|
|
->execute();
|
|
}
|
|
else {
|
|
$pid = db_insert('url_alias')
|
|
->fields($path)
|
|
->execute();
|
|
}
|
|
$path['pid'] = $pid;
|
|
module_invoke_all('path_' . ($new ? 'insert' : 'update'), $path);
|
|
|
|
drupal_clear_path_cache();
|
|
return $path;
|
|
}
|
|
|
|
/**
|
|
* Delete a URL alias.
|
|
*
|
|
* @param $criteria
|
|
* A number representing the pid or an array of criteria.
|
|
*/
|
|
function path_delete($criteria) {
|
|
if (!is_array($criteria)) {
|
|
$criteria = array('pid' => $criteria);
|
|
}
|
|
$path = path_load($criteria);
|
|
$delete = db_delete('url_alias');
|
|
foreach ($criteria as $field => $value) {
|
|
$delete->condition($field, $value);
|
|
}
|
|
$delete->execute();
|
|
module_invoke_all('path_delete', $path);
|
|
drupal_clear_path_cache();
|
|
}
|
|
|
|
/**
|
|
* Implement hook_node_validate().
|
|
*/
|
|
function path_node_validate($node, $form) {
|
|
if (user_access('create url aliases') || user_access('administer url aliases')) {
|
|
if (isset($node->path)) {
|
|
if (!is_array($node->path)) {
|
|
$node->path = array('alias' => $node->path);
|
|
}
|
|
$select = db_select('url_alias')->condition('alias', trim($node->path['alias']));
|
|
$select->addExpression('COUNT(alias)');
|
|
if ($node->nid) {
|
|
$select->condition('source', 'node/' . $node->nid, '<>');
|
|
}
|
|
if (isset($node->language)) {
|
|
$select->condition('language', $node->language);
|
|
}
|
|
if ($select->execute()->fetchField()) {
|
|
form_set_error('path', t('The path is already in use.'));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implement hook_node_load().
|
|
*/
|
|
function path_node_load($nodes, $types) {
|
|
foreach ($nodes as $node) {
|
|
$criteria = array('source' => 'node/' . $node->nid);
|
|
if (isset($node->language)) {
|
|
$criteria['language'] = $node->language;
|
|
}
|
|
$alias = path_load($criteria);
|
|
if ($alias) {
|
|
$node->path = $alias;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implement hook_node_insert().
|
|
*/
|
|
function path_node_insert($node) {
|
|
if ((user_access('create url aliases') || user_access('administer url aliases')) && isset($node->path)) {
|
|
if (!is_array($node->path)) {
|
|
$node->path = array('alias' => $node->path);
|
|
}
|
|
|
|
$node->path += array(
|
|
'source' => 'node/' . $node->nid,
|
|
'language' => isset($node->language) ? $node->language : '',
|
|
);
|
|
$node->path = path_save($node->path);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implement hook_node_update().
|
|
*/
|
|
function path_node_update($node) {
|
|
if ((user_access('create url aliases') || user_access('administer url aliases')) && isset($node->path)) {
|
|
if (!is_array($node->path)) {
|
|
$node->path = array('alias' => $node->path);
|
|
}
|
|
if (isset($node->pid)) {
|
|
$node->path['pid'] = $node->pid;
|
|
}
|
|
$node->path += array(
|
|
'source' => 'node/' . $node->nid,
|
|
'language' => isset($node->language) ? $node->language : '',
|
|
);
|
|
path_save($node->path);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implement hook_node_delete().
|
|
*/
|
|
function path_node_delete($node) {
|
|
if (isset($node->path)) {
|
|
if (!is_array($node->path)) {
|
|
$node->path = path_load(array('alias' => $node->path));
|
|
}
|
|
path_delete($node->path['pid']);
|
|
unset($node->path);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implement hook_taxonomy_term_delete().
|
|
*/
|
|
function path_taxonomy_term_delete($term) {
|
|
path_delete(path_load('taxonomy/term/' . $term->tid));
|
|
}
|
|
|
|
/**
|
|
* Implement hook_form_alter().
|
|
*/
|
|
function path_form_alter(&$form, $form_state, $form_id) {
|
|
if (!empty($form['#node_edit_form'])) {
|
|
$path = NULL;
|
|
if (isset($form['#node']->path)) {
|
|
if (is_array($form['#node']->path)) {
|
|
$path = $form['#node']->path['alias'];
|
|
}
|
|
else {
|
|
$path = $form['#node']->path;
|
|
}
|
|
}
|
|
$form['path'] = array(
|
|
'#type' => 'fieldset',
|
|
'#title' => t('URL path settings'),
|
|
'#collapsible' => TRUE,
|
|
'#collapsed' => empty($path),
|
|
'#group' => 'additional_settings',
|
|
'#attached' => array(
|
|
'js' => array(drupal_get_path('module', 'path') . '/path.js'),
|
|
),
|
|
'#access' => user_access('create url aliases'),
|
|
'#weight' => 30,
|
|
);
|
|
$form['path']['path'] = array(
|
|
'#type' => 'textfield',
|
|
'#title' => t('URL alias'),
|
|
'#default_value' => $path,
|
|
'#maxlength' => 255,
|
|
'#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',
|
|
'#value' => $form['#node']->path['pid'],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implement hook_form_FORM_ID_alter().
|
|
*/
|
|
function path_form_taxonomy_form_term_alter(&$form, $form_state) {
|
|
// Make sure this does not show up on the delete confirmation form.
|
|
if (empty($form_state['confirm_delete'])) {
|
|
// After a new term is added, populate the path field if it was set.
|
|
if (!empty($form['#term']['path'])) {
|
|
$path = $form['#term']['path'];
|
|
if (!is_array($path)) {
|
|
$path = path_load(array('alias' => $path));
|
|
}
|
|
}
|
|
else {
|
|
$alias = path_load('taxonomy/term/' . $form['#term']['tid']);
|
|
// Since drupal_get_path_alias() can return the default path, check if we really have an alias.
|
|
if ($alias['alias'] != 'taxonomy/term/' . $form['#term']['tid']) {
|
|
$path = $alias;
|
|
}
|
|
else {
|
|
$path = NULL;
|
|
}
|
|
}
|
|
$form['#validate'][] = 'path_taxonomy_term_validate';
|
|
$form['#submit'][] = 'path_taxonomy_term_submit';
|
|
$form['identification']['path'] = array(
|
|
'#type' => 'textfield',
|
|
'#title' => t('URL alias'),
|
|
'#default_value' => $path['alias'],
|
|
'#maxlength' => 255,
|
|
'#weight' => 0,
|
|
'#access' => (user_access('create url aliases') || user_access('administer url aliases')),
|
|
'#description' => t("Optionally specify an alternative URL by which this term can be accessed. Use a relative path and don't add a trailing slash or the URL alias won't work."),
|
|
);
|
|
if ($path) {
|
|
// Populate with pid so we can update existing path entry instead of creating a new one.
|
|
$form['identification']['path']['pid'] = array(
|
|
'#type' => 'value',
|
|
'#access' => (user_access('create url aliases') || user_access('administer url aliases')),
|
|
'#value' => db_query("SELECT pid FROM {url_alias} WHERE alias = :alias", array(':alias' => $path['alias']))->fetchField(),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Path validation callback for taxonomy_form_term.
|
|
*/
|
|
function path_taxonomy_term_validate($form, &$form_state) {
|
|
$path = path_load(array('alias' => $form_state['values']['path']));
|
|
if ($path) {
|
|
// If the pid matches the one in use for this term then we are fine.
|
|
if (isset($form_state['values']['pid']) && $path['pid'] == $form_state['values']['pid']) {
|
|
return;
|
|
}
|
|
form_set_error('path', t('The URL alias is already in use.'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Path submission callback for taxonomy_form_term.
|
|
*/
|
|
function path_taxonomy_term_submit($form, &$form_state) {
|
|
// Make sure this is not triggered on the delete confirmation form.
|
|
if (empty($form_state['confirm_delete'])) {
|
|
$path = array(
|
|
'source' => 'taxonomy/term/' . $form_state['tid'],
|
|
'alias' => isset($form_state['values']['path']) ? $form_state['values']['path'] : NULL,
|
|
'pid' => isset($form_state['values']['pid']) ? $form_state['values']['pid'] : NULL,
|
|
);
|
|
path_save($path);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implement hook_permission().
|
|
*/
|
|
function path_permission() {
|
|
return array(
|
|
'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.'),
|
|
),
|
|
);
|
|
}
|