--- /home/sseverin/drupal/path_redirect-5.x-1.x/path_redirect.module	2007-12-20 20:46:19.000000000 -0600
+++ path_redirect.module	2007-12-20 21:01:39.000000000 -0600
@@ -24,14 +24,45 @@ function path_redirect_help($section) {
  */
 function path_redirect_init() {
   // see if this page has a redirect path
+  // first we build an array of possible path entries for the current path
   $query = '';
   if (isset($_SERVER['QUERY_STRING'])) {
     $query = preg_replace('/^q=([^&]*).*$/', '\1', $_SERVER['QUERY_STRING']);
   }
-  $r = db_fetch_object(db_query("SELECT redirect, query, fragment, type FROM {path_redirect} WHERE path = '%s' OR path = '%s'", $query, utf8_encode($query)));
+  $paths[] = $query;
+  $utf = utf8_encode($query); // the utf8 version
+  if ($utf != $query) {
+    $paths[] = $utf;
+  }
+  // then we stick '<*>' in each position and add those to the possibilities
+  $args = explode('/', $query);
+  foreach($args as $key => $val) {
+    $temp = $args;
+    $temp[$key] = '<*>';
+    $temp_path = implode('/', $temp);
+    if (!in_array($temp_path, $paths)) {
+      $paths[] = implode('/', $temp);
+    }
+  }
+  // sanitize everything
+  foreach ($paths as $key => $val) {
+    $paths[$key] = db_escape_string($val);
+  }
+  $r = db_fetch_object(db_query("SELECT path, redirect, query, fragment, type FROM {path_redirect} WHERE path IN ('". implode("','", $paths) ."') LIMIT 1"));
   if ($r) {
+    if (strpos($r->path, '<*>') !== FALSE) {
+      //find the position of the wildcard
+      $rargs = explode('/', $r->path);
+      foreach ($rargs as $key => $val) {
+        if (strpos($val, '<*>') !== FALSE) {
+          $r->redirect = str_replace('<*>', $args[$key], $r->redirect);
+          $r->query = str_replace('<*>', $args[$key], $r->query);
+          $r->fragment = str_replace('<*>', $args[$key], $r->fragment);
+          break;
+        }
+      }
+    }
     if (function_exists('drupal_goto')) {
-      // if there's a result found, do the redirect
       unset($_REQUEST['destination']);
       drupal_goto($r->redirect, ($r->query ? $r->query: NULL), ($r->fragment ? $r->fragment : NULL), $r->type);
     }
@@ -147,7 +178,7 @@ function path_redirect_admin($rid = FALS
       $path,
       check_url($redirect . $query . $fragment),
       $types[$r->type]['title'],
-      array('data' => l(t('test'), $r->path, array())),
+      array('data' => l(t('test'), preg_replace('/<\*>/', 'test', $r->path), array())),
       array('data' => l(t('edit'), 'admin/build/path_redirect/edit/'. $r->rid)),
       array('data' => l(t('delete'), 'admin/build/path_redirect/edit/'. $r->rid .'/delete')),
     );
@@ -181,7 +212,10 @@ function path_redirect_edit($edit = arra
   $form['path'] = array(
     '#type' => 'textfield',
     '#title' => t('From'),
-    '#description' => t('Enter a Drupal path or path alias to redirect'),
+    '#description' => t('Enter a Drupal path or path alias to redirect. <br/>
+      A single wildcard of <code>&lt;*&gt;</code> can be used as a distinct
+      path segment (separated by <code>/</code>).<br/>
+      Example: <code>photos/&lt;*&gt;/large</code>'),
     '#maxlength' => 255,
     '#default_value' => $edit['path'],
   );
@@ -191,7 +225,14 @@ function path_redirect_edit($edit = arra
     '#prefix' => '<div class="container-inline">',
     '#suffix' => '</div>',
     '#title' => t('To'),
-    '#description' => '<div style="display:block">'. t('Enter a Drupal path, path alias, or external URL to redirect to. Use %front to redirect to the front page.  Enter (optional) queries after "?" and (optional) anchor after "#". Most redirects will not contain queries or fragment anchors.', array('%front' => '<front>')) .'</div>',
+    '#description' => '<div style="display:block">'. t('Enter a Drupal path,
+      path alias, or external URL to redirect to. Use %front to redirect to
+      the front page.  Enter (optional) queries after "?" and (optional)
+      anchor after "#". Most redirects will not contain queries or fragment
+      anchors.<br/> If you entered a wildcard in the <em>From</em> field,
+      you can enter <code>&lt;*&gt;</code> in any of these fields to have
+      the value of the wildcard appear in the redirected path.',
+      array('%front' => '<front>')) .'</div>',
   );
 
   $form['redirect']['redirect'] = array(
@@ -268,11 +309,25 @@ function path_redirect_edit_validate($fo
   elseif (strstr($form_values['path'], '?')) {
     form_set_error('path', t('You cannot currently include a query in your redirect <strong>from</strong> path.'));
   }
-  elseif (!valid_url($form_values['path'])) {
+  elseif (strpos($form_values['path'], '<*>') === FALSE && !valid_url($form_values['path'])) {
     form_set_error('path', t('The redirect <strong>from</strong> path does not appear valid. This must be a local Drupal path.'));
   }
+  elseif (strpos($form_values['path'], '<*>') !== FALSE) {
+    // if we've got a wildcard, let's make sure it's by itself
+    $args = explode('/', $form_values['path']);
+    foreach($args as $key => $val) {
+      if (strpos($val, '<*>')) {
+        $val = str_replace('<*>', '', $val);
+        if (strlen($val)) {
+          $args[$key] = '<*>';
+          form_set_error('path', t('Wildcards in the redirect <strong>from</strong> path must be separate URL segments delimited by "/", for example: <em>user/<*>/edit</em>.<br />A valid path is: %path', array('%path' => implode('/', $args))));
+          break;
+        }
+      }
+    }
+  }
 
-  if (!valid_url($form_values['redirect']) && !valid_url($form_values['redirect'], TRUE) && $form_values['redirect'] != '<front>') {
+  if (valid_url($form_values['redirect']) && !valid_url($form_values['redirect'], TRUE) && $form_values['redirect'] != '<front>') {
     form_set_error('redirect', t('The redirect <strong>to</strong> path does not appear valid.'));
   }
 
