summaryrefslogtreecommitdiff
path: root/modules/path/path.module
diff options
context:
space:
mode:
Diffstat (limited to 'modules/path/path.module')
-rw-r--r--modules/path/path.module405
1 files changed, 203 insertions, 202 deletions
diff --git a/modules/path/path.module b/modules/path/path.module
index c2915bc42..ca3c16d55 100644
--- a/modules/path/path.module
+++ b/modules/path/path.module
@@ -22,14 +22,32 @@ function path_help($path, $arg) {
$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_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.'),
+ ),
+ );
+}
+
+/**
* Implement hook_menu().
*/
function path_menu() {
@@ -75,26 +93,34 @@ function path_menu() {
/**
* Fetch a specific URL alias from the database.
*
- * @param $criteria
+ * @param $conditions
* A string representing the source, a number representing the pid, or an
- * array of criteria.
+ * array of query conditions.
+ *
+ * @return
+ * FALSE if no alias was found or an associative array containing the
+ * following keys:
+ * - source: The internal system path.
+ * - alias: The URL alias.
+ * - pid: Unique path alias identifier.
+ * - language: The language of the alias.
*/
-function path_load($criteria) {
- if (is_numeric($criteria)) {
- $criteria = array('pid' => $criteria);
+function path_load($conditions) {
+ if (is_numeric($conditions)) {
+ $conditions = array('pid' => $conditions);
}
- else if (is_string($criteria)) {
- $criteria = array('source' => $criteria);
+ elseif (is_string($conditions)) {
+ $conditions = array('source' => $conditions);
}
- else if (!is_array($criteria)) {
+ elseif (!is_array($conditions)) {
return FALSE;
}
$select = db_select('url_alias');
- foreach ($criteria as $field => $value) {
+ foreach ($conditions as $field => $value) {
$select->condition($field, $value);
}
return $select
- ->fields('url_alias', array('source', 'alias', 'language', 'pid'))
+ ->fields('url_alias')
->execute()
->fetchAssoc();
}
@@ -103,38 +129,28 @@ function path_load($criteria) {
* 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).
+ * An associative array containing the following keys:
+ * - source: The internal system path.
+ * - alias: The URL alias.
+ * - pid: (optional) Unique path alias identifier.
+ * - language: (optional) The language of the alias.
*/
-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);
+function path_save(&$path) {
+ $path += array('pid' => NULL, 'language' => '');
- drupal_clear_path_cache();
- return $path;
+ // Insert or update the alias.
+ $status = drupal_write_record('url_alias', $path, (!empty($path['pid']) ? 'pid' : NULL));
+
+ // Verify that a record was written.
+ if (isset($status) && $status) {
+ if ($status === SAVED_NEW) {
+ module_invoke_all('path_insert', $path);
+ }
+ else {
+ module_invoke_all('path_update', $path);
+ }
+ drupal_clear_path_cache();
+ }
}
/**
@@ -148,51 +164,98 @@ function path_delete($criteria) {
$criteria = array('pid' => $criteria);
}
$path = path_load($criteria);
- $delete = db_delete('url_alias');
+ $query = db_delete('url_alias');
foreach ($criteria as $field => $value) {
- $delete->condition($field, $value);
+ $query->condition($field, $value);
}
- $delete->execute();
+ $query->execute();
module_invoke_all('path_delete', $path);
drupal_clear_path_cache();
}
/**
- * Implement hook_node_validate().
+ * Implement hook_form_alter().
*/
-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);
+function path_form_alter(&$form, $form_state, $form_id) {
+ if (!empty($form['#node_edit_form'])) {
+ $path = array();
+ if (!empty($form['#node']->nid)) {
+ $conditions = array('source' => 'node/' . $form['#node']->nid);
+ if (!empty($form['#node']->language)) {
+ $conditions['language'] = $form['#node']->language;
}
- if ($select->execute()->fetchField()) {
- form_set_error('path', t('The path is already in use.'));
+ $path = path_load($conditions);
+ if ($path === FALSE) {
+ $path = array();
}
}
+ $path += array(
+ 'pid' => NULL,
+ 'source' => isset($form['#node']->nid) ? 'node/' . $form['#node']->nid : NULL,
+ 'alias' => '',
+ 'language' => isset($form['#node']->language) ? $form['#node']->language : '',
+ );
+
+ $form['path'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('URL path settings'),
+ '#collapsible' => TRUE,
+ '#collapsed' => empty($path['alias']),
+ '#group' => 'additional_settings',
+ '#attached' => array(
+ 'js' => array(drupal_get_path('module', 'path') . '/path.js'),
+ ),
+ '#access' => user_access('create url aliases') || user_access('administer url aliases'),
+ '#weight' => 30,
+ '#tree' => TRUE,
+ '#element_validate' => array('path_form_element_validate'),
+ );
+ $form['path']['alias'] = array(
+ '#type' => 'textfield',
+ '#title' => t('URL alias'),
+ '#default_value' => $path['alias'],
+ '#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.'),
+ );
+ $form['path']['pid'] = array('#type' => 'value', '#value' => $path['pid']);
+ $form['path']['source'] = array('#type' => 'value', '#value' => $path['source']);
+ $form['path']['language'] = array('#type' => 'value', '#value' => $path['language']);
}
}
/**
- * Implement hook_node_load().
+ * Form element validation handler for URL alias form element.
*/
-function path_node_load($nodes, $types) {
- foreach ($nodes as $node) {
- $criteria = array('source' => 'node/' . $node->nid);
- if (isset($node->language)) {
- $criteria['language'] = $node->language;
+function path_form_element_validate($element, &$form_state, $complete_form) {
+ if (!empty($form_state['values']['path']['alias'])) {
+ // Trim the submitted value.
+ $alias = trim($form_state['values']['path']['alias']);
+ form_set_value($element['alias'], $alias, $form_state);
+ // Node language (Locale module) needs special care. Since the language of
+ // the URL alias depends on the node language, and the node language can be
+ // switched right within the same form, we need to conditionally overload
+ // the originally assigned URL alias language.
+ // @todo Remove this after converting Path module to a field, and, after
+ // stopping Locale module from abusing the content language system.
+ if (isset($form_state['values']['language'])) {
+ form_set_value($element['language'], $form_state['values']['language'], $form_state);
}
- $alias = path_load($criteria);
- if ($alias) {
- $node->path = $alias;
+
+ $path = $form_state['values']['path'];
+
+ // Ensure that the submitted alias does not exist yet.
+ $query = db_select('url_alias')
+ ->condition('alias', $path['alias'])
+ ->condition('language', $path['language']);
+ if (!empty($path['source'])) {
+ $query->condition('source', $path['source'], '<>');
+ }
+ $query->addExpression('1');
+ $query->range(0, 1);
+ if ($query->execute()->fetchField()) {
+ form_set_error('alias', t('The alias is already in use.'));
}
}
}
@@ -201,16 +264,16 @@ function path_node_load($nodes, $types) {
* 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);
+ if (isset($node->path)) {
+ $path = $node->path;
+ $path['alias'] = trim($path['alias']);
+ // Only save a non-empty alias.
+ if (!empty($path['alias'])) {
+ // Ensure fields for programmatic executions.
+ $path['source'] = 'node/' . $node->nid;
+ $path['language'] = isset($node->language) ? $node->language : '';
+ path_save($path);
}
-
- $node->path += array(
- 'source' => 'node/' . $node->nid,
- 'language' => isset($node->language) ? $node->language : '',
- );
- $node->path = path_save($node->path);
}
}
@@ -218,18 +281,20 @@ function path_node_insert($node) {
* 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->path)) {
+ $path = $node->path;
+ $path['alias'] = trim($path['alias']);
+ // Delete old alias if user erased it.
+ if (!empty($path['pid']) && empty($path['alias'])) {
+ path_delete($path['pid']);
}
- if (isset($node->pid)) {
- $node->path['pid'] = $node->pid;
+ // Only save a non-empty alias.
+ if (!empty($path['alias'])) {
+ // Ensure fields for programmatic executions.
+ $path['source'] = 'node/' . $node->nid;
+ $path['language'] = isset($node->language) ? $node->language : '';
+ path_save($path);
}
- $node->path += array(
- 'source' => 'node/' . $node->nid,
- 'language' => isset($node->language) ? $node->language : '',
- );
- path_save($node->path);
}
}
@@ -237,64 +302,8 @@ function path_node_update($node) {
* 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'],
- );
- }
- }
+ // Delete all aliases associated with this node.
+ path_delete(array('source' => 'node/' . $node->nid));
}
/**
@@ -303,86 +312,78 @@ function path_form_alter(&$form, $form_state, $form_id) {
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;
- }
+ $path = (isset($form['#term']['tid']) ? path_load('taxonomy/term/' . $form['#term']['tid']) : array());
+ if ($path === FALSE) {
+ $path = array();
}
- $form['#validate'][] = 'path_taxonomy_term_validate';
- $form['#submit'][] = 'path_taxonomy_term_submit';
+ $path += array(
+ 'pid' => NULL,
+ 'source' => isset($form['#term']['tid']) ? 'taxonomy/term/' . $form['#term']['tid'] : NULL,
+ 'alias' => '',
+ 'language' => '',
+ );
$form['identification']['path'] = array(
+ '#access' => user_access('create url aliases') || user_access('administer url aliases'),
+ '#tree' => TRUE,
+ '#element_validate' => array('path_form_element_validate'),
+ );
+ $form['identification']['path']['alias'] = 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(),
- );
- }
+ $form['identification']['path']['pid'] = array('#type' => 'value', '#value' => $path['pid']);
+ $form['identification']['path']['source'] = array('#type' => 'value', '#value' => $path['source']);
+ $form['identification']['path']['language'] = array('#type' => 'value', '#value' => $path['language']);
}
}
/**
- * Path validation callback for taxonomy_form_term.
+ * Implement hook_taxonomy_term_insert().
*/
-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;
+function path_taxonomy_term_insert($term) {
+ if (isset($term->path)) {
+ $path = $term->path;
+ $path['alias'] = trim($path['alias']);
+ // Only save a non-empty alias.
+ if (!empty($path['alias'])) {
+ // Ensure fields for programmatic executions.
+ $path['source'] = 'taxonomy/term/' . $term->tid;
+ $path['language'] = '';
+ path_save($path);
}
- form_set_error('path', t('The URL alias is already in use.'));
}
}
/**
- * Path submission callback for taxonomy_form_term.
+ * Implement hook_taxonomy_term_update().
*/
-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);
+function path_taxonomy_term_update($term) {
+ if (isset($term->path)) {
+ $path = $term->path;
+ $path['alias'] = trim($path['alias']);
+ // Delete old alias if user erased it.
+ if (!empty($path['pid']) && empty($path['alias'])) {
+ path_delete($path['pid']);
+ }
+ // Only save a non-empty alias.
+ if (!empty($path['alias'])) {
+ // Ensure fields for programmatic executions.
+ $path['source'] = 'taxonomy/term/' . $term->tid;
+ $path['language'] = '';
+ path_save($path);
+ }
}
}
/**
- * Implement hook_permission().
+ * Implement hook_taxonomy_term_delete().
*/
-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.'),
- ),
- );
+function path_taxonomy_term_delete($term) {
+ // Delete all aliases associated with this term.
+ path_delete(array('source' => 'taxonomy/term/' . $term->tid));
}
+