diff --git a/INSTALL.txt b/INSTALL.txt
deleted file mode 100644
index 586fdfe..0000000
--- a/INSTALL.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-**Installation:
-
-Pathauto is an extension to the path module, which must be enabled.
-
-Pathauto also relies on the Token module, which must be downloaded and
-enabled separately.
-
-1. Unpack the Pathauto folder and contents in the appropriate modules
-directory of your Drupal installation. This is probably
- sites/all/modules/
-2. Enable the Pathauto module in the administration tools.
-3. If you're not using Drupal's default administrative account, make
-sure "administer pathauto" is enabled through access control administration.
-4. Visit the Pathauto settings page and make appropriate configurations
- For 5.x: Administer > Site configuration > Pathauto
- For 6.x: Administer > Site building > URL alias > Automated alias settings
-
-**Transliteration support:
-If you desire transliteration support in the creation of URLs (e.g. the
-replacement of Á with A) then you will need to install the Transliteration
-module, which can be found at http://drupal.org/project/transliteration
-
-Once you've installed and enabled the module, simply go to
-admin/config/search/path/settings and check the "Transliterate prior to
-creating alias" box and path aliases should now be transliterated automagically.
-
-**Upgrading from previous versions:
-If you are upgrading from Pathauto 5.x-1.x to 5.x-2.x (or 6.x-2.x) then you
-will probably need to change your patterns.
-
-For content patterns:
- [user] is now [author-name]
- [cat] is now [term]
-
-There may be other changes as well. Please review the pattern examples on
- Administration > Site Configuration > Pathauto
-
-If you upgraded from Pathauto 5.x-1.x directly without enabling Token
-first then you will need to
- 1) download/install the Token module
- 2) disable the Pathauto module
- 3) re-enable the Pathauto module
-
-Upgrade to 6.x:
-Note that the settings page has moved so that it is more logically grouped with
-other URL alias related items under
- Administer > Site building > URL alias > Automated alias settings
-
diff --git a/README.txt b/README.txt
deleted file mode 100644
index fc56959..0000000
--- a/README.txt
+++ /dev/null
@@ -1,81 +0,0 @@
-Please read this file and also the INSTALL.txt.
-They contain answers to many common questions.
-If you are developing for this module, the API.txt may be interesting.
-If you are upgrading, check the CHANGELOG.txt for major changes.
-
-** Description:
-The Pathauto module provides support functions for other modules to
-automatically generate aliases based on appropriate criteria, with a
-central settings path for site administrators.
-
-Implementations are provided for core entity types: content, taxonomy terms,
-and users (including blogs and forum pages).
-
-Pathauto also provides a way to delete large numbers of aliases. This feature
-is available at Administer > Configuration > Search and metadata > URL aliases
-> Delete aliases.
-
-** Benefits:
-Besides making the page address more reflective of its content than
-"node/138", it's important to know that modern search engines give
-heavy weight to search terms which appear in a page's URL. By
-automatically using keywords based directly on the page content in the URL,
-relevant search engine hits for your page can be significantly
-enhanced.
-
-** Installation AND Upgrades:
-See the INSTALL.txt file.
-
-** Notices:
-Pathauto just adds URL aliases to content, users, and taxonomy terms.
-Because it's an alias, the standard Drupal URL (for example node/123 or
-taxonomy/term/1) will still function as normal. If you have external links
-to your site pointing to standard Drupal URLs, or hardcoded links in a module,
-template, content or menu which point to standard Drupal URLs it will bypass
-the alias set by Pathauto.
-
-There are reasons you might not want two URLs for the same content on your
-site. If this applies to you, please note that you will need to update any
-hard coded links in your content or blocks.
-
-If you use the "system path" (i.e. node/10) for menu items and settings like
-that, Drupal will replace it with the url_alias.
-
-For external links, you might want to consider the Path Redirect or
-Global Redirect modules, which allow you to set forwarding either per item or
-across the site to your aliased URLs.
-
-URLs (not) Getting Replaced With Aliases:
-Please bear in mind that only URLs passed through Drupal's l() or url()
-functions will be replaced with their aliases during page output. If a module
-or your template contains hardcoded links, such as 'href="node/$node->nid"'
-those won't get replaced with their corresponding aliases. Use the
-Drupal API instead:
-
-* 'href="'. url("node/$node->nid") .'"' or
-* l("Your link title", "node/$node->nid")
-
-See http://api.drupal.org/api/HEAD/function/url and
-http://api.drupal.org/api/HEAD/function/l for more information.
-
-** Disabling Pathauto for a specific content type (or taxonomy)
-When the pattern for a content type is left blank, the default pattern will be
-used. But if the default pattern is also blank, Pathauto will be disabled
-for that content type.
-
-** Credits:
-The original module combined the functionality of Mike Ryan's autopath with
-Tommy Sundstrom's path_automatic.
-
-Significant enhancements were contributed by jdmquin @ www.bcdems.net.
-
-Matt England added the tracker support (tracker support has been removed in
-recent changes).
-
-Other suggestions and patches contributed by the Drupal community.
-
-Current maintainers:
- Dave Reid - http://www.davereid.net
- Greg Knaddison - http://www.knaddison.com
- Mike Ryan - http://mikeryan.name
- Frederik 'Freso' S. Olesen - http://freso.dk
diff --git a/pathauto.admin.inc b/pathauto.admin.inc
deleted file mode 100644
index b8679dd..0000000
--- a/pathauto.admin.inc
+++ /dev/null
@@ -1,437 +0,0 @@
-module;
- $patterndescr = $settings->patterndescr;
- $patterndefault = $settings->patterndefault;
- $groupheader = $settings->groupheader;
-
- $form[$module] = array(
- '#type' => 'fieldset',
- '#title' => $groupheader,
- '#collapsible' => TRUE,
- '#collapsed' => FALSE,
- );
-
- // Prompt for the default pattern for this module
- $variable = 'pathauto_' . $module . '_pattern';
- $form[$module][$variable] = array(
- '#type' => 'textfield',
- '#title' => $patterndescr,
- '#default_value' => variable_get($variable, $patterndefault),
- '#size' => 65,
- '#maxlength' => 1280,
- '#element_validate' => array('token_element_validate'),
- '#after_build' => array('token_element_validate'),
- '#token_types' => array($settings->token_type),
- '#min_tokens' => 1,
- '#parents' => array($variable),
- );
-
- // If the module supports a set of specialized patterns, set
- // them up here
- if (isset($settings->patternitems)) {
- foreach ($settings->patternitems as $itemname => $itemlabel) {
- $variable = 'pathauto_' . $module . '_' . $itemname . '_pattern';
- $form[$module][$variable] = array(
- '#type' => 'textfield',
- '#title' => $itemlabel,
- '#default_value' => variable_get($variable, ''),
- '#size' => 65,
- '#maxlength' => 1280,
- '#element_validate' => array('token_element_validate'),
- '#after_build' => array('token_element_validate'),
- '#token_types' => array($settings->token_type),
- '#min_tokens' => 1,
- '#parents' => array($variable),
- );
- }
- }
-
- // Display the user documentation of placeholders supported by
- // this module, as a description on the last pattern
- $form[$module]['token_help'] = array(
- '#title' => t('Replacement patterns'),
- '#type' => 'fieldset',
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- );
- $form[$module]['token_help']['help'] = array(
- '#theme' => 'token_tree',
- '#token_types' => array($settings->token_type),
- );
- }
-
- return system_settings_form($form);
-}
-
-/**
- * Form builder; Configure the Pathauto settings.
- *
- * @ingroup forms
- * @see system_settings_form()
- */
-function pathauto_settings_form($form) {
- module_load_include('inc', 'pathauto');
-
- $form['pathauto_verbose'] = array(
- '#type' => 'checkbox',
- '#title' => t('Verbose'),
- '#default_value' => variable_get('pathauto_verbose', FALSE),
- '#description' => t('Display alias changes (except during bulk updates).'),
- );
-
- $form['pathauto_separator'] = array(
- '#type' => 'textfield',
- '#title' => t('Separator'),
- '#size' => 1,
- '#maxlength' => 1,
- '#default_value' => variable_get('pathauto_separator', '-'),
- '#description' => t('Character used to separate words in titles. This will replace any spaces and punctuation characters. Using a space or + character can cause unexpected results.'),
- );
-
- $form['pathauto_case'] = array(
- '#type' => 'radios',
- '#title' => t('Character case'),
- '#default_value' => variable_get('pathauto_case', PATHAUTO_CASE_LOWER),
- '#options' => array(
- PATHAUTO_CASE_LEAVE_ASIS => t('Leave case the same as source token values.'),
- PATHAUTO_CASE_LOWER => t('Change to lower case'),
- ),
- );
-
- $max_length = _pathauto_get_schema_alias_maxlength();
-
- $form['pathauto_max_length'] = array(
- '#type' => 'textfield',
- '#title' => t('Maximum alias length'),
- '#size' => 3,
- '#maxlength' => 3,
- '#default_value' => variable_get('pathauto_max_length', 100),
- '#min_value' => 1,
- '#max_value' => $max_length,
- '#description' => t('Maximum length of aliases to generate. 100 is the recommended length. @max is the maximum possible length. See Pathauto help for details.', array('@pathauto-help' => url('admin/help/pathauto'), '@max' => $max_length)),
- '#element_validate' => array('_pathauto_validate_numeric_element'),
- );
- $form['pathauto_max_component_length'] = array(
- '#type' => 'textfield',
- '#title' => t('Maximum component length'),
- '#size' => 3,
- '#maxlength' => 3,
- '#default_value' => variable_get('pathauto_max_component_length', 100),
- '#min_value' => 1,
- '#max_value' => $max_length,
- '#description' => t('Maximum text length of any component in the alias (e.g., [title]). 100 is the recommended length. @max is the maximum possible length. See Pathauto help for details.', array('@pathauto-help' => url('admin/help/pathauto'), '@max' => $max_length)),
- '#element_validate' => array('_pathauto_validate_numeric_element'),
- );
-
-
- $description = t('What should Pathauto do when updating an existing content item which already has an alias?');
- if (module_exists('redirect')) {
- $description .= ' ' . t('The Redirect module settings affect whether a redirect is created when an alias is deleted.', array('!url' => url('admin/config/search/redirect/settings')));
- }
- else {
- $description .= ' ' . t('Considering installing the Redirect module to get redirects when your aliases change.', array('!url' => 'http://drupal.org/project/redirect'));
- }
- $form['pathauto_update_action'] = array(
- '#type' => 'radios',
- '#title' => t('Update action'),
- '#default_value' => variable_get('pathauto_update_action', PATHAUTO_UPDATE_ACTION_DELETE),
- '#options' => array(
- PATHAUTO_UPDATE_ACTION_NO_NEW => t('Do nothing. Leave the old alias intact.'),
- PATHAUTO_UPDATE_ACTION_LEAVE => t('Create a new alias. Leave the existing alias functioning.'),
- PATHAUTO_UPDATE_ACTION_DELETE => t('Create a new alias. Delete the old alias.'),
- ),
- '#description' => $description,
- );
-
- $form['pathauto_transliterate'] = array(
- '#type' => 'checkbox',
- '#title' => t('Transliterate prior to creating alias'),
- '#default_value' => variable_get('pathauto_transliterate', FALSE) && module_exists('transliteration'),
- '#description' => t('When a pattern includes certain characters (such as those with accents) should Pathauto attempt to transliterate them into the US-ASCII alphabet? Transliteration is handled by the Transliteration module.'),
- '#access' => module_exists('transliteration'),
- );
-
- $form['pathauto_reduce_ascii'] = array(
- '#type' => 'checkbox',
- '#title' => t('Reduce strings to letters and numbers'),
- '#default_value' => variable_get('pathauto_reduce_ascii', FALSE),
- '#description' => t('Filters the new alias to only letters and numbers found in the ASCII-96 set.'),
- );
-
- $form['pathauto_ignore_words'] = array(
- '#type' => 'textarea',
- '#title' => t('Strings to Remove'),
- '#default_value' => variable_get('pathauto_ignore_words', PATHAUTO_IGNORE_WORDS),
- '#description' => t('Words to strip out of the URL alias, separated by commas. Do not use this to remove punctuation.'),
- '#wysiwyg' => FALSE,
- );
-
- $form['punctuation'] = array(
- '#type' => 'fieldset',
- '#title' => t('Punctuation'),
- '#collapsible' => TRUE,
- '#collapsed' => TRUE,
- );
-
- $punctuation = pathauto_punctuation_chars();
- foreach ($punctuation as $name => $details) {
- $details['default'] = PATHAUTO_PUNCTUATION_REMOVE;
- if ($details['value'] == variable_get('pathauto_separator', '-')) {
- $details['default'] = PATHAUTO_PUNCTUATION_REPLACE;
- }
- $form['punctuation']['pathauto_punctuation_' . $name] = array(
- '#type' => 'select',
- '#title' => $details['name'] . ' (' . check_plain($details['value']) . '
)',
- '#default_value' => variable_get('pathauto_punctuation_' . $name, $details['default']),
- '#options' => array(
- PATHAUTO_PUNCTUATION_REMOVE => t('Remove'),
- PATHAUTO_PUNCTUATION_REPLACE => t('Replace by separator'),
- PATHAUTO_PUNCTUATION_DO_NOTHING => t('No action (do not replace)'),
- ),
- );
- }
-
- return system_settings_form($form);
-}
-
-/**
- * Validate a form element that should have an numeric value.
- */
-function _pathauto_validate_numeric_element($element, &$form_state) {
- $value = $element['#value'];
-
- if (!is_numeric($value)) {
- form_error($element, t('The field %name is not a valid number.', array('%name' => $element['#title'])));
- }
- elseif (isset($element['#max_value']) && $value > $element['#max_value']) {
- form_error($element, t('The field %name cannot be greater than @max.', array('%name' => $element['#title'], '@max' => $element['#max_value'])));
- }
- elseif (isset($element['#min_value']) && $value < $element['#min_value']) {
- form_error($element, t('The field %name cannot be less than @min.', array('%name' => $element['#title'], '@min' => $element['#min_value'])));
- }
-}
-
-/**
- * Validate pathauto_settings_form form submissions.
- */
-function pathauto_settings_form_validate($form, &$form_state) {
- module_load_include('inc', 'pathauto');
-
- // Perform a basic check for HTML characters in the strings to remove field.
- if (strip_tags($form_state['values']['pathauto_ignore_words']) != $form_state['values']['pathauto_ignore_words']) {
- form_set_error('pathauto_ignore_words', t('The Strings to remove field must not contain HTML. Make sure to disable any WYSIWYG editors for this field.'));
- }
-
- // Validate that the separator is not set to be removed per http://drupal.org/node/184119
- // This isn't really all that bad so warn, but still allow them to save the value.
- $separator = $form_state['values']['pathauto_separator'];
- $punctuation = pathauto_punctuation_chars();
- foreach ($punctuation as $name => $details) {
- if ($details['value'] == $separator) {
- $action = $form_state['values']['pathauto_punctuation_' . $name];
- if ($action == PATHAUTO_PUNCTUATION_REMOVE) {
- drupal_set_message(t('You have configured the @name to be the separator and to be removed when encountered in strings. This can cause problems with your patterns and especially with the term:path token. You should probably set the action for @name to be "replace by separator".', array('@name' => $details['name'])), 'error');
- }
- }
- }
-}
-
-/**
- * Form contructor for path alias bulk update form.
- *
- * @see pathauto_bulk_update_form_submit()
- * @ingroup forms
- */
-function pathauto_bulk_update_form() {
- $form['#update_callbacks'] = array();
-
- $form['update'] = array(
- '#type' => 'checkboxes',
- '#title' => t('Select the types of un-aliased paths for which to generate URL aliases'),
- '#options' => array(),
- '#default_value' => array(),
- );
-
- $pathauto_settings = module_invoke_all('pathauto', 'settings');
- foreach ($pathauto_settings as $settings) {
- if (!empty($settings->batch_update_callback)) {
- $form['#update_callbacks'][$settings->batch_update_callback] = $settings;
- $form['update']['#options'][$settings->batch_update_callback] = $settings->groupheader;
- }
- }
-
- $form['actions']['#type'] = 'actions';
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Update'),
- );
-
- return $form;
-}
-
-/**
- * Form submit handler for path alias bulk update form.
- *
- * @see pathauto_batch_update_form()
- * @see pathauto_bulk_update_batch_finished()
- */
-function pathauto_bulk_update_form_submit($form, &$form_state) {
- $batch = array(
- 'title' => t('Bulk updating URL aliases'),
- 'operations' => array(
- array('pathauto_bulk_update_batch_start', array()),
- ),
- 'finished' => 'pathauto_bulk_update_batch_finished',
- 'file' => drupal_get_path('module', 'pathauto') . '/pathauto.admin.inc',
- );
-
- foreach ($form_state['values']['update'] as $callback) {
- if (!empty($callback)) {
- $settings = $form['#update_callbacks'][$callback];
- if (!empty($settings->batch_file)) {
- $batch['operations'][] = array('pathauto_bulk_update_batch_process', array($callback, $settings));
- }
- else {
- $batch['operations'][] = array($callback, array());
- }
- }
- }
-
- batch_set($batch);
-}
-
-/**
- * Batch callback; count the current number of URL aliases for comparison later.
- */
-function pathauto_bulk_update_batch_start(&$context) {
- $context['results']['count_before'] = db_select('url_alias')->countQuery()->execute()->fetchField();
-}
-
-/**
- * Common batch processing callback for all operations.
- *
- * Required to load our include the proper batch file.
- */
-function pathauto_bulk_update_batch_process($callback, $settings, &$context) {
- if (!empty($settings->batch_file)) {
- require_once DRUPAL_ROOT . '/' . $settings->batch_file;
- }
- return $callback($context);
-}
-
-/**
- * Batch finished callback.
- */
-function pathauto_bulk_update_batch_finished($success, $results, $operations) {
- if ($success) {
- // Count the current number of URL aliases after the batch is completed
- // and compare to the count before the batch started.
- $results['count_after'] = db_select('url_alias')->countQuery()->execute()->fetchField();
- $results['count_changed'] = max($results['count_after'] - $results['count_before'], 0);
- if ($results['count_changed']) {
- drupal_set_message(format_plural($results['count_changed'], 'Generated 1 URL alias.', 'Generated @count URL aliases.'));
- }
- else {
- drupal_set_message(t('No new URL aliases to generate.'));
- }
- }
- else {
- $error_operation = reset($operations);
- drupal_set_message(t('An error occurred while processing @operation with arguments : @args', array('@operation' => $error_operation[0], '@args' => print_r($error_operation[0], TRUE))));
- }
-}
-
-/**
- * Menu callback; select certain alias types to delete.
- */
-function pathauto_admin_delete() {
- /* TODO:
- 1) all - DONE
- 2) all node aliases - DONE
- 4) all user aliases - DONE
- 5) all taxonomy aliases - DONE
- 6) by node type
- 7) by taxonomy vocabulary
- 8) no longer existing aliases (see http://drupal.org/node/128366 )
- 9) where src like 'pattern' - DON'T DO
- 10) where dst like 'pattern' - DON'T DO
- */
-
- $form['delete'] = array(
- '#type' => 'fieldset',
- '#title' => t('Choose aliases to delete'),
- '#collapsible' => FALSE,
- '#collapsed' => FALSE,
- );
-
- // First we do the "all" case
- $total_count = db_query('SELECT count(1) FROM {url_alias}')->fetchField();
- $form['delete']['all_aliases'] = array(
- '#type' => 'checkbox',
- '#title' => t('All aliases'),
- '#default_value' => FALSE,
- '#description' => t('Delete all aliases. Number of aliases which will be deleted: %count.', array('%count' => $total_count)),
- );
-
- // Next, iterate over an array of objects/alias types which can be deleted and provide checkboxes
- $objects = module_invoke_all('path_alias_types');
- foreach ($objects as $internal_name => $label) {
- $count = db_query("SELECT count(1) FROM {url_alias} WHERE source LIKE :src", array(':src' => "$internal_name%"))->fetchField();
- $form['delete'][$internal_name] = array(
- '#type' => 'checkbox',
- '#title' => $label, // This label is sent through t() in the hard coded function where it is defined
- '#default_value' => FALSE,
- '#description' => t('Delete aliases for all @label. Number of aliases which will be deleted: %count.', array('@label' => $label, '%count' => $count)),
- );
- }
-
- // Warn them and give a button that shows we mean business
- $form['warning'] = array('#value' => '
' . t('Note: there is no confirmation. Be sure of your action before clicking the "Delete aliases now!" button.
You may want to make a backup of the database and/or the url_alias table prior to using this feature.') . '
' . t('Provides a mechanism for modules to automatically generate aliases for the content they manage.') . '
'; $output .= '' . t('Bulk generation will only generate URL aliases for items that currently have no aliases. This is typically used when installing Pathauto on a site that has existing un-aliased content that needs to be aliased in bulk.') . '
'; 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/patterns'] = array( - 'title' => 'Patterns', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('pathauto_patterns_form'), - 'access arguments' => array('administer pathauto'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 10, - 'file' => 'pathauto.admin.inc', - ); - $items['admin/config/search/path/settings'] = array( - 'title' => 'Settings', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('pathauto_settings_form'), - 'access arguments' => array('administer pathauto'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 20, - 'file' => 'pathauto.admin.inc', - ); - $items['admin/config/search/path/update_bulk'] = array( - 'title' => 'Bulk generate', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('pathauto_bulk_update_form'), - 'access arguments' => array('administer url aliases'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 30, - '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' => 40, - 'file' => 'pathauto.admin.inc', - ); - - return $items; -} - -/** - * Load an URL alias pattern by entity, bundle, and language. - * - * @param $entity - * An entity (e.g. node, taxonomy, user, etc.) - * @param $bundle - * A bundle (e.g. content type, vocabulary ID, etc.) - * @param $language - * A language code, defaults to the LANGUAGE_NONE constant. - */ -function pathauto_pattern_load_by_entity($entity, $bundle = '', $language = LANGUAGE_NONE) { - $patterns = &drupal_static(__FUNCTION__, array()); - - $pattern_id = "$entity:$bundle:$language"; - if (!isset($patterns[$pattern_id])) { - $variables = array(); - if ($language != LANGUAGE_NONE) { - $variables[] = "pathauto_{$entity}_{$bundle}_{$language}_pattern"; - } - if ($bundle) { - $variables[] = "pathauto_{$entity}_{$bundle}_pattern"; - } - $variables[] = "pathauto_{$entity}_pattern"; - - foreach ($variables as $variable) { - if ($pattern = trim(variable_get($variable, ''))) { - break; - } - } - - $patterns[$pattern_id] = $pattern; - } - - return $patterns[$pattern_id]; -} - -/** - * Delete multiple URL aliases. - * - * Intent of this is to abstract a potential path_delete_multiple() function - * for Drupal 7 or 8. - * - * @param $pids - * An array of path IDs to delete. + * Implements hook_entity_bundle_rename(). */ -function pathauto_path_delete_multiple($pids) { - foreach ($pids as $pid) { - path_delete(array('pid' => $pid)); - } -} +function pathauto_entity_bundle_rename($entity_type_id, $bundle_old, $bundle_new) { + $config = \Drupal::configFactory()->getEditable('pathauto.pattern'); + $bundle_settings = $config->get('patterns.' . $entity_type_id . '.bundles'); -/** - * Delete an URL alias and any of its sub-paths. - * - * Given a source like 'node/1' this function will delete any alias that have - * that specific source or any sources that match 'node/1/%'. - * - * @param $source - * An string with a source URL path. - */ -function pathauto_path_delete_all($source) { - $sql = "SELECT pid FROM {url_alias} WHERE source = :source OR source LIKE :source_wildcard"; - $pids = db_query($sql, array(':source' => $source, ':source_wildcard' => $source . '/%'))->fetchCol(); - if ($pids) { - pathauto_path_delete_multiple($pids); + if (isset($bundle_settings[$bundle_old])) { + $bundle_settings[$bundle_new] = $bundle_settings[$bundle_old]; + unset($bundle_settings[$bundle_old]); + $config->set('patterns.' . $entity_type_id . '.bundles', $bundle_settings); + $config->save(); } } /** - * Delete an entity URL alias and any of its sub-paths. - * - * This function also checks to see if the default entity URI is different from - * the current entity URI and will delete any of the default aliases. - * - * @param $entity_type - * A string with the entity type. - * @param $entity - * An entity object. - * @param $default_uri - * The optional default uri path for the entity. + * Implements hook__entity_bundle_delete(). */ -function pathauto_entity_path_delete_all($entity_type, $entity, $default_uri = NULL) { - $uri = entity_uri($entity_type, $entity); - pathauto_path_delete_all($uri['path']); - if (isset($default_uri) && $uri['path'] != $default_uri) { - pathauto_path_delete_all($default_uri); - } +function pathauto_entity_bundle_delete($entity_type, $bundle) { + $config = \Drupal::configFactory()->getEditable('pathauto.pattern'); + $config->clear('patterns.' . $entity_type . '.bundles.' . $bundle); + $config->save(); } -/** - * Implements hook_field_attach_rename_bundle(). - * - * Respond to machine name changes for pattern variables. - */ -function pathauto_field_attach_rename_bundle($entity_type, $bundle_old, $bundle_new) { - $variables = db_select('variable', 'v') - ->fields('v', array('name')) - ->condition('name', db_like("pathauto_{$entity_type}_{$bundle_old}_") . '%', 'LIKE') - ->execute() - ->fetchCol(); - foreach ($variables as $variable) { - $value = variable_get($variable, ''); - variable_del($variable); - $variable = strtr($variable, array("{$entity_type}_{$bundle_old}" => "{$entity_type}_{$bundle_new}")); - variable_set($variable, $value); - } -} /** - * Implements hook_field_attach_delete_bundle(). - * - * Respond to sub-types being deleted, their patterns can be removed. - */ -function pathauto_field_attach_delete_bundle($entity_type, $bundle) { - $variables = db_select('variable', 'v') - ->fields('v', array('name')) - ->condition('name', db_like("pathauto_{$entity_type}_{$bundle}_") . '%', 'LIKE') - ->execute() - ->fetchCol(); - foreach ($variables as $variable) { - variable_del($variable); - } -} - -/** - * Implements hook_field_attach_form(). - * - * Add the automatic alias form elements to an existing path form fieldset. + * Implements hook_entity_presave(). */ -function pathauto_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) { - list($id, , $bundle) = entity_extract_ids($entity_type, $entity); - - if (!isset($form['path'])) { - // This entity must be supported by core's path.module first. - // @todo Investigate removing this and supporting all fieldable entities. - return; - } - else { - // Taxonomy terms do not have an actual fieldset for path settings. - // Merge in the defaults. - $form['path'] += array( - '#type' => 'fieldset', - '#title' => t('URL path settings'), - '#collapsible' => TRUE, - '#collapsed' => empty($form['path']['alias']), - '#group' => 'additional_settings', - '#attributes' => array( - 'class' => array('path-form'), - ), - '#access' => user_access('create url aliases') || user_access('administer url aliases'), - '#weight' => 30, - '#tree' => TRUE, - '#element_validate' => array('path_form_element_validate'), - ); - } - - $pattern = pathauto_pattern_load_by_entity($entity_type, $bundle, $langcode); - if (empty($pattern)) { +function pathauto_entity_presave($entity) { + if (!($entity instanceof ContentEntityInterface) || $entity->hasField('path')) { return; } - - if (!isset($entity->path['pathauto'])) { - if (!empty($id)) { - module_load_include('inc', 'pathauto'); - $uri = entity_uri($entity_type, $entity); - $pathauto_alias = pathauto_create_alias($entity_type, 'return', $uri['path'], array($entity_type => $entity), $bundle, $langcode); - if ($pathauto_alias === FALSE) { - // If Pathauto is not going to be able to generate an alias, then we - // should not bother to show the checkbox since it wouldn't do anything. - // Note that if a pattern does apply, but all the tokens currently - // evaluate to empty strings, then $pathauto_alias would equal null and - // not false. - return; - } - else { - $path = drupal_get_path_alias($uri['path'], $langcode); - $entity->path['pathauto'] = ($path != $uri['path'] && $path == $pathauto_alias); - } - } - else { - $entity->path['pathauto'] = 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]"]'] = 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'] = array( - '#type' => 'checkbox', - '#title' => t('Generate automatic URL alias'), - '#default_value' => $entity->path['pathauto'], - '#description' => t('Uncheck this to create a custom alias below.'), - '#weight' => -1, - ); - - // Add a shortcut link to configure URL alias patterns. - if (drupal_valid_path('admin/config/search/path/patterns')) { - $form['path']['pathauto']['#description'] .= ' ' . l(t('Configure URL alias patterns.'), 'admin/config/search/path/patterns'); - } - - if ($entity->path['pathauto'] && !empty($entity->old_alias) && empty($entity->path['alias'])) { - $form['path']['alias']['#default_value'] = $entity->old_alias; - $entity->path['alias'] = $entity->old_alias; - } - - // For Pathauto to remember the old alias and prevent the Path module from - // deleting it when Pathauto wants to preserve it. - if (!empty($entity->path['alias'])) { - $form['path']['old_alias'] = array( - '#type' => 'value', - '#value' => $entity->path['alias'], - ); - } -} - -/** - * Implements hook_entity_presave(). - */ -function pathauto_entity_presave($entity, $type) { // About to be saved (before insert/update) - if (!empty($entity->path['pathauto']) && isset($entity->path['old_alias']) - && $entity->path['alias'] == '' && $entity->path['old_alias'] != '') { - /** + if (!empty($entity->path->pathauto) && isset($entity->path->old_alias) + && $entity->path->alias == '' && $entity->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. */ - $entity->path['alias'] = $entity->path['old_alias']; + $entity->path->alias = $entity->path->old_alias; } // Help prevent errors with progromatically creating entities by defining // path['alias'] as an empty string. // @see http://drupal.org/node/1328180 // @see http://drupal.org/node/1576552 - if (isset($entity->path['pathauto']) && !isset($entity->path['alias'])) { - $entity->path['alias'] = ''; + if (isset($entity->path->pathauto) && !isset($entity->path->alias)) { + $entity->path->alias = ''; } } /** - * Implements hook_action_info(). + * Implements hook_entity_insert(). */ -function pathauto_action_info() { - $info['pathauto_node_update_action'] = array( - 'type' => 'node', - 'label' => t('Update node alias'), - 'configurable' => FALSE, - 'triggers' => array(), - ); - $info['pathauto_taxonomy_term_update_action'] = array( - 'type' => 'taxonomy_term', - 'label' => t('Update taxonomy term alias'), - 'configurable' => FALSE, - 'triggers' => array(), - ); - $info['pathauto_user_update_action'] = array( - 'type' => 'user', - 'label' => t('Update user alias'), - 'configurable' => FALSE, - 'triggers' => array(), - ); - - return $info; -} - -/** - * Returns the language code of the given entity. - * - * Backward compatibility layer to ensure that installations running an older - * version of core where entity_language() is not avilable do not break. - * - * @param string $entity_type - * An entity type. - * @param object $entity - * An entity object. - * @param bool $check_language_property - * A boolean if TRUE, will attempt to fetch the language code from - * $entity->language if the entity_language() function failed or does not - * exist. Default is TRUE. - */ -function pathauto_entity_language($entity_type, $entity, $check_language_property = TRUE) { - $langcode = NULL; - - if (function_exists('entity_language')) { - $langcode = entity_language($entity_type, $entity); - } - elseif ($check_language_property && !empty($entity->language)) { - $langcode = $entity->language; - } - - return !empty($langcode) ? $langcode : LANGUAGE_NONE; -} - -function pathauto_is_alias_reserved($alias, $source, $langcode = LANGUAGE_NONE) { - foreach (module_implements('pathauto_is_alias_reserved') as $module) { - $result = module_invoke($module, 'pathauto_is_alias_reserved', $alias, $source, $langcode); - if (!empty($result)) { - // As soon as the first module says that an alias is in fact reserved, - // then there is no point in checking the rest of the modules. - return TRUE; - } - } - - return FALSE; +function pathauto_entity_insert(EntityInterface $entity) { + \Drupal::service('pathauto.manager')->updateAlias($entity, 'insert'); } /** - * Implements hook_pathauto_is_alias_reserved() on behalf of path.module. + * Implements hook_entity_update(). */ -function path_pathauto_is_alias_reserved($alias, $source, $langcode) { - return (bool) db_query_range("SELECT pid FROM {url_alias} WHERE source <> :source AND alias = :alias AND language IN (:language, :language_none) ORDER BY language DESC, pid DESC", 0, 1, array( - ':source' => $source, - ':alias' => $alias, - ':language' => $langcode, - ':language_none' => LANGUAGE_NONE, - ))->fetchField(); +function pathauto_entity_update(EntityInterface $entity) { + \Drupal::service('pathauto.manager')->updateAlias($entity, 'update'); } -/** - * Implements hook_pathauto_is_alias_reserved(). - */ -function pathauto_pathauto_is_alias_reserved($alias, $source, $langcode) { - module_load_include('inc', 'pathauto'); - return _pathauto_path_is_callback($alias); -} -if (!function_exists('path_field_extra_fields')) { /** - * Implements hook_field_extra_fields() on behalf of path.module. - * - * Add support for the 'URL path settings' to be re-ordered by the user on the - * 'Manage Fields' tab of content types and vocabularies. + * Implements hook_entity_update(). */ -function path_field_extra_fields() { - $info = array(); - - foreach (node_type_get_types() as $node_type) { - if (!isset($info['node'][$node_type->type]['form']['path'])) { - $info['node'][$node_type->type]['form']['path'] = array( - 'label' => t('URL path settings'), - 'description' => t('Path module form elements'), - 'weight' => 30, - ); - } +function pathauto_entity_delete(EntityInterface $entity) { + if ($entity->hasLinkTemplate('canonical')) { + \Drupal::service('pathauto.alias_storage_helper')->deleteEntityPathAll($entity); } - - if (module_exists('taxonomy')) { - $vocabularies = taxonomy_get_vocabularies(); - foreach ($vocabularies as $vocabulary) { - if (!isset($info['taxonomy_term'][$vocabulary->machine_name]['form']['path'])) { - $info['taxonomy_term'][$vocabulary->machine_name]['form']['path'] = array( - 'label' => t('URL path settings'), - 'description' => t('Path module form elements'), - 'weight' => 30, - ); - } - } - } - - return $info; -} -} - -/** - * @name pathauto_node Pathauto integration for the core node module. - * @{ - */ - -/** - * Implements hook_node_insert(). - */ -function pathauto_node_insert($node) { - // @todo Remove the next line when http://drupal.org/node/1025870 is fixed. - unset($node->uri); - pathauto_node_update_alias($node, 'insert'); -} - -/** - * Implements hook_node_update(). - */ -function pathauto_node_update($node) { - pathauto_node_update_alias($node, 'update'); -} - -/** - * Implements hook_node_delete(). - */ -function pathauto_node_delete($node) { - pathauto_entity_path_delete_all('node', $node, "node/{$node->nid}"); -} - -/** - * Implements hook_form_BASE_FORM_ID_alter(). - * - * Add the Pathauto settings to the node form. - */ -function pathauto_form_node_form_alter(&$form, &$form_state) { - $node = $form_state['node']; - $langcode = pathauto_entity_language('node', $node); - pathauto_field_attach_form('node', $node, $form, $form_state, $langcode); -} - -/** - * Implements hook_node_operations(). - */ -function pathauto_node_operations() { - $operations['pathauto_update_alias'] = array( - 'label' => t('Update URL alias'), - 'callback' => 'pathauto_node_update_alias_multiple', - 'callback arguments' => array('bulkupdate', array('message' => TRUE)), - ); - return $operations; -} - -/** - * Update the URL aliases for an individual node. - * - * @param $node - * A node object. - * @param $op - * Operation being performed on the node ('insert', 'update' or 'bulkupdate'). - * @param $options - * An optional array of additional options. - */ -function pathauto_node_update_alias(stdClass $node, $op, array $options = array()) { - // Skip processing if the user has disabled pathauto for the node. - if (isset($node->path['pathauto']) && empty($node->path['pathauto']) && empty($options['force'])) { - return FALSE; - } - - $options += array('language' => pathauto_entity_language('node', $node)); - - // Skip processing if the node has no pattern. - if (!pathauto_pattern_load_by_entity('node', $node->type, $options['language'])) { - return FALSE; - } - - module_load_include('inc', 'pathauto'); - $uri = entity_uri('node', $node); - return pathauto_create_alias('node', $op, $uri['path'], array('node' => $node), $node->type, $options['language']); } /** * Update the URL aliases for multiple nodes. * - * @param $nids + * @param array $nids * An array of node IDs. - * @param $op + * @param string $op * Operation being performed on the nodes ('insert', 'update' or * 'bulkupdate'). - * @param $options + * @param array $options * An optional array of additional options. */ function pathauto_node_update_alias_multiple(array $nids, $op, array $options = array()) { $options += array('message' => FALSE); - $nodes = node_load_multiple($nids); + $nodes = Node::loadMultiple($nids); foreach ($nodes as $node) { - pathauto_node_update_alias($node, $op, $options); + \Drupal::service('pathauto.manager')->updateAlias($node, $op, $options); } if (!empty($options['message'])) { - drupal_set_message(format_plural(count($nids), 'Updated URL alias for 1 node.', 'Updated URL aliases for @count nodes.')); + drupal_set_message(\Drupal::translation()->formatPlural(count($nids), 'Updated URL alias for 1 node.', 'Updated URL aliases for @count nodes.')); } } /** - * Update action wrapper for pathauto_node_update_alias(). - */ -function pathauto_node_update_action($node, $context = array()) { - pathauto_node_update_alias($node, 'bulkupdate', array('message' => TRUE)); -} - -/** - * @} End of "name pathauto_node". - */ - -/** - * @name pathauto_taxonomy Pathauto integration for the core taxonomy module. - * @{ - */ - -/** - * Implements hook_taxonomy_term_insert(). - */ -function pathauto_taxonomy_term_insert($term) { - pathauto_taxonomy_term_update_alias($term, 'insert'); -} - -/** - * Implements hook_taxonomy_term_update(). - */ -function pathauto_taxonomy_term_update($term) { - pathauto_taxonomy_term_update_alias($term, 'update', array('alias children' => TRUE)); -} - -/** - * Implements hook_taxonomy_term_delete(). - */ -function pathauto_taxonomy_term_delete($term) { - pathauto_entity_path_delete_all('taxonomy_term', $term, "taxonomy/term/{$term->tid}"); -} - -/** - * Implements hook_form_FORM_ID_alter(). - * - * Add the Pathauto settings to the taxonomy term form. - */ -function pathauto_form_taxonomy_form_term_alter(&$form, $form_state) { - $term = $form_state['term']; - $langcode = pathauto_entity_language('taxonomy_term', $term); - pathauto_field_attach_form('taxonomy_term', $term, $form, $form_state, $langcode); -} - -/** - * Update the URL aliases for an individual taxonomy term. - * - * @param $term - * A taxonomy term object. - * @param $op - * Operation being performed on the term ('insert', 'update' or 'bulkupdate'). - * @param $options - * An optional array of additional options. - */ -function pathauto_taxonomy_term_update_alias(stdClass $term, $op, array $options = array()) { - // Skip processing if the user has disabled pathauto for the term. - if (isset($term->path['pathauto']) && empty($term->path['pathauto']) && empty($options['force'])) { - return FALSE; - } - - $module = 'taxonomy_term'; - if ($term->vid == variable_get('forum_nav_vocabulary', '')) { - if (module_exists('forum')) { - $module = 'forum'; - } - else { - return FALSE; - } - } - - // Check that the term has its bundle, which is the vocabulary's machine name. - if (!isset($term->vocabulary_machine_name)) { - $vocabulary = taxonomy_vocabulary_load($term->vid); - $term->vocabulary_machine_name = $vocabulary->machine_name; - } - - $options += array( - 'alias children' => FALSE, - 'language' => pathauto_entity_language('taxonomy_term', $term), - ); - - // Skip processing if the term has no pattern. - if (!pathauto_pattern_load_by_entity($module, $term->vocabulary_machine_name)) { - return FALSE; - } - - module_load_include('inc', 'pathauto'); - $uri = entity_uri('taxonomy_term', $term); - $result = pathauto_create_alias($module, $op, $uri['path'], array('term' => $term), $term->vocabulary_machine_name, $options['language']); - - if (!empty($options['alias children'])) { - // For all children generate new aliases. - $options['alias children'] = FALSE; - unset($options['language']); - foreach (taxonomy_get_tree($term->vid, $term->tid) as $subterm) { - pathauto_taxonomy_term_update_alias($subterm, $op, $options); - } - } - - return $result; -} - -/** * Update the URL aliases for multiple taxonomy terms. * - * @param $tids + * @param array $tids * An array of term IDs. - * @param $op + * @param string $op * Operation being performed on the nodes ('insert', 'update' or * 'bulkupdate'). - * @param $options + * @param array $options * An optional array of additional options. */ function pathauto_taxonomy_term_update_alias_multiple(array $tids, $op, array $options = array()) { $options += array('message' => FALSE); - $terms = taxonomy_term_load_multiple($tids); + $terms = entity_load_multiple('taxonomy_term', $tids); foreach ($terms as $term) { - pathauto_taxonomy_term_update_alias($term, $op, $options); + \Drupal::service('pathauto.manager')->updateAlias($term, $op, $options); } if (!empty($options['message'])) { - drupal_set_message(format_plural(count($tids), 'Updated URL alias for 1 term.', 'Updated URL aliases for @count terms.')); + drupal_set_message(\Drupal::translation()->formatPlural(count($tids), 'Updated URL alias for 1 term.', 'Updated URL aliases for @count terms.')); } } /** - * Update action wrapper for pathauto_taxonomy_term_update_alias(). - */ -function pathauto_taxonomy_term_update_action($term, $context = array()) { - pathauto_taxonomy_term_update_alias($term, 'bulkupdate', array('message' => TRUE)); -} - -/** - * @} End of "name pathauto_taxonomy". - */ - -/** - * @name pathauto_user Pathauto integration for the core user and blog modules. - * @{ - */ - -/** - * Implements hook_user_insert(). - */ -function pathauto_user_insert(&$edit, $account, $category) { - pathauto_user_update_alias($account, 'insert'); -} - -/** - * Implements hook_user_update(). - */ -function pathauto_user_update(&$edit, $account, $category) { - pathauto_user_update_alias($account, 'update'); -} - -/** - * Implements hook_user_delete(). - */ -function pathauto_user_delete($account) { - pathauto_entity_path_delete_all('user', $account, "user/{$account->uid}"); - pathauto_path_delete_all("blog/{$account->uid}"); -} - -/** - * Implements hook_user_operations(). - */ -function pathauto_user_operations() { - $operations['pathauto_update_alias'] = array( - 'label' => t('Update URL alias'), - 'callback' => 'pathauto_user_update_alias_multiple', - 'callback arguments' => array('bulkupdate', array('message' => TRUE)), - ); - return $operations; -} - -/** - * Update the URL aliases for an individual user account. - * - * @param $account - * A user account object. - * @param $op - * Operation being performed on the account ('insert', 'update' or - * 'bulkupdate'). - * @param $options - * An optional array of additional options. - */ -function pathauto_user_update_alias(stdClass $account, $op, array $options = array()) { - // Skip processing if the user has disabled pathauto for the account. - if (isset($account->path['pathauto']) && empty($account->path['pathauto']) && empty($options['force'])) { - return FALSE; - } - - $options += array( - 'alias blog' => module_exists('blog'), - // $user->language is not the user entity language, thus we need to skip - // the property fallback check. - 'language' => pathauto_entity_language('user', $account, FALSE), - ); - - // Skip processing if the account has no pattern. - if (!pathauto_pattern_load_by_entity('user', '', $options['language'])) { - return FALSE; - } - - module_load_include('inc', 'pathauto'); - $uri = entity_uri('user', $account); - $return = pathauto_create_alias('user', $op, $uri['path'], array('user' => $account), NULL, $options['language']); - - // Because blogs are also associated with users, also generate the blog paths. - if (!empty($options['alias blog'])) { - pathauto_blog_update_alias($account, $op, $options); - } - - return $return; -} - -/** * Update the URL aliases for multiple user accounts. * - * @param $uids + * @param array $uids * An array of user account IDs. - * @param $op + * @param string $op * Operation being performed on the accounts ('insert', 'update' or * 'bulkupdate'). - * @param $options + * @param array $options * An optional array of additional options. */ function pathauto_user_update_alias_multiple(array $uids, $op, array $options = array()) { $options += array('message' => FALSE); - $accounts = user_load_multiple($uids); + $accounts = User::loadMultiple($uids); foreach ($accounts as $account) { - pathauto_user_update_alias($account, $op, $options); + \Drupal::service('pathauto.manager')->updateAlias($account, $op, $options); } if (!empty($options['message'])) { - drupal_set_message(format_plural(count($uids), 'Updated URL alias for 1 user account.', 'Updated URL aliases for @count user accounts.')); + drupal_set_message(\Drupal::translation()->formatPlural(count($uids), 'Updated URL alias for 1 user account.', 'Updated URL aliases for @count user accounts.')); } } /** - * Update action wrapper for pathauto_user_update_alias(). + * Implements hook_field_info_alter(). */ -function pathauto_user_update_action($account, $context = array()) { - pathauto_user_update_alias($account, 'bulkupdate', array('message' => TRUE)); +function pathauto_field_info_alter(&$info) { + $info['path']['class'] = '\Drupal\pathauto\PathautoItem'; } /** - * Update the blog URL aliases for an individual user account. - * - * @param $account - * A user account object. - * @param $op - * Operation being performed on the blog ('insert', 'update' or - * 'bulkupdate'). - * @param $options - * An optional array of additional options. + * Implements hook_entity_base_field_info_alter(). */ -function pathauto_blog_update_alias(stdClass $account, $op, array $options = array()) { - // Skip processing if the blog has no pattern. - if (!pathauto_pattern_load_by_entity('blog')) { - return FALSE; - } - - $options += array( - 'language' => LANGUAGE_NONE, - ); - - module_load_include('inc', 'pathauto'); - if (node_access('create', 'blog', $account)) { - return pathauto_create_alias('blog', $op, "blog/{$account->uid}", array('user' => $account), NULL, $options['language']); - } - else { - pathauto_path_delete_all("blog/{$account->uid}"); +function pathauto_entity_base_field_info_alter(&$fields, EntityTypeInterface $entity_type) { + if (isset($fields['path']) && $fields['path']->getType() == 'path') { + $fields['path']->setDisplayOptions('form', array( + 'type' => 'pathauto', + 'weight' => 30, + )); } } + /** - * @} End of "name pathauto_user". + * Implements hook_entity_base_field_info(). */ +function pathauto_entity_base_field_info(EntityTypeInterface $entity_type) { + // @todo: Make this configurable and/or remove if + // https://drupal.org/node/476294 is resolved. + if ($entity_type->id() === 'user') { + $fields['path'] = BaseFieldDefinition::create('path') + ->setCustomStorage(TRUE) + ->setLabel(t('URL alias')) + ->setTranslatable(TRUE) + ->setDisplayOptions('form', array( + 'type' => 'pathauto', + 'weight' => 30, + )) + ->setDisplayConfigurable('form', TRUE); + + return $fields; + } +} diff --git a/pathauto.pathauto.inc b/pathauto.pathauto.inc deleted file mode 100644 index 28d3ce0..0000000 --- a/pathauto.pathauto.inc +++ /dev/null @@ -1,392 +0,0 @@ - t('language neutral')) + locale_language_list('name'); - } - - foreach (node_type_get_names() as $node_type => $node_name) { - if (count($languages) && variable_get('language_content_type_' . $node_type, 0)) { - $settings['patternitems'][$node_type] = t('Default path pattern for @node_type (applies to all @node_type content types with blank patterns below)', array('@node_type' => $node_name)); - foreach ($languages as $lang_code => $lang_name) { - $settings['patternitems'][$node_type . '_' . $lang_code] = t('Pattern for all @language @node_type paths', array('@node_type' => $node_name, '@language' => $lang_name)); - } - } - else { - $settings['patternitems'][$node_type] = t('Pattern for all @node_type paths', array('@node_type' => $node_name)); - } - } - return (object) $settings; - default: - break; - } -} - -/** - * Batch processing callback; Generate aliases for nodes. - */ -function node_pathauto_bulk_update_batch_process(&$context) { - if (!isset($context['sandbox']['current'])) { - $context['sandbox']['count'] = 0; - $context['sandbox']['current'] = 0; - } - - $query = db_select('node', 'n'); - $query->leftJoin('url_alias', 'ua', "CONCAT('node/', n.nid) = ua.source"); - $query->addField('n', 'nid'); - $query->isNull('ua.source'); - $query->condition('n.nid', $context['sandbox']['current'], '>'); - $query->orderBy('n.nid'); - $query->addTag('pathauto_bulk_update'); - $query->addMetaData('entity', 'node'); - - // Get the total amount of items to process. - if (!isset($context['sandbox']['total'])) { - $context['sandbox']['total'] = $query->countQuery()->execute()->fetchField(); - - // If there are no nodes to update, the stop immediately. - if (!$context['sandbox']['total']) { - $context['finished'] = 1; - return; - } - } - - $query->range(0, 25); - $nids = $query->execute()->fetchCol(); - - pathauto_node_update_alias_multiple($nids, 'bulkupdate'); - $context['sandbox']['count'] += count($nids); - $context['sandbox']['current'] = max($nids); - $context['message'] = t('Updated alias for node @nid.', array('@nid' => end($nids))); - - if ($context['sandbox']['count'] != $context['sandbox']['total']) { - $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; - } -} - -/** - * Implements hook_pathauto(). - */ -function taxonomy_pathauto($op) { - switch ($op) { - case 'settings': - $settings = array(); - $settings['module'] = 'taxonomy_term'; - $settings['token_type'] = 'term'; - $settings['groupheader'] = t('Taxonomy term paths'); - $settings['patterndescr'] = t('Default path pattern (applies to all vocabularies with blank patterns below)'); - $settings['patterndefault'] = '[term:vocabulary]/[term:name]'; - $settings['batch_update_callback'] = 'taxonomy_pathauto_bulk_update_batch_process'; - $settings['batch_file'] = drupal_get_path('module', 'pathauto') . '/pathauto.pathauto.inc'; - - $vocabularies = taxonomy_get_vocabularies(); - if (count($vocabularies)) { - $settings['patternitems'] = array(); - foreach ($vocabularies as $vid => $vocabulary) { - if ($vid == variable_get('forum_nav_vocabulary', '')) { - // Skip the forum vocabulary. - continue; - } - $settings['patternitems'][$vocabulary->machine_name] = t('Pattern for all %vocab-name paths', array('%vocab-name' => $vocabulary->name)); - } - } - return (object) $settings; - default: - break; - } -} - -/** - * Batch processing callback; Generate aliases for taxonomy terms. - */ -function taxonomy_pathauto_bulk_update_batch_process(&$context) { - if (!isset($context['sandbox']['current'])) { - $context['sandbox']['count'] = 0; - $context['sandbox']['current'] = 0; - } - - $query = db_select('taxonomy_term_data', 'td'); - $query->leftJoin('url_alias', 'ua', "CONCAT('taxonomy/term/', td.tid) = ua.source"); - $query->addField('td', 'tid'); - $query->isNull('ua.source'); - $query->condition('td.tid', $context['sandbox']['current'], '>'); - // Exclude the forums terms. - if ($forum_vid = variable_get('forum_nav_vocabulary', '')) { - $query->condition('td.vid', $forum_vid, '<>'); - } - $query->orderBy('td.tid'); - $query->addTag('pathauto_bulk_update'); - $query->addMetaData('entity', 'taxonomy_term'); - - // Get the total amount of items to process. - if (!isset($context['sandbox']['total'])) { - $context['sandbox']['total'] = $query->countQuery()->execute()->fetchField(); - - // If there are no nodes to update, the stop immediately. - if (!$context['sandbox']['total']) { - $context['finished'] = 1; - return; - } - } - - $query->range(0, 25); - $tids = $query->execute()->fetchCol(); - - pathauto_taxonomy_term_update_alias_multiple($tids, 'bulkupdate'); - $context['sandbox']['count'] += count($tids); - $context['sandbox']['current'] = max($tids); - $context['message'] = t('Updated alias for term @tid.', array('@tid' => end($tids))); - - if ($context['sandbox']['count'] != $context['sandbox']['total']) { - $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; - } -} - -/** - * Implements hook_pathauto() for forum module. - */ -function forum_pathauto($op) { - switch ($op) { - case 'settings': - $settings = array(); - $settings['module'] = 'forum'; - $settings['token_type'] = 'term'; - $settings['groupheader'] = t('Forum paths'); - $settings['patterndescr'] = t('Pattern for forums and forum containers'); - $settings['patterndefault'] = '[term:vocabulary]/[term:name]'; - $settings['batch_update_callback'] = 'forum_pathauto_bulk_update_batch_process'; - $settings['batch_file'] = drupal_get_path('module', 'pathauto') . '/pathauto.pathauto.inc'; - return (object) $settings; - default: - break; - } -} - -/** - * Batch processing callback; Generate aliases for forums. - */ -function forum_pathauto_bulk_update_batch_process(&$context) { - if (!isset($context['sandbox']['current'])) { - $context['sandbox']['count'] = 0; - $context['sandbox']['current'] = 0; - } - - $query = db_select('taxonomy_term_data', 'td'); - $query->leftJoin('url_alias', 'ua', "CONCAT('forum/', td.tid) = ua.source"); - $query->addField('td', 'tid'); - $query->isNull('ua.source'); - $query->condition('td.tid', $context['sandbox']['current'], '>'); - $query->condition('td.vid', variable_get('forum_nav_vocabulary', '')); - $query->orderBy('td.tid'); - $query->addTag('pathauto_bulk_update'); - $query->addMetaData('entity', 'taxonomy_term'); - - // Get the total amount of items to process. - if (!isset($context['sandbox']['total'])) { - $context['sandbox']['total'] = $query->countQuery()->execute()->fetchField(); - - // If there are no nodes to update, the stop immediately. - if (!$context['sandbox']['total']) { - $context['finished'] = 1; - return; - } - } - - $query->range(0, 25); - $tids = $query->execute()->fetchCol(); - - pathauto_taxonomy_term_update_alias_multiple($tids, 'bulkupdate'); - $context['sandbox']['count'] += count($tids); - $context['sandbox']['current'] = max($tids); - $context['message'] = t('Updated alias for forum @tid.', array('@tid' => end($tids))); - - if ($context['sandbox']['count'] != $context['sandbox']['total']) { - $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; - } -} - -/** - * Implements hook_pathauto(). - */ -function user_pathauto($op) { - switch ($op) { - case 'settings': - $settings = array(); - $settings['module'] = 'user'; - $settings['token_type'] = 'user'; - $settings['groupheader'] = t('User paths'); - $settings['patterndescr'] = t('Pattern for user account page paths'); - $settings['patterndefault'] = 'users/[user:name]'; - $settings['batch_update_callback'] = 'user_pathauto_bulk_update_batch_process'; - $settings['batch_file'] = drupal_get_path('module', 'pathauto') . '/pathauto.pathauto.inc'; - return (object) $settings; - default: - break; - } -} - -/** - * Batch processing callback; Generate aliases for users. - */ -function user_pathauto_bulk_update_batch_process(&$context) { - if (!isset($context['sandbox']['current'])) { - $context['sandbox']['count'] = 0; - $context['sandbox']['current'] = 0; - } - - $query = db_select('users', 'u'); - $query->leftJoin('url_alias', 'ua', "CONCAT('user/', u.uid) = ua.source"); - $query->addField('u', 'uid'); - $query->isNull('ua.source'); - $query->condition('u.uid', $context['sandbox']['current'], '>'); - $query->orderBy('u.uid'); - $query->addTag('pathauto_bulk_update'); - $query->addMetaData('entity', 'user'); - - // Get the total amount of items to process. - if (!isset($context['sandbox']['total'])) { - $context['sandbox']['total'] = $query->countQuery()->execute()->fetchField(); - - // If there are no nodes to update, the stop immediately. - if (!$context['sandbox']['total']) { - $context['finished'] = 1; - return; - } - } - - $query->range(0, 25); - $uids = $query->execute()->fetchCol(); - - pathauto_user_update_alias_multiple($uids, 'bulkupdate', array('alias blog' => FALSE)); - $context['sandbox']['count'] += count($uids); - $context['sandbox']['current'] = max($uids); - $context['message'] = t('Updated alias for user @uid.', array('@uid' => end($uids))); - - if ($context['sandbox']['count'] != $context['sandbox']['total']) { - $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; - } -} - -/** - * Implements hook_pathauto(). - */ -function blog_pathauto($op) { - switch ($op) { - case 'settings': - $settings = array(); - $settings['module'] = 'blog'; - $settings['token_type'] = 'user'; - $settings['groupheader'] = t('Blog paths'); - $settings['patterndescr'] = t('Pattern for blog page paths'); - $settings['patterndefault'] = 'blogs/[user:name]'; - $settings['batch_update_callback'] = 'blog_pathauto_bulk_update_batch_process'; - $settings['batch_file'] = drupal_get_path('module', 'pathauto') . '/pathauto.pathauto.inc'; - return (object) $settings; - default: - break; - } -} - -/** - * Batch processing callback; Generate aliases for blogs. - */ -function blog_pathauto_bulk_update_batch_process(&$context) { - if (!isset($context['sandbox']['current'])) { - $context['sandbox']['count'] = 0; - $context['sandbox']['current'] = 0; - } - - $query = db_select('users', 'u'); - $query->leftJoin('url_alias', 'ua', "CONCAT('blog/', u.uid) = ua.source"); - $query->addField('u', 'uid'); - $query->isNull('ua.source'); - $query->condition('u.uid', $context['sandbox']['current'], '>'); - $query->orderBy('u.uid'); - $query->addTag('pathauto_bulk_update'); - $query->addMetaData('entity', 'user'); - - // Get the total amount of items to process. - if (!isset($context['sandbox']['total'])) { - $context['sandbox']['total'] = $query->countQuery()->execute()->fetchField(); - - // If there are no nodes to update, the stop immediately. - if (!$context['sandbox']['total']) { - $context['finished'] = 1; - return; - } - } - - $query->range(0, 25); - $uids = $query->execute()->fetchCol(); - - $accounts = user_load_multiple($uids); - foreach ($accounts as $account) { - pathauto_blog_update_alias($account, 'bulkupdate'); - } - - $context['sandbox']['count'] += count($uids); - $context['sandbox']['current'] = max($uids); - $context['message'] = t('Updated alias for blog user @uid.', array('@uid' => end($uids))); - - if ($context['sandbox']['count'] != $context['sandbox']['total']) { - $context['finished'] = $context['sandbox']['count'] / $context['sandbox']['total']; - } -} diff --git a/pathauto.test b/pathauto.test deleted file mode 100644 index 5a408e0..0000000 --- a/pathauto.test +++ /dev/null @@ -1,840 +0,0 @@ - $token), array($type => $object)); - $tokens += array($token => ''); - $this->assertIdentical($tokens[$token], $expected, t("Token value for [@type:@token] was '@actual', expected value '@expected'.", array('@type' => $type, '@token' => $token, '@actual' => $tokens[$token], '@expected' => $expected))); - } - - function saveAlias($source, $alias, $language = LANGUAGE_NONE) { - $alias = array( - 'source' => $source, - 'alias' => $alias, - 'language' => $language, - ); - path_save($alias); - return $alias; - } - - function saveEntityAlias($entity_type, $entity, $alias, $language = LANGUAGE_NONE) { - $uri = entity_uri($entity_type, $entity); - return $this->saveAlias($uri['path'], $alias, $language); - } - - function assertEntityAlias($entity_type, $entity, $expected_alias, $language = LANGUAGE_NONE) { - $uri = entity_uri($entity_type, $entity); - $this->assertAlias($uri['path'], $expected_alias, $language); - } - - function assertEntityAliasExists($entity_type, $entity) { - $uri = entity_uri($entity_type, $entity); - return $this->assertAliasExists(array('source' => $uri['path'])); - } - - function assertNoEntityAlias($entity_type, $entity, $language = LANGUAGE_NONE) { - $uri = entity_uri($entity_type, $entity); - $this->assertEntityAlias($entity_type, $entity, $uri['path'], $language); - } - - function assertNoEntityAliasExists($entity_type, $entity) { - $uri = entity_uri($entity_type, $entity); - $this->assertNoAliasExists(array('source' => $uri['path'])); - } - - function assertAlias($source, $expected_alias, $language = LANGUAGE_NONE) { - drupal_clear_path_cache($source); - $alias = drupal_get_path_alias($source, $language); - $this->assertIdentical($alias, $expected_alias, t("Alias for %source with language '@language' was %actual, expected %expected.", array('%source' => $source, '%actual' => $alias, '%expected' => $expected_alias, '@language' => $language))); - } - - function assertAliasExists($conditions) { - $path = path_load($conditions); - $this->assertTrue($path, t('Alias with conditions @conditions found.', array('@conditions' => var_export($conditions, TRUE)))); - return $path; - } - - function assertNoAliasExists($conditions) { - $alias = path_load($conditions); - $this->assertFalse($alias, t('Alias with conditions @conditions not found.', array('@conditions' => var_export($conditions, TRUE)))); - } - - function deleteAllAliases() { - db_delete('url_alias')->execute(); - drupal_clear_path_cache(); - } - - function addVocabulary(array $vocabulary = array()) { - $name = drupal_strtolower($this->randomName(5)); - $vocabulary += array( - 'name' => $name, - 'machine_name' => $name, - 'nodes' => array('article' => 'article'), - ); - $vocabulary = (object) $vocabulary; - taxonomy_vocabulary_save($vocabulary); - return $vocabulary; - } - - function addTerm(stdClass $vocabulary, array $term = array()) { - $term += array( - 'name' => drupal_strtolower($this->randomName(5)), - 'vocabulary_machine_name' => $vocabulary->machine_name, - 'vid' => $vocabulary->vid, - ); - $term = (object) $term; - taxonomy_term_save($term); - return $term; - } - - function assertEntityPattern($entity_type, $bundle, $language = LANGUAGE_NONE, $expected) { - drupal_static_reset('pathauto_pattern_load_by_entity'); - $this->refreshVariables(); - $pattern = pathauto_pattern_load_by_entity($entity_type, $bundle, $language); - $this->assertIdentical($expected, $pattern); - } - - function drupalGetTermByName($name, $reset = FALSE) { - $terms = entity_load('taxonomy_term', array(), array('name' => $name), $reset); - return !empty($terms) ? reset($terms) : FALSE; - } -} - -/** - * Unit tests for Pathauto functions. - */ -class PathautoUnitTestCase extends PathautoTestHelper { - public static function getInfo() { - return array( - 'name' => 'Pathauto unit tests', - 'description' => 'Unit tests for Pathauto functions.', - 'group' => 'Pathauto', - 'dependencies' => array('token'), - ); - } - - function setUp(array $modules = array()) { - parent::setUp($modules); - module_load_include('inc', 'pathauto'); - } - - /** - * Test _pathauto_get_schema_alias_maxlength(). - */ - function testGetSchemaAliasMaxLength() { - $this->assertIdentical(_pathauto_get_schema_alias_maxlength(), 255); - } - - /** - * Test pathauto_pattern_load_by_entity(). - */ - function testPatternLoadByEntity() { - variable_set('pathauto_node_story_en_pattern', ' story/en/[node:title] '); - variable_set('pathauto_node_story_pattern', 'story/[node:title]'); - variable_set('pathauto_node_pattern', 'content/[node:title]'); - variable_set('pathauto_user_pattern', 'users/[user:name]'); - - $tests = array( - array('entity' => 'node', 'bundle' => 'story', 'language' => 'fr', 'expected' => 'story/[node:title]'), - array('entity' => 'node', 'bundle' => 'story', 'language' => 'en', 'expected' => 'story/en/[node:title]'), - array('entity' => 'node', 'bundle' => 'story', 'language' => LANGUAGE_NONE, 'expected' => 'story/[node:title]'), - array('entity' => 'node', 'bundle' => 'page', 'language' => 'en', 'expected' => 'content/[node:title]'), - array('entity' => 'user', 'bundle' => 'user', 'language' => LANGUAGE_NONE, 'expected' => 'users/[user:name]'), - array('entity' => 'invalid-entity', 'bundle' => '', 'language' => LANGUAGE_NONE, 'expected' => ''), - ); - foreach ($tests as $test) { - $actual = pathauto_pattern_load_by_entity($test['entity'], $test['bundle'], $test['language']); - $this->assertIdentical($actual, $test['expected'], t("pathauto_pattern_load_by_entity('@entity', '@bundle', '@language') returned '@actual', expected '@expected'", array('@entity' => $test['entity'], '@bundle' => $test['bundle'], '@language' => $test['language'], '@actual' => $actual, '@expected' => $test['expected']))); - } - } - - /** - * Test pathauto_cleanstring(). - */ - function testCleanString() { - $tests = array(); - variable_set('pathauto_ignore_words', ', in, is,that, the , this, with, '); - variable_set('pathauto_max_component_length', 35); - - // Test the 'ignored words' removal. - $tests['this'] = 'this'; - $tests['this with that'] = 'this-with-that'; - $tests['this thing with that thing'] = 'thing-thing'; - - // Test length truncation and duplicate separator removal. - $tests[' - Pathauto is the greatest - module ever in Drupal history - '] = 'pathauto-greatest-module-ever'; - - // Test that HTML tags are removed. - $tests['This text has