' . t('About') . '';
$output .= '
' . t('Provides a mechanism for modules to automatically generate aliases for the content they manage.') . '
';
$output .= '' . t('Settings') . '
';
$output .= '';
$output .= '- ' . t('Maximum alias and component length') . '
';
$output .= '- ' . t('The maximum alias length and maximum component length values default to 100 and have a limit of @max from Pathauto. This length is limited by the length of the "alias" column of the url_alias database table. The default database schema for this column is @max. If you set a length that is equal to that of the one set in the "alias" column it will cause problems in situations where the system needs to append additional words to the aliased URL. For example, URLs generated for feeds will have "/feed" added to the end. You should enter a value that is the length of the "alias" column minus the length of any strings that might get added to the end of the URL. The length of strings that might get added to the end of your URLs depends on which modules you have enabled and on your Pathauto settings. The recommended and default value is 100.', array('@max' => _pathauto_get_schema_alias_maxlength())) . '
';
$output .= '
';
return $output;
}
}
/**
* Implements hook_permission().
*/
function pathauto_permission() {
return array(
'administer pathauto' => array(
'title' => t('Administer pathauto'),
'description' => t('Allows a user to configure patterns for automated aliases and bulk delete URL-aliases.'),
),
'notify of path changes' => array(
'title' => t('Notify of Path Changes'),
'description' => t('Determines whether or not users are notified.'),
),
);
}
/**
* Implements hook_menu().
*/
function pathauto_menu() {
$items['admin/config/search/path/pathauto'] = array(
'title' => 'Automated alias settings',
'page callback' => 'drupal_get_form',
'page arguments' => array('pathauto_admin_settings'),
'access callback' => 'user_access',
'access arguments' => array('administer pathauto'),
'type' => MENU_LOCAL_TASK,
'weight' => 10,
'file' => 'pathauto.admin.inc',
);
$items['admin/config/search/path/delete_bulk'] = array(
'title' => 'Delete aliases',
'page callback' => 'drupal_get_form',
'page arguments' => array('pathauto_admin_delete'),
'access arguments' => array('administer url aliases'),
'type' => MENU_LOCAL_TASK,
'weight' => 11,
'file' => 'pathauto.admin.inc',
);
return $items;
}
/**
* Include all Pathauto include files.
*/
function _pathauto_include() {
module_load_include('inc', 'pathauto');
module_load_include('inc', 'pathauto', 'pathauto_node');
module_load_include('inc', 'pathauto', 'pathauto_taxonomy');
module_load_include('inc', 'pathauto', 'pathauto_user');
}
/**
* Implements hook_path_alias_types().
*
* Used primarily by the bulk delete form.
*/
function pathauto_path_alias_types() {
$objects = array('user/' => t('Users'), 'node/' => t('Content'));
if (module_exists('blog')) {
$objects['blog/'] = t('User blogs');
}
if (module_exists('taxonomy')) {
$objects['taxonomy/'] = t('Vocabularies and terms');
}
if (module_exists('tracker')) {
$objects['user/%/track'] = t('User trackers');
}
if (module_exists('forum')) {
$objects['forum/%'] = t('Forums');
}
return $objects;
}
//==============================================================================
// Some node related functions.
/**
* Implements hook_node_presave().
*/
function pathauto_node_presave($node) {
// About to be saved (before insert/update)
if (!empty($node->path['pathauto_perform_alias']) && isset($node->path['old_alias'])
&& $node->path['alias'] == '' && $node->path['old_alias'] != '') {
/**
* There was an old alias, but when pathauto_perform_alias was checked
* the javascript disabled the textbox which led to an empty value being
* submitted. Restoring the old path-value here prevents the Path module
* from deleting any old alias before Pathauto gets control.
*/
$node->path['alias'] = $node->path['old_alias'];
}
}
/**
* Implements hook_node_insert().
*/
function pathauto_node_insert($node) {
_pathauto_node_insert_update($node, 'insert');
}
/**
* Implements hook_node_update().
*/
function pathauto_node_update($node) {
_pathauto_node_insert_update($node, 'update');
}
/**
* Internal helper for node insert/update duplicate functionality.
*/
function _pathauto_node_insert_update($node, $op) {
_pathauto_include();
// Get the specific pattern or the default
if (variable_get('language_content_type_' . $node->type, 0)) {
$pattern = trim(variable_get('pathauto_node_' . $node->type . '_' . $node->language . '_pattern', FALSE));
}
if (empty($pattern)) {
$pattern = trim(variable_get('pathauto_node_' . $node->type . '_pattern', FALSE));
if (empty($pattern)) {
$pattern = trim(variable_get('pathauto_node_pattern', FALSE));
}
}
// Only do work if there's a pattern
if ($pattern) {
// Only create an alias if the checkbox was not provided or if the checkbox was provided and is checked
if (!isset($node->path['pathauto_perform_alias']) || $node->path['pathauto_perform_alias']) {
$source = "node/$node->nid";
$alias = pathauto_create_alias('node', $op, $source, array('node' => $node), $node->type, $node->language);
}
}
}
/**
* Implements hook_node_delete().
*/
function pathauto_node_delete($node) {
path_delete(array('source' => 'node/' . $node->nid));
path_delete(array('source' => 'node/' . $node->nid . '/feed'));
}
/**
* Implements hook_form_alter().
*
* This allows alias creators to override Pathauto and specify their
* own aliases (Pathauto will be invisible to other users). Inserted
* into the path module's fieldset in the node form.
*/
function pathauto_form_alter(&$form, &$form_state, $form_id) {
// Only do this for node forms
if (!empty($form['#node_edit_form'])) {
$node = $form['#node'];
$pattern = FALSE;
// Find if there is an automatic alias pattern for this node type.
if (isset($form['language'])) {
$language = isset($form['language']['#value']) ? $form['language']['#value'] : $form['language']['#default_value'];
$pattern = trim(variable_get('pathauto_node_' . $form['type']['#value'] . '_' . $language . '_pattern', ''));
}
if (!$pattern) {
$pattern = trim(variable_get('pathauto_node_' . $form['type']['#value'] . '_pattern', ''));
if (!$pattern) {
$pattern = trim(variable_get('pathauto_node_pattern', ''));
}
}
// If there is a pattern, show the automatic alias checkbox.
if ($pattern) {
if (!isset($node->pathauto_perform_alias)) {
if (!empty($node->nid)) {
// If this is not a new node, compare it's current alias to the
// alias that would be genereted by pathauto. If they are the same,
// then keep the automatic alias enabled.
_pathauto_include();
$path = path_load(array('source' => 'node/' . $node->nid));
$pathauto_alias = pathauto_create_alias('node', 'return', "node/{$node->nid}", array('node' => $node), $node->type, $node->language);
$node->pathauto_perform_alias = !empty($path['alias']) && $path['alias'] == $pathauto_alias;
}
else {
// If this is a new node, enable the automatic alias.
$node->pathauto_perform_alias = TRUE;
}
}
// Add JavaScript that will disable the path textfield when the automatic
// alias checkbox is checked.
$form['path']['alias']['#states']['!enabled']['input[name="path[pathauto_perform_alias]"]'] = array('checked' => TRUE);
// Override path.module's vertical tabs summary.
$form['path']['#attached']['js'] = array(
'vertical-tabs' => drupal_get_path('module', 'pathauto') . '/pathauto.js'
);
$form['path']['pathauto_perform_alias'] = array(
'#type' => 'checkbox',
'#title' => t('Automatic alias'),
'#default_value' => $node->pathauto_perform_alias,
'#description' => t('An alias will be generated for you. If you wish to create your own alias below, uncheck this option.'),
'#weight' => -1,
);
if (user_access('administer pathauto')) {
$form['path']['pathauto_perform_alias']['#description'] .= ' ' . t('To control the format of the generated aliases, see the automated alias settings.', array('@pathauto' => url('admin/config/search/path/pathauto')));
}
if ($node->pathauto_perform_alias && !empty($node->old_alias) && empty($path['alias'])) {
$form['path']['alias']['#default_value'] = $node->old_alias;
$path['alias'] = $node->old_alias;
}
// For Pathauto to remember the old alias and prevent the Path-module from deleteing it when Pathauto wants to preserve it
if (!empty($path['alias'])) {
$form['path']['old_alias'] = array(
'#type' => 'value',
'#value' => $path['alias'],
);
}
}
}
}
/**
* Implements hook_node_operations().
*/
function pathauto_node_operations() {
$operations = array(
'update_alias' => array(
'label' => t('Update path alias'),
'callback' => 'pathauto_node_operations_update',
),
);
return $operations;
}
/**
* Callback function for updating node aliases.
*
* @param $nodes
* Array of node nid's.
*/
function pathauto_node_operations_update($nodes) {
_pathauto_include();
$nodes = node_load_multiple($nodes);
foreach ($nodes as $node) {
pathauto_create_alias('node', 'bulkupdate', "node/$node->nid", array('node' => $node), $node->type, $node->language);
}
}
//==============================================================================
// Taxonomy related functions.
/**
* Implements hook_taxonomy_term_insert().
*/
function pathauto_taxonomy_term_insert($term) {
// taxonomy.tokens.inc expects a description
if (!isset($term->description)) {
$term->description = NULL;
}
_pathauto_taxonomy_term_insert_update($term, 'insert');
}
/**
* Implements hook_taxonomy_term_update().
*/
function pathauto_taxonomy_term_update($term) {
_pathauto_taxonomy_term_insert_update($term, 'update');
}
/**
* Internal helper for taxonomy term insert/update duplicate functionality
*/
function _pathauto_taxonomy_term_insert_update($term, $op) {
_pathauto_include();
if ($term->name) {
$count = _taxonomy_pathauto_alias($term, $op);
}
// For all children generate new alias (important if [catpath] used)
foreach (taxonomy_get_tree($term->vid, $term->tid) as $subterm) {
$count = _taxonomy_pathauto_alias($subterm, $op);
}
}
/**
* Implements hook_taxonomy_term_delete().
*/
function pathauto_taxonomy_term_delete($term) {
path_delete(array('source' => 'taxonomy/term/' . $term->tid));
path_delete(array('source' => 'forum/' . $term->tid));
path_delete(array('source' => 'taxonomy/term/' . $term->tid . '/0/feed'));
}
//==============================================================================
// User related functions. For users, trackers, and blogs.
/**
* Implements hook_user_insert().
*/
function pathauto_user_insert(&$edit, $account, $category) {
_pathauto_user_insert_update($edit, $account, $category, 'insert');
}
/**
* Implements hook_user_update().
*/
function pathauto_user_update(&$edit, $account, $category) {
_pathauto_user_insert_update($edit, $account, $category, 'update');
}
/**
* Internal helper for user insert/update duplicate functionality.
*/
function _pathauto_user_insert_update(&$edit, $account, $category, $op) {
_pathauto_include();
// Use the username to automatically create an alias
$pathauto_user = (object) array_merge((array) $account, $edit);
if ($pathauto_user->name) {
$source = 'user/' . $pathauto_user->uid;
$alias = pathauto_create_alias('user', $op, $source, array('user' => $pathauto_user));
if (module_exists('blog')) {
$new_user = clone $pathauto_user;
if ($category == 'account') {
$new_user->roles = isset($edit['roles']) ? $edit['roles'] : array();
$new_user->roles[DRUPAL_AUTHENTICATED_RID] = t('authenticated user'); // Add this back
}
if (node_access('create', 'blog', $new_user)) {
$source = 'blog/' . $new_user->uid;
$alias = pathauto_create_alias('blog', $op, $source, array('user' => $new_user));
}
else {
path_delete(array('source' => 'blog/' . $new_user->uid));
path_delete(array('source' => 'blog/' . $new_user->uid . '/feed'));
}
}
if (module_exists('tracker')) {
$source = 'user/' . $new_user->uid . '/track';
$alias = pathauto_create_alias('tracker', $op, $source, array('user' => $new_user));
}
if (module_exists('contact')) {
$source = 'user/' . $new_user->uid . '/contact';
$alias = pathauto_create_alias('contact', $op, $source, array('user' => $new_user));
}
}
}
/**
* Implements hook_user_delete().
*/
function pathauto_user_cancel($edit, $account, $method) {
switch ($method) {
case 'user_cancel_block':
case 'user_cancel_block_unpublish':
// Don't remove aliases because the user may become active again later.
break;
case 'user_cancel_reassign':
case 'user_cancel_delete':
// Remove the users's path aliases
$user = (object) $account;
path_delete(array('source' => 'user/' . $user->uid));
// They may have enabled these modules and/or feeds when the user was created, so let's try to delete all of them
path_delete(array('source' => 'blog/' . $user->uid));
path_delete(array('source' => 'blog/' . $user->uid . '/feed'));
path_delete(array('source' => 'user/' . $user->uid . '/track'));
path_delete(array('source' => 'user/' . $user->uid . '/track/feed'));
path_delete(array('source' => 'user/' . $user->uid . '/contact'));
break;
}
}