[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/pathauto/ -> pathauto.inc (source)

   1  <?php
   2  
   3  /**
   4   * @file
   5   * Miscellaneous functions for Pathauto.
   6   *
   7   * @ingroup pathauto
   8   */
   9  
  10  /**
  11   * Check to see if there is already an alias pointing to a different item.
  12   *
  13   * @param $alias
  14   *   A string alias.
  15   * @param $source
  16   *   A string that is the internal path.
  17   * @param $language
  18   *   A string indicating the path's language.
  19   * @return
  20   *   TRUE if an alias exists, FALSE if not.
  21   */
  22  function _pathauto_alias_exists($alias, $source, $language = '') {
  23    $pid = db_result(db_query_range("SELECT pid FROM {url_alias} WHERE src <> '%s' AND dst = '%s' AND language IN ('%s', '') ORDER BY language DESC, pid DESC", $source, $alias, $language, 0, 1));
  24  
  25    if (module_exists('path_redirect') && function_exists('path_redirect_delete_multiple')) {
  26      // Delete from path_redirect the exact same alias to the same node.
  27      path_redirect_delete_multiple(NULL, array('source' => $alias, 'redirect' => $source));
  28  
  29      // If there still is this alias used in path_redirect, then create a different alias.
  30      $redirects = path_redirect_load_multiple(NULL, array('source' => $alias));
  31    }
  32  
  33    if ($pid || !empty($redirects)) {
  34      return TRUE;
  35    }
  36    else {
  37      return FALSE;
  38    }
  39  }
  40  
  41  /**
  42   * Fetches an existing URL alias given a path and optional language.
  43   *
  44   * @param $source
  45   *   An internal Drupal path.
  46   * @param $language
  47   *   An optional language code to look up the path in.
  48   * @return
  49   *   FALSE if no alias was found or an associative array containing the
  50   *   following keys:
  51   *   - pid: Unique path alias identifier.
  52   *   - alias: The URL alias.
  53   */
  54  function _pathauto_existing_alias_data($source, $language = '') {
  55    return db_fetch_array(db_query_range("SELECT pid, dst AS alias, language FROM {url_alias} WHERE src = '%s' AND language IN ('%s', '') ORDER BY language DESC, pid DESC", $source, $language, 0, 1));
  56  }
  57  
  58  /**
  59   * Clean up a string segment to be used in an URL alias.
  60   *
  61   * Performs the following possible alterations:
  62   * - Remove all HTML tags.
  63   * - Process the string through the transliteration module.
  64   * - Replace or remove punctuation with the separator character.
  65   * - Remove back-slashes.
  66   * - Replace non-ascii and non-numeric characters with the separator.
  67   * - Remove common words.
  68   * - Replace whitespace with the separator character.
  69   * - Trim duplicate, leading, and trailing separators.
  70   * - Convert to lower-case.
  71   * - Shorten to a desired length and logical position based on word boundaries.
  72   *
  73   * This function should *not* be called on URL alias or path strings because it
  74   * is assumed that they are already clean.
  75   *
  76   * @param $string
  77   *   A string to clean.
  78   * @return
  79   *   The cleaned string.
  80   */
  81  function pathauto_cleanstring($string) {
  82    static $strings = array();
  83  
  84    // Empty strings do not need any proccessing.
  85    if ($string === '' || $string === NULL) {
  86      return '';
  87    }
  88  
  89    // Check if the string has already been processed, and if so return the
  90    // cached result.
  91    if (isset($strings[$string])) {
  92      return $strings[$string];
  93    }
  94  
  95    // Remove all HTML tags from the string.
  96    $output = strip_tags(decode_entities($string));
  97  
  98    // Optionally remove accents and transliterate
  99    if (variable_get('pathauto_transliterate', FALSE)) {
 100      static $translations;
 101  
 102      if (!isset($translations)) {
 103        $translations = FALSE;
 104        if ($file = _pathauto_get_i18n_file()) {
 105          $translations = parse_ini_file($file);
 106        }
 107      }
 108  
 109      if (!empty($translations)) {
 110        $output = strtr($output, $translations);
 111      }
 112    }
 113  
 114    // Replace or drop punctuation based on user settings
 115    $separator = variable_get('pathauto_separator', '-');
 116    $punctuation = pathauto_punctuation_chars();
 117    foreach ($punctuation as $name => $details) {
 118      $action = variable_get('pathauto_punctuation_'. $name, 0);
 119      // 2 is the action for "do nothing" with the punctuation
 120      if ($action != 2) {
 121        // Slightly tricky inline if which either replaces with the separator or nothing
 122        $output = str_replace($details['value'], ($action ? $separator : ''), $output);
 123      }
 124    }
 125  
 126    // Reduce strings to letters and numbers
 127    if (variable_get('pathauto_reduce_ascii', FALSE)) {
 128      $pattern = '/[^a-zA-Z0-9\/]+/';
 129      $output = preg_replace($pattern, $separator, $output);
 130    }
 131  
 132    // Calculate and statically cache the ignored words regex expression.
 133    static $ignore_words_regex;
 134    if (!isset($ignore_words_regex)) {
 135      $ignore_words = array(
 136        'a', 'an', 'as', 'at', 'before', 'but', 'by', 'for', 'from', 'is', 'in',
 137        'into', 'like', 'of', 'off', 'on', 'onto', 'per', 'since', 'than', 'the',
 138        'this', 'that', 'to', 'up', 'via', 'with',
 139      );
 140      $ignore_words = variable_get('pathauto_ignore_words', $ignore_words);
 141      $ignore_words_regex = preg_replace(array('/^[,\s]+|[,\s]+$/', '/[,\s]+/'), array('', '\b|\b'), $ignore_words);
 142      if ($ignore_words_regex) {
 143        $ignore_words_regex = '\b' . $ignore_words_regex . '\b';
 144      }
 145    }
 146  
 147    // Get rid of words that are on the ignore list
 148    if ($ignore_words_regex) {
 149      if (function_exists('mb_eregi_replace')) {
 150        $words_removed = mb_eregi_replace($ignore_words_regex, '', $output);
 151      }
 152      else {
 153        $words_removed = preg_replace("/$ignore_words_regex/i", '', $output);
 154      }
 155      if (drupal_strlen(trim($words_removed)) > 0) {
 156        $output = $words_removed;
 157      }
 158    }
 159  
 160    // Always replace whitespace with the separator.
 161    $output = preg_replace('/\s+/', $separator, $output);
 162  
 163    // Trim duplicates and remove trailing and leading separators.
 164    $output = _pathauto_clean_separators($output);
 165  
 166    // Optionally convert to lower case.
 167    if (variable_get('pathauto_case', 1)) {
 168      $output = drupal_strtolower($output);
 169    }
 170  
 171    // Enforce the maximum component length.
 172    $maxlength = min(variable_get('pathauto_max_component_length', 100), _pathauto_get_schema_alias_maxlength());
 173    $output = drupal_substr($output, 0, $maxlength);
 174  
 175    // Cache this result in the static array.
 176    $strings[$string] = $output;
 177  
 178    return $output;
 179  }
 180  
 181  /**
 182   * Trims duplicate, leading, and trailing separators from a string.
 183   *
 184   * @param $string
 185   *   The string to clean path separators from.
 186   * @param $separator
 187   *   The path separator to use when cleaning.
 188   * @return
 189   *   The cleaned version of the string.
 190   *
 191   * @see pathauto_cleanstring()
 192   * @see pathauto_clean_alias()
 193   */
 194  function _pathauto_clean_separators($string, $separator = NULL) {
 195    $output = $string;
 196  
 197    if (!isset($separator)) {
 198      $separator = variable_get('pathauto_separator', '-');
 199    }
 200  
 201    // Clean duplicate or trailing separators.
 202    if (strlen($separator)) {
 203      // Escape the separator.
 204      $seppattern = preg_quote($separator, '/');
 205  
 206      // Trim any leading or trailing separators.
 207      $output = preg_replace("/^$seppattern+|$seppattern+$/", '', $output);
 208  
 209      // Replace trailing separators around slashes.
 210      if ($separator !== '/') {
 211        $output = preg_replace("/$seppattern+\/|\/$seppattern+/", "/", $output);
 212      }
 213  
 214      // Replace multiple separators with a single one.
 215      $output = preg_replace("/$seppattern+/", $separator, $output);
 216    }
 217  
 218    return $output;
 219  }
 220  
 221  /**
 222   * Clean up an URL alias.
 223   *
 224   * Performs the following alterations:
 225   * - Trim duplicate, leading, and trailing back-slashes.
 226   * - Trim duplicate, leading, and trailing separators.
 227   * - Shorten to a desired length and logical position based on word boundaries.
 228   *
 229   * @param $alias
 230   *   A string with the URL alias to clean up.
 231   * @return
 232   *   The cleaned URL alias.
 233   */
 234  function pathauto_clean_alias($alias) {
 235    $output = $alias;
 236  
 237    // Trim duplicate, leading, and trailing back-slashes.
 238    $output = _pathauto_clean_separators($output, '/');
 239  
 240    // Trim duplicate, leading, and trailing separators.
 241    $output = _pathauto_clean_separators($output);
 242  
 243    // Enforce the maximum length.
 244    $separator = variable_get('pathauto_separator', '-');
 245    $maxlength = min(variable_get('pathauto_max_length', 100), _pathauto_get_schema_alias_maxlength());
 246    $output = drupal_substr($output, 0, $maxlength);
 247  
 248    return $output;
 249  }
 250  
 251  /**
 252   * Apply patterns to create an alias.
 253   *
 254   * @param $module
 255   *   The name of your module (e.g., 'node').
 256   * @param $op
 257   *   Operation being performed on the content being aliased
 258   *   ('insert', 'update', 'return', or 'bulkupdate').
 259   * @param $placeholders
 260   *   An array whose keys consist of the translated placeholders
 261   *   which appear in patterns (e.g., t('[title]')) and values are the
 262   *   actual values to be substituted into the pattern (e.g., $node->title).
 263   * @param $source
 264   *   An internal Drupal path to be aliased.
 265   * @param $entity_id
 266   *   The entity ID (node ID, user ID, etc.).
 267   * @param $type
 268   *   For modules which provided pattern items in hook_pathauto(),
 269   *   the relevant identifier for the specific item to be aliased
 270   *   (e.g., $node->type).
 271   * @param $language
 272   *   A string specify the path's language.
 273   * @return
 274   *   The alias that was created.
 275   *
 276   * @see _pathauto_set_alias()
 277   * @see pathauto_get_placeholders()
 278   */
 279  function pathauto_create_alias($module, $op, $placeholders, $source, $entity_id, $type = NULL, $language = '') {
 280    // Retrieve and apply the pattern for this content type
 281    if (!empty($type)) {
 282      $pattern = trim(variable_get("pathauto_{$module}_{$type}_{$language}_pattern", ''));
 283      if (empty($pattern)) {
 284        $pattern = trim(variable_get("pathauto_{$module}_{$type}_pattern", ''));
 285      }
 286    }
 287    if (empty($pattern)) {
 288      $pattern = trim(variable_get("pathauto_{$module}_pattern", ''));
 289    }
 290    // No pattern? Do nothing (otherwise we may blow away existing aliases...)
 291    if (empty($pattern)) {
 292      return '';
 293    }
 294  
 295    if ($module == 'taxonomy') {
 296      // Get proper path for term.
 297      $term_path = taxonomy_term_path(taxonomy_get_term($entity_id));
 298      if ($term_path != $source) {
 299        // Quietly alias 'taxonomy/term/[tid]' with proper path for term.
 300        $update_data = _pathauto_existing_alias_data($source, $language);
 301        _pathauto_set_alias($source, $term_path, $module, $entity_id, $update_data['pid'], FALSE, $update_data['old_alias'], $language);
 302        // Set $source as proper path.
 303        $source = $term_path;
 304      }
 305    }
 306  
 307    // Special handling when updating an item which is already aliased.
 308    $existing_alias = NULL;
 309    if ($op == 'update' || $op == 'bulkupdate') {
 310      if ($existing_alias = _pathauto_existing_alias_data($source, $language)) {
 311        switch (variable_get('pathauto_update_action', 2)) {
 312          case 0:
 313            // If an alias already exists, and the update action is set to do nothing,
 314            // then gosh-darn it, do nothing.
 315            return '';
 316        }
 317      }
 318    }
 319  
 320    // Replace the placeholders with the values provided by the module.
 321    $alias = str_replace($placeholders['tokens'], $placeholders['values'], $pattern);
 322  
 323    // Check if the token replacement has not actually replaced any values. If
 324    // that is the case, then stop because we should not generate an alias.
 325    // @see token_scan()
 326    $pattern_tokens_removed = preg_replace('/\[([^\s]+?)\]/', '', $pattern);
 327    if ($alias === $pattern_tokens_removed) {
 328      return '';
 329    }
 330  
 331    $alias = pathauto_clean_alias($alias);
 332  
 333    // Allow other modules to alter the alias.
 334    $context = array(
 335      'module' => $module,
 336      'op' => $op,
 337      'source' => $source,
 338      'entity_id' => $entity_id,
 339      'type' => $type,
 340      'language' => $language,
 341      'pattern' => $pattern,
 342    );
 343    drupal_alter('pathauto_alias', $alias, $context);
 344  
 345    // If we have arrived at an empty string, discontinue.
 346    if (!drupal_strlen($alias)) {
 347      return '';
 348    }
 349  
 350    // If the alias already exists, generate a new, hopefully unique, variant
 351    if (_pathauto_alias_exists($alias, $source, $language)) {
 352      $maxlength = min(variable_get('pathauto_max_length', 100), _pathauto_get_schema_alias_maxlength());
 353      $separator = variable_get('pathauto_separator', '-');
 354      $original_alias = $alias;
 355  
 356      $i = 0;
 357      do {
 358        // Append an incrementing numeric suffix until we find a unique alias.
 359        $unique_suffix = $separator . $i;
 360        $alias = drupal_substr($original_alias, 0, $maxlength - drupal_strlen($unique_suffix, TRUE)) . $unique_suffix;
 361        $i++;
 362      } while (_pathauto_alias_exists($alias, $source, $language));
 363  
 364      // Alert the user why this happened.
 365      _pathauto_verbose(t('The automatically generated alias %original_alias conflicted with an existing alias. Alias changed to %alias.', array(
 366        '%original_alias' => $original_alias,
 367        '%alias' => $alias,
 368      )), $op);
 369    }
 370  
 371    // Return the generated alias if requested.
 372    if ($op == 'return') {
 373      return $alias;
 374    }
 375  
 376    // Build the new path alias array and send it off to be created.
 377    $path = array(
 378      'source' => $source,
 379      'alias' => $alias,
 380      'language' => $language,
 381    );
 382    $success = _pathauto_set_alias($path, $existing_alias, $op);
 383  
 384    // Also create a related feed alias if requested and supported.
 385    $feedappend = trim(variable_get('pathauto_' . $module . '_applytofeeds', ''));
 386    if (drupal_strlen($feedappend)) {
 387      // For forums and taxonomies, the source doesn't always form the base of the RSS feed (i.e. image galleries)
 388      if ($module == 'taxonomy' || $module == 'forum' && !empty($entity_id)) {
 389        $source = "taxonomy/term/{$entity_id}";
 390      }
 391  
 392      // Build the feed path alias array and send it off to be created.
 393      $path = array(
 394        'source' => "$source/$feedappend",
 395        'alias' => "$alias/feed",
 396        'language' => $language,
 397      );
 398      $existing_alias = _pathauto_existing_alias_data($path['source'], $path['language']);
 399      _pathauto_set_alias($path, $existing_alias, $op);
 400    }
 401  
 402    return $success ? $alias : NULL;
 403  }
 404  
 405  /**
 406   * Verify if the given path is a valid menu callback.
 407   *
 408   * Taken from menu_execute_active_handler().
 409   *
 410   * @param $path
 411   *   A string containing a relative path.
 412   * @return
 413   *   TRUE if the path already exists.
 414   */
 415  function _pathauto_path_is_callback($path) {
 416    $menu = menu_get_item($path);
 417    if (isset($menu['path']) && $menu['path'] == $path) {
 418      return TRUE;
 419    }
 420    elseif (is_file('./' . $path) || is_dir('./' . $path)) {
 421      // Do not allow existing files or directories to get assigned an automatic
 422      // alias. Note that we do not need to use is_link() to check for symbolic
 423      // links since this returns TRUE for either is_file() or is_dir() already.
 424      return TRUE;
 425    }
 426    return FALSE;
 427  }
 428  
 429  /**
 430   * Private function for Pathauto to create an alias.
 431   *
 432   * @param $path
 433   *   An associative array containing the following keys:
 434   *   - source: The internal system path.
 435   *   - alias: The URL alias.
 436   *   - pid: (optional) Unique path alias identifier.
 437   *   - language: (optional) The language of the alias.
 438   * @param $existing_alias
 439   *   (optional) An associative array of the existing path alias.
 440   * @param $op
 441   *   An optional string with the operation being performed.
 442   * @return
 443   *   TRUE if the path was saved, or NULL otherwise.
 444   *
 445   * @see path_set_alias()
 446   */
 447  function _pathauto_set_alias($path, $existing_alias = NULL, $op = NULL) {
 448    $verbose = _pathauto_verbose(NULL, $op);
 449  
 450    // Alert users that an existing callback cannot be overridden automatically
 451    if (_pathauto_path_is_callback($path['alias'])) {
 452      if ($verbose) {
 453        _pathauto_verbose(t('Ignoring alias %alias due to existing path conflict.', array('%alias' => $path['alias'])));
 454      }
 455      return;
 456    }
 457    // Alert users if they are trying to create an alias that is the same as the internal path
 458    if ($path['source'] == $path['alias']) {
 459      if ($verbose) {
 460        _pathauto_verbose(t('Ignoring alias %alias because it is the same as the internal path.', array('%alias' => $path['alias'])));
 461      }
 462      return;
 463    }
 464  
 465    $path += array(
 466      'pid' => NULL,
 467      'language' => '',
 468    );
 469  
 470    // Skip replacing the current alias with an identical alias
 471    if (empty($existing_alias) || $existing_alias['alias'] != $path['alias']) {
 472      // If there is already an alias, respect some update actions.
 473      if (!empty($existing_alias)) {
 474        switch (variable_get('pathauto_update_action', 2)) {
 475          case 0:
 476            // Do not create the alias.
 477            return;
 478          case 1:
 479            // Create a new alias instead of overwriting the existing by leaving
 480            // $path['pid'] empty.
 481            break;
 482          case 3:
 483            // Create a redirect
 484            if (module_exists('path_redirect') && function_exists('path_redirect_save')) {
 485              $redirect = array(
 486                'source' => $existing_alias['alias'],
 487                'language' => $existing_alias['language'],
 488                'redirect' => $path['source'],
 489              );
 490              path_redirect_save($redirect);
 491            }
 492            // Intentionally fall through to the next condition since we still
 493            // want to replace the existing alias.
 494          case 2:
 495            // Both the redirect and delete actions should overwrite the existing
 496            // alias.
 497            $path['pid'] = $existing_alias['pid'];
 498            break;
 499        }
 500      }
 501  
 502      // Save the path array.
 503      path_set_alias($path['source'], $path['alias'], $path['pid'], $path['language']);
 504  
 505      if ($verbose) {
 506        if (!empty($redirect)) {
 507          _pathauto_verbose(t('Created new alias %alias for %source, replacing %old_alias. %old_alias now redirects to %alias.', array('%alias' => $path['alias'], '%source' => $path['source'], '%old_alias' => $existing_alias['alias'])));
 508        }
 509        elseif (!empty($existing_alias['pid'])) {
 510          _pathauto_verbose(t('Created new alias %alias for %source, replacing %old_alias.', array('%alias' => $path['alias'], '%source' => $path['source'], '%old_alias' => $existing_alias['alias'])));
 511        }
 512        else {
 513          _pathauto_verbose(t('Created new alias %alias for %source.', array('%alias' => $path['alias'], '%source' => $path['source'])));
 514        }
 515      }
 516  
 517      return TRUE;
 518    }
 519  }
 520  
 521  /**
 522   * Output a helpful message if verbose output is enabled.
 523   *
 524   * Verbose output is only enabled when:
 525   * - The 'pathauto_verbose' setting is enabled.
 526   * - The current user has the 'notify of path changes' permission.
 527   * - The $op parameter is anything but 'bulkupdate' or 'return'.
 528   *
 529   * @param $message
 530   *   An optional string of the verbose message to display. This string should
 531   *   already be run through t().
 532   * @param $op
 533   *   An optional string with the operation being performed.
 534   * @return
 535   *   TRUE if verbose output is enabled, or FALSE otherwise.
 536   */
 537  function _pathauto_verbose($message = NULL, $op = NULL) {
 538    static $verbose;
 539  
 540    if (!isset($verbose)) {
 541      $verbose = variable_get('pathauto_verbose', FALSE) && user_access('notify of path changes');
 542    }
 543  
 544    if (!$verbose || (isset($op) && in_array($op, array('bulkupdate', 'return')))) {
 545      return FALSE;
 546    }
 547  
 548    if ($message) {
 549      drupal_set_message($message);
 550    }
 551  
 552    return $verbose;
 553  }
 554  
 555  /**
 556   * Generalized function to get tokens across all Pathauto types.
 557   *
 558   * @param $object
 559   *   A user, node, or category object.
 560   * @return
 561   *   Tokens for that object formatted in the way that
 562   *   Pathauto expects to see them.
 563   */
 564  function pathauto_get_placeholders($type, $object) {
 565    if (!function_exists('token_get_values')) {
 566      // TODO at some point try removing this and see if install profiles have problems again.
 567      watchdog('Pathauto', 'It appears that you have installed Pathauto, which depends on token, but token is either not installed or not installed properly.');
 568      return array('tokens' => array(), 'values' => array());
 569    }
 570  
 571    $options = array('pathauto' => TRUE);
 572    $full = token_get_values($type, $object, TRUE, $options);
 573    $tokens = token_prepare_tokens($full->tokens);
 574    $values = pathauto_clean_token_values($full, $options);
 575    return array('tokens' => $tokens, 'values' => $values);
 576  }
 577  
 578  /**
 579   * Clean tokens so they are URL friendly.
 580   *
 581   * @param $full
 582   *   An array of token values from token_get_values() that need to be "cleaned"
 583   *   for use in the URL.
 584   *
 585   * @return
 586   *   An array of the cleaned tokens.
 587   */
 588  function pathauto_clean_token_values($full, $options = array()) {
 589    $replacements = array();
 590    foreach ($full->values as $key => $value) {
 591      $token = $full->tokens[$key];
 592      if (strpos($token, 'path') !== FALSE && is_array($value) && !empty($options['pathauto'])) {
 593        // If the token name contains 'path', the token value is an array, and
 594        // the 'pathauto' option was passed to token_get_values(), then the token
 595        // should have each segment cleaned, and then glued back together to
 596        // construct a value resembling an URL.
 597        $segments = array_map('pathauto_cleanstring', $value);
 598        $replacements[$token] = implode('/', $segments);
 599      }
 600      elseif (preg_match('/(path|alias|url|url-brief)(-raw)?$/', $token)) {
 601        // Token name matches an URL-type name and should be left raw.
 602        $replacements[$token] = $value;
 603      }
 604      else {
 605        // Token is not an URL, so it should have its value cleaned.
 606        $replacements[$token] = pathauto_cleanstring($value);
 607      }
 608    }
 609    return $replacements;
 610  }
 611  
 612  /**
 613   * Return an array of arrays for punctuation values.
 614   *
 615   * Returns an array of arrays for punctuation values keyed by a name, including
 616   * the value and a textual description.
 617   * Can and should be expanded to include "all" non text punctuation values.
 618   *
 619   * @return
 620   *   An array of arrays for punctuation values keyed by a name, including the
 621   *   value and a textual description.
 622   */
 623  function pathauto_punctuation_chars() {
 624    static $punctuation;
 625  
 626    if (!isset($punctuation)) {
 627      $punctuation = array();
 628      $punctuation['double_quotes']      = array('value' => '"', 'name' => t('Double quotes "'));
 629      $punctuation['quotes']             = array('value' => "'", 'name' => t("Single quotes (apostrophe) '"));
 630      $punctuation['backtick']           = array('value' => '`', 'name' => t('Back tick `'));
 631      $punctuation['comma']              = array('value' => ',', 'name' => t('Comma ,'));
 632      $punctuation['period']             = array('value' => '.', 'name' => t('Period .'));
 633      $punctuation['hyphen']             = array('value' => '-', 'name' => t('Hyphen -'));
 634      $punctuation['underscore']         = array('value' => '_', 'name' => t('Underscore _'));
 635      $punctuation['colon']              = array('value' => ':', 'name' => t('Colon :'));
 636      $punctuation['semicolon']          = array('value' => ';', 'name' => t('Semicolon ;'));
 637      $punctuation['pipe']               = array('value' => '|', 'name' => t('Pipe |'));
 638      $punctuation['left_curly']         = array('value' => '{', 'name' => t('Left curly bracket {'));
 639      $punctuation['left_square']        = array('value' => '[', 'name' => t('Left square bracket ['));
 640      $punctuation['right_curly']        = array('value' => '}', 'name' => t('Right curly bracket }'));
 641      $punctuation['right_square']       = array('value' => ']', 'name' => t('Right square bracket ]'));
 642      $punctuation['plus']               = array('value' => '+', 'name' => t('Plus +'));
 643      $punctuation['equal']              = array('value' => '=', 'name' => t('Equal ='));
 644      $punctuation['asterisk']           = array('value' => '*', 'name' => t('Asterisk *'));
 645      $punctuation['ampersand']          = array('value' => '&', 'name' => t('Ampersand &'));
 646      $punctuation['percent']            = array('value' => '%', 'name' => t('Percent %'));
 647      $punctuation['caret']              = array('value' => '^', 'name' => t('Caret ^'));
 648      $punctuation['dollar']             = array('value' => '$', 'name' => t('Dollar $'));
 649      $punctuation['hash']               = array('value' => '#', 'name' => t('Hash #'));
 650      $punctuation['at']                 = array('value' => '@', 'name' => t('At @'));
 651      $punctuation['exclamation']        = array('value' => '!', 'name' => t('Exclamation !'));
 652      $punctuation['tilde']              = array('value' => '~', 'name' => t('Tilde ~'));
 653      $punctuation['left_parenthesis']   = array('value' => '(', 'name' => t('Left parenthesis ('));
 654      $punctuation['right_parenthesis']  = array('value' => ')', 'name' => t('Right parenthesis )'));
 655      $punctuation['question_mark']      = array('value' => '?', 'name' => t('Question mark ?'));
 656      $punctuation['less_than']          = array('value' => '<', 'name' => t('Less than <'));
 657      $punctuation['greater_than']       = array('value' => '>', 'name' => t('Greater than >'));
 658      $punctuation['slash']              = array('value' => '/', 'name' => t('Slash /'));
 659      $punctuation['back_slash']         = array('value' => '\\', 'name' => t('Backslash \\'));
 660    }
 661  
 662    return $punctuation;
 663  }
 664  
 665  /**
 666   * Fetch the maximum length of the {url_alias}.dst field from the schema.
 667   *
 668   * @return
 669   *   An integer of the maximum URL alias length allowed by the database.
 670   */
 671  function _pathauto_get_schema_alias_maxlength() {
 672    static $maxlength;
 673    if (!isset($maxlength)) {
 674      $schema = drupal_get_schema('url_alias');
 675      $maxlength = $schema['fields']['dst']['length'];
 676    }
 677    return $maxlength;
 678  }
 679  
 680  /**
 681   * Fetch an array of non-raw tokens that have matching raw tokens.
 682   *
 683   * @return
 684   *   An array of tokens.
 685   */
 686  function _pathauto_get_raw_tokens() {
 687    static $raw_tokens;
 688  
 689    if (!isset($raw_tokens)) {
 690      $raw_tokens = array();
 691  
 692      // Build one big list of tokens.
 693      foreach (token_get_list('all') as $tokens) {
 694        $raw_tokens = array_merge($raw_tokens, array_keys($tokens));
 695      }
 696  
 697      // Filter out any tokens without -raw as a suffix.
 698      foreach ($raw_tokens as $index => $token) {
 699        if (substr($token, -4) !== '-raw') {
 700          unset($raw_tokens[$index]);
 701        }
 702      }
 703  
 704      array_unique($raw_tokens);
 705    }
 706  
 707    return $raw_tokens;
 708  }
 709  
 710  /**
 711   * Return all the possible paths of the i18n-ascii.txt transliteration file.
 712   *
 713   * @return
 714   *   An array of possible file paths.
 715   */
 716  function _pathauto_get_i18n_possible_files() {
 717    $file = 'i18n-ascii.txt';
 718    $files = array(
 719      conf_path() . '/' . $file,
 720      "sites/all/$file",
 721      drupal_get_path('module', 'pathauto') . '/' . $file,
 722    );
 723    // Always prefer $conf['pathauto_i18n_file'] if defined.
 724    if ($conf_file = variable_get('pathauto_i18n_file', '')) {
 725      array_unshift($files, $conf_file);
 726    }
 727    return $files;
 728  }
 729  
 730  /**
 731   * Fetch the path to the i18n-ascii.txt transliteration file
 732   *
 733   * @return
 734   *   The complete path or FALSE if not found in any of the possible paths.
 735   *
 736   * @see _pathauto_get_i18n_possible_files()
 737   */
 738  function _pathauto_get_i18n_file() {
 739    static $i18n_file;
 740  
 741    if (!isset($i18n_file)) {
 742      $i18n_file = FALSE;
 743      foreach (_pathauto_get_i18n_possible_files() as $file) {
 744        if (file_exists($file)) {
 745          $i18n_file = $file;
 746          break;
 747        }
 748      }
 749    }
 750  
 751    return $i18n_file;
 752  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7