title) * @param $src * The "real" URI of the content to be aliased (e.g., "node/$node->nid") * @param $type * For modules which provided patternitems in hook_pathauto(), * the relevant identifier for the specific item to be aliased (e.g., * $node->type) * @return * The alias that was created */ function pathauto_create_alias($module, $op, $placeholders, $src, $type = NULL) { if (($op != 'bulkupdate') and variable_get('pathauto_verbose', FALSE)) { $verbose = TRUE; } else { $verbose = FALSE; } // Retrieve and apply the pattern for this content type $pattern = ''; if ($type) { $pattern = drupal_strtolower(variable_get('pathauto_'. $module .'_'. $type .'_pattern', '')); } if (!trim($pattern)) { $pattern = drupal_strtolower(variable_get('pathauto_'. $module .'_pattern', '')); } // No pattern? Do nothing (otherwise we may blow away existing aliases...) if (!trim($pattern)) { return ''; } // Special handling when updating an item which is already aliased. $pid = NULL; if ($op == 'update' or $op == 'bulkupdate') { $result = db_query("SELECT pid, dst FROM {url_alias} WHERE src='%s'", $src); if ($data = db_fetch_object($result)) { // The item is already aliased, check what to do... switch (variable_get('pathauto_update_action', 2)) { // Do nothing case 0: return ''; // Add new alias in addition to old one case 1: $oldalias = $data->dst; break; // Replace old alias - remember the pid to update case 2: $pid = $data->pid; $oldalias = $data->dst; break; default: break; } } } // Replace the placeholders with the values provided by the module, // and lower-case the result $alias = str_replace($placeholders['tokens'], $placeholders['values'], $pattern); $alias = drupal_strtolower($alias); // Two or more slashes should be collapsed into one $alias = preg_replace("/\/+/", "/", $alias); // Trim any leading or trailing slashes $alias = preg_replace("/^\/|\/+$/", "", $alias); $maxlength = min(variable_get('pathauto_max_length', 100), 128); $alias = drupal_substr($alias, 0, $maxlength); // If the alias already exists, generate a new variant $separator = variable_get('pathauto_separator', '-'); if (_pathauto_alias_exists($alias, $src)) { for ($i = 0; _pathauto_alias_exists($alias . $separator . $i, $src); $i++) { } // Make room for the sequence number $alias = drupal_substr($alias, 0, $maxlength - 1 -($i/10 + 1)); $alias = $alias . $separator . $i; } // If $pid is NULL, a new alias is created - otherwise, the existing // alias for the designated src is replaced _pathauto_set_alias($src, $alias, $pid, $verbose, $oldalias); // Also create a related feed alias if requested, and if supported // by the module if (variable_get('pathauto_'. $module .'_applytofeeds', FALSE)) { $feedappend = variable_get('pathauto_'. $module .'_supportsfeeds', ''); // Handle replace case (get existing pid) _pathauto_set_alias("$src/$feedappend", "$alias/feed", NULL, $verbose); } return $alias; } /** * Verifies if the given path is a valid menu callback. * Taken from menu_execute_active_handler(). * * @param $path * A string containing a relative path. * * @return * TRUE if the path already exists. */ function _pathauto_path_is_callback($path) { static $menu = NULL; if (is_null($menu)) { $menu = menu_get_menu(); } // Determine the menu item containing the callback. return isset($menu["callbacks"][$path]); } /** * Private function for pathauto to create an alias * * @param $src * The internal path * @param $dst * The visible externally used path. * @param $pid * If the item is currently aliased, the pid for that item. * @param $verbose * If the admin has enabled verbose, should be TRUE. Else FALSE or NULL. * @param $oldalias * If the item is currently aliased, the existing alias for that item. * */ function _pathauto_set_alias($src, $dst, $pid = NULL, $verbose = FALSE, $oldalias = NULL) { // Alert users that an existing callback cannot be overridden automatically if (_pathauto_path_is_callback($dst)) { if ($verbose and user_access('create url aliases')) { drupal_set_message(t('Ignoring alias '). $dst .t(' due to existing path conflict')); } return; } // Skip replacing the current alias with an identical alias if ($oldalias != $dst) { path_set_alias($src, $dst, $pid, 1, 10); if ($verbose and user_access('create url aliases')) { if ($pid) { drupal_set_message(t('Created new alias %dst for %src, replacing %oldalias', array('%dst' => $dst, '%src' => $src, '%oldalias' => $oldalias))); } else { drupal_set_message(t('Created new alias %dst for %src', array('%dst' => $dst, '%src' => $src))); } } } } /** * Generalized function to get tokens across all Pathauto types * * @param $object * A user, node, or category object. * * @return * tokens for that object formatted in the way that Pathauto expects to see them. * */ function pathauto_get_placeholders($type, $object) { $full = token_get_values($type, $object, TRUE); $tokens = token_prepare_tokens($full->tokens); $values = pathauto_clean_token_values($full->values); return array('tokens' => $tokens, 'values' => $values); } /** * Cleans tokens so they are URL friendly * * @param $values * An array of token values that need to be "cleaned" for use in the URL * */ function pathauto_clean_token_values($values) { foreach ($values as $key => $value) { $values[$key] = pathauto_cleanstring($value); } return $values; }