--- uploadpath.original.module	2008-05-05 15:41:10.000000000 +1200
+++ uploadpath.module	2008-05-25 01:31:32.000000000 +1200
@@ -1,5 +1,5 @@
 <?php
-// $Id: uploadpath.module,v 1.1.2.3 2008/05/05 03:41:10 crell Exp $
+// $Id: uploadpath.module,v 1.1.2.2 2007/06/15 22:44:39 crell Exp $
 
 /**
  * @file
@@ -35,9 +35,55 @@ function uploadpath_admin_settings() {
 
   $form['uploadpath_prefix'] = array(
     '#type' => 'textfield',
-    '#title' => t('Pattern for the file prefix'),
+    '#title' => t('Default pattern for the file path prefix'),
     '#description' => t('Specify the pattern to prefix to file names uploaded with the upload module.  It will be appended after the site files directory (e.g., files) but before the file name itself.  Do not include a leading or trailing slash.  Spaces will be converted to underscores to avoid file system issues.'),
     '#default_value' => variable_get('uploadpath_prefix', ''),
+    '#weight' => -9
+  );
+  
+  $form['misc'] = array(
+    '#title' => t('Miscellaneous'),
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#description' => t('Other settings'),
+    '#weight' => -6
+  );
+  
+  $form['misc']['uploadpath_bugfix1'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Set node created and updated time, if not set'),
+    '#return_value' => 1,
+    '#default_value' => variable_get('uploadpath_bugfix1', true),
+    '#description' => t('This is a bugfix for this issue http://drupal.org/node/153737 where [yyyy] etc isn\'t evaluated properly and is only useful if you\'re using date tokens in your paths.'),
+    '#weight' => 0,
+  );
+  
+  $form['misc']['uploadpath_clean_filenames'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Clean file upload filenames'),
+    '#return_value' => 1,
+    '#default_value' => variable_get('uploadpath_clean_filenames', true),
+    '#description' => t('Rename uploaded files based on node title. characters other than numbers and letters are replaced with underscore and a unique id is appended. maximum length is 45 characters.'),
+    '#weight' => 0,
+  );
+  
+  $form['node_types_exclude'] = array(
+    '#title' => t('Excluded node types'),
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#description' => t('Select the node types to exclude from upload path processing'),
+    '#weight' => -8
+  );
+  
+  $form['node_types'] = array(
+    '#title' => t('Patterns for each node type'),
+    '#type' => 'fieldset',
+    '#collapsible' => TRUE,
+    '#collapsed' => TRUE,
+    '#description' => t('Patterns for node types. If empty, the default pattern will be used.'),
+    '#weight' => -7
   );
   
   $form['token_help'] = array(
@@ -46,11 +92,38 @@ function uploadpath_admin_settings() {
     '#collapsible' => TRUE,
     '#collapsed' => TRUE,
     '#description' => t('Prefer raw-text replacements for text to avoid problems with HTML entities!'),
+    '#weight' => -6
   );
   $form['token_help']['help'] = array(
     '#value' => theme('token_help', 'node'),
   );
-
+  
+  //node type settings
+  $node_types = node_get_types();
+  foreach($node_types as $type){
+  	$types[$type->type] = $type->name;
+  }
+  //set excluded node types
+  $form['node_types_exclude']['uploadpath_excluded_node_types'] = array(
+    '#type' => 'select',
+  	'#multiple' => true,
+    '#title' => t('Excluded Node Types'),
+    '#default_value' => variable_get('uploadpath_excluded_node_types', array()),
+    '#description' => t('Select the node types to exclude from uploadpath processing.'),
+  	'#options' => $types,
+  );
+  
+  foreach($node_types as $type){
+  	//only show settings if not excluded
+  	if(!in_array($type->type, variable_get('uploadpath_excluded_node_types',array()))){
+	  	$form['node_types']['uploadpath_prefix_'.$type->type] = array(
+	    '#type' => 'textfield',
+	    '#title' => t('Path pattern for '.$type->name),
+	    '#description' => t('Specify the path pattern to prefix for '.$type->name.' type nodes'),
+	    '#default_value' => variable_get('uploadpath_prefix_'.$type->type, ''),  	
+	  	);
+  	}
+  }
   return system_settings_form($form);
 }
 
@@ -60,28 +133,55 @@ function uploadpath_admin_settings() {
 function uploadpath_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
   switch ($op) {
     case 'submit':
-      if (isset($node->files)) {
-        foreach ($node->files as $key => $file) {
-          if (0 === strpos($key, 'upload_')) {  // Only rewrite the name when adding the file, not when updating it
-            // Get the new, prefixed file name
-            $file_name = str_replace(array(' ', "\n", "\t"), '_', token_replace(variable_get('uploadpath_prefix', '') . '/', 'node', $node)) . $node->files[$key]['filename'];
-
-            // SECURITY NOTE:
-            // Tokens include user supplied information and could provide an attack vector.
-            // The current method of creating directories prevents the use of .. or other malicious
-            // paths, but future developers should keep this in mind when modifying the following code
-
-            // Create the directory if it doesn't exist yet.
-            $dirs = explode('/', dirname($file_name));
-            $directory = file_directory_path();
-            while (count($dirs)) {
-              $directory .= '/' . array_shift($dirs);
-              file_check_directory($directory, FILE_CREATE_DIRECTORY);
-            }
-            // Change where the file will be saved to the specified directory.
-            $node->files[$key]['filename'] = $file_name;
-          }
-        }
+      if(!in_array($node->type, variable_get('uploadpath_excluded_node_types',array()))){
+	      if (isset($node->files)) {
+	        foreach ($node->files as $key => $file) {
+	          if (0 === strpos($key, 'upload_')) {  // Only rewrite the name when adding the file, not when updating it
+	          	
+	            //optional 
+	            if(variable_get('uploadpath_bugfix1', true)){
+		            //bugfix: set node created and updated timestamp if not set for token replace
+		            //see http://drupal.org/node/153737
+		            if(!$node->created){$node->created = (int)time();}
+		            if(!$node->changed){$node->changed = (int)$node->created;}
+	            }
+	            
+	            //get the token path pattern
+	            $pattern = variable_get('uploadpath_prefix_'.$node->type,false);
+	            if(!$pattern){ 
+		            //default pattern
+		            $pattern = variable_get('uploadpath_prefix', '');
+	            }
+                    
+                    if(variable_get('uploadpath_clean_filenames', true) && $node->title){
+                      //convert filename into semantic name based on node title :-)
+                      //get path info of file
+                      $file_info = pathinfo($node->files[$key]['filename']);
+                      /*crop lowercase node title to 35 chars max
+                        replace anything except numbers and letters with underscore
+                        add 10 digit unique id and file extension*/
+                      $file_name = preg_replace("/([^a-z0-9])/", '_', strtolower(substr($node->title, 0, 35))). '_'. substr(uniqid(),0,10). '.'. $file_info['extension'];
+                      // apply new, prefixed file name by token replacing the path pattern
+                      $file_name = str_replace(array(' ', "\n", "\t"), '_', token_replace($pattern . '/', 'node', $node)) . $file_name;
+                    }else{
+                      // apply new, prefixed file name by token replacing the path pattern
+                      $file_name = str_replace(array(' ', "\n", "\t"), '_', token_replace($pattern . '/', 'node', $node)) . $node->files[$key]['filename'];                      
+                    }
+	
+	            // Create the directory if it doesn't exist yet.
+	            $dirs = explode('/', dirname($file_name));
+	            $directory = file_directory_path();
+	            while (count($dirs)) {
+	              $directory .= '/' . array_shift($dirs);
+	              file_check_directory($directory, FILE_CREATE_DIRECTORY);
+	            }
+	            // Change where the file will be saved to the specified directory.
+	            $node->files[$key]['filename'] = $file_name;
+                    //drupal_set_message('<pre>'.print_r($node->files[$key],1).'</pre>');
+
+	          }
+	        }
+	      }
       }
       break;
   }
