| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |