[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

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

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


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7