? .pathauto.inc.swp
? multipath.patch
Index: pathauto.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto.inc,v
retrieving revision 1.1.2.51
diff -u -p -r1.1.2.51 pathauto.inc
--- pathauto.inc	18 Jun 2008 20:05:08 -0000	1.1.2.51
+++ pathauto.inc	31 Oct 2008 17:28:52 -0000
@@ -91,20 +91,20 @@ function _pathauto_alias_exists($alias, 
  */
 function _pathauto_existing_alias_data($src) {
   $output = array(
-    'pid' => '',
-    'old_alias' => ''
+    'pid' => array(),
+    'old_alias' => array(),
   );
   $result = db_query("SELECT pid, dst FROM {url_alias} WHERE src='%s'", $src);
-  if ($data = db_fetch_object($result)) {
+  while ($data = db_fetch_object($result)) {
     // The item is already aliased, check what to do...
     switch (variable_get('pathauto_update_action', 2)) {
       // Replace old alias - remember the pid to update
       case 2:
       case 3:
-        $output['pid'] = $data->pid;
+        $output['pid'][] = $data->pid;
       // Add new alias in addition to old one
       case 1:
-        $output['old_alias'] = $data->dst;
+        $output['old_alias'][] = $data->dst;
         break;
       // Do nothing
       case 0:
@@ -141,6 +141,12 @@ function pathauto_cleanstring($string, $
   $punctuation = pathauto_punctuation_chars();
   foreach ($punctuation as $name => $details) {
     $action = variable_get('pathauto_punctuation_'. $name, 0);
+
+    // TODO make this configurable?
+    // ; is reserved for multipath separator
+    if ($details['value'] == ';') {
+      $action = 2;
+    }
     // 2 is the action for "do nothing" with the punctuation
     if ($action != 2) {
       // Slightly tricky inline if which either replaces with the separator or nothing
@@ -273,63 +279,77 @@ function pathauto_create_alias($module, 
       return '';
     }
     $update_data = _pathauto_existing_alias_data($src);
-    $pid = $update_data['pid'];
-    $old_alias = $update_data['old_alias'];
+    $pid = array_shift($update_data['pid']);
+    $old_alias = array_shift($update_data['old_alias']);
   }
 
-  // Replace the placeholders with the values provided by the module,
-  // and optionally lower-case the result
-  $alias = str_replace($placeholders['tokens'], $placeholders['values'], $pattern);
-
-  if (variable_get('pathauto_case', 1)) {
-    $alias = drupal_strtolower($alias);
+  // TODO for now i assume multialias nodes have [multi-*][...] patterns
+  $pattern_exploded = explode('/', $pattern);
+  if (drupal_substr($pattern_exploded[0], 1, 5) == 'multi') {
+    $aliases = array();
+    $aliases = _pathauto_replace_multiple($placeholders, $pattern);
+    $update_data = _pathauto_existing_alias_data($src);
+    foreach ($aliases as $alias) {
+      $pid = array_shift($update_data['pid']);
+      $old_alias = array_shift($update_data['old_alias']);
+      _pathauto_set_alias($src, $alias, $module, $entity_id, $pid, $verbose, $old_alias);
+    }
   }
+  else {
+    // Replace the placeholders with the values provided by the module,
+    // and optionally lower-case the result
+    $alias = str_replace($placeholders['tokens'], $placeholders['values'], $pattern);
 
-  // Two or more slashes should be collapsed into one
-  $alias = preg_replace('/\/+/', '/', $alias);
+    if (variable_get('pathauto_case', 1)) {
+      $alias = drupal_strtolower($alias);
+    }
 
-  // Trim any leading or trailing slashes
-  $alias = preg_replace('/^\/|\/+$/', '', $alias);
+    // Two or more slashes should be collapsed into one
+    $alias = preg_replace('/\/+/', '/', $alias);
 
-  $maxlength = min(variable_get('pathauto_max_length', 100), 128);
-  $alias = drupal_substr($alias, 0, $maxlength);
+    // Trim any leading or trailing slashes
+    $alias = preg_replace('/^\/|\/+$/', '', $alias);
 
-  // If the alias already exists, generate a new, hopefully unique, variant
-  $separator = variable_get('pathauto_separator', '-');
-  if (_pathauto_alias_exists($alias, $src)) {
-    $original_alias = $alias;
-    for ($i = 0; _pathauto_alias_exists(drupal_substr($alias, 0, $maxlength - strlen($i)) . $separator . $i, $src); $i++) {
-    }
-    // Make room for the sequence number
-    $alias = drupal_substr($alias, 0, $maxlength - drupal_strlen($i));
-    $alias = $alias . $separator . $i;
-    // If verbose is on, alert the user why this happened
-    if ($verbose) {
-      drupal_set_message(t('The automatically generated alias %original_alias conflicted with an existing alias. Alias changed to %alias.',
-        array('%original_alias' => $original_alias, '%alias' => $alias)));
-    }
-  }
+    $maxlength = min(variable_get('pathauto_max_length', 100), 128);
+    $alias = drupal_substr($alias, 0, $maxlength);
 
-  // If $pid is NULL, a new alias is created - otherwise, the existing
-  // alias for the designated src is replaced
-  _pathauto_set_alias($src, $alias, $module, $entity_id, $pid, $verbose, $old_alias);
-
-  // Also create a related feed alias if requested, and if supported
-  // by the module
-  if (drupal_strlen(variable_get('pathauto_'. $module .'_applytofeeds', ''))) {
-    $feedappend = variable_get('pathauto_'. $module .'_applytofeeds', '');
-
-    // For forums and taxonomies, the src doesn't always form the base of the rss feed (ie. image galleries)
-    if ($module == 'taxonomy' || $module == 'forum') {
-      $update_data = _pathauto_existing_alias_data("taxonomy/term/$entity_id/$feedappend");
-      _pathauto_set_alias("taxonomy/term/$entity_id/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pid'], $verbose, $update_data['old_alias']);
+    // If the alias already exists, generate a new, hopefully unique, variant
+    $separator = variable_get('pathauto_separator', '-');
+    if (_pathauto_alias_exists($alias, $src)) {
+      $original_alias = $alias;
+      for ($i = 0; _pathauto_alias_exists(drupal_substr($alias, 0, $maxlength - strlen($i)) . $separator . $i, $src); $i++) {
+      }
+      // Make room for the sequence number
+      $alias = drupal_substr($alias, 0, $maxlength - drupal_strlen($i));
+      $alias = $alias . $separator . $i;
+      // If verbose is on, alert the user why this happened
+      if ($verbose) {
+        drupal_set_message(t('The automatically generated alias %original_alias conflicted with an existing alias. Alias changed to %alias.',
+          array('%original_alias' => $original_alias, '%alias' => $alias)));
+      }
     }
-    else {
-      $update_data = _pathauto_existing_alias_data("$src/$feedappend");
-      _pathauto_set_alias("$src/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pid'], $verbose, $update_data['old_alias']);
+
+    // If $pid is NULL, a new alias is created - otherwise, the existing
+    // alias for the designated src is replaced
+    _pathauto_set_alias($src, $alias, $module, $entity_id, $pid, $verbose, $old_alias);
+
+    // Also create a related feed alias if requested, and if supported
+    // by the module
+    if (drupal_strlen(variable_get('pathauto_'. $module .'_applytofeeds', ''))) {
+      $feedappend = variable_get('pathauto_'. $module .'_applytofeeds', '');
+
+      // For forums and taxonomies, the src doesn't always form the base of the rss feed (ie. image galleries)
+      if ($module == 'taxonomy' || $module == 'forum') {
+        $update_data = _pathauto_existing_alias_data("taxonomy/term/$entity_id/$feedappend");
+        _pathauto_set_alias("taxonomy/term/$entity_id/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pid'], $verbose, $update_data['old_alias']);
+      }
+      else {
+        $update_data = _pathauto_existing_alias_data("$src/$feedappend");
+        _pathauto_set_alias("$src/$feedappend", "$alias/feed", $module, $entity_id, $update_data['pid'], $verbose, $update_data['old_alias']);
+      }
     }
-  }
 
+  }
   return $alias;
 }
 
@@ -501,3 +521,44 @@ function pathauto_punctuation_chars() {
 
   return $punctuation;
 }
+
+/**
+ * Helper function to create multiple aliases
+ * @param $placeholders array of tokens and values
+ * @param $pattern the replace pattern we work on
+ * @return the array of ready aliases
+ */
+function _pathauto_replace_multiple($placeholders, $pattern) {
+  /**
+   * value => [id] => /path1;path1/path2;...
+   * token => [id] => multi-term-path-raw/stg else /...
+   */
+  $multitoken = '[multi-term-path-raw]';
+  $key = array_keys($placeholders['tokens'], $multitoken);
+  $key = $key[0];
+  $raw_paths = explode(';', $placeholders['values'][$key]);
+  // create new patterns for each raw multipath
+  $aliases = array();
+  foreach ($raw_paths as $path) {
+    $tokens = $placeholders['tokens'];
+    $values = $placeholders['values'];
+    // we just simply substitute $values[$key] with the actual $path from the iteration
+    $values[$key] = $path;
+    // do the usual substitution for all the parts
+    $alias = str_replace($tokens, $values, $pattern);
+
+    // 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, hopefully unique, variant
+    $separator = variable_get('pathauto_separator', '-');
+    $aliases[] = $alias;
+  }
+  return $aliases;
+}
Index: pathauto.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/pathauto/pathauto.module,v
retrieving revision 1.44.4.101
diff -u -p -r1.44.4.101 pathauto.module
--- pathauto.module	24 Jun 2008 16:04:11 -0000	1.44.4.101
+++ pathauto.module	31 Oct 2008 17:28:53 -0000
@@ -113,6 +113,19 @@ function pathauto_token_values($type, $o
           // In the realm of nodes these are terms, in the realm of Taxonomy, cats
           $label = 'term';
 
+          // TODO multiple taxonomies: another foreach around it for that
+          $taxonomy = array_pop($object->taxonomy);
+          $lineage = array();
+          foreach ($taxonomy as $level => $term) { // order represents the lineage
+            $termname = db_result(db_query('SELECT name FROM {term_data} WHERE tid = %d', $term));
+            $name .= '/'. $termname;
+            $lineage[] = $name; // stack the levels
+          }
+          $values['multi-term-path-raw'] .= implode(';', $lineage);
+          // keeping the path-raw ending so pathauto_clean_token_values() doesn't filter / out
+          // using ; as a separator for the different entries, so we can handle it as an array
+          // in the search and replace phase
+
         case 'taxonomy':
         default:
           if (!isset($category)) {
