--- uploadpath.module 2008-11-08 23:23:30.000000000 +0000 +++ uploadpath-patched.module 2010-09-22 02:19:42.000000000 +0000 @@ -29,70 +29,111 @@ function uploadpath_nodeapi(&$node, $op, switch ($op) { case 'insert': case 'update': - if( !in_array($node->type, variable_get('uploadpath_excluded_node_types',array())) ){ - if(isset($node->files) && user_access('upload files')) { - foreach ($node->files as $key => $file) { - if(is_object($file)){ - $file = (array)$file; // if object then type cast as array - } - // Only rewrite the path on new files to be saved - if ($file['new'] && !$file['remove']){ - //get the token path pattern - $pattern = variable_get('uploadpath_prefix_'.$node->type, false); - if(!$pattern){ - //default pattern - $pattern = variable_get('uploadpath_prefix', '[type]/[yyyy]/[mm]'); - } - if(variable_get('uploadpath_clean_filenames', false) && $node->title){ - //convert filename into meaningful semantic name based on node title or file desc :-) - //e.g: 'DC100_1.jpg' becomes 'the_quick_brown_fox_a3de.jpg' - if($file['description'] && strlen($file['description']) > 3){ - $filename_root = $file['description']; //base filename on file desc - }else{ - $filename_root = $node->title; //base filename on node title - } - //drupal_set_message($filename_root); - //get path info of file - $file_info = pathinfo($file['filename']); - /*crop lowercase node title to max - replace anything except numbers and letters with underscore - add 10 digit unique id and file extension*/ - $file_name = substr($filename_root, 0, 50); - //replace anything except numbers and letters with an underscore - $file_name = preg_replace("/([^a-z0-9])/", '_', strtolower($file_name)); - //replace multiple underscores with a single one - $file_name = preg_replace("/_+/", '_', $file_name); - $file_name .= '_'. substr(uniqid(rand(), true),0,5). '.'. $file_info['extension']; - // apply new, prefixed file name by token replacing the path pattern - $file_path = token_replace($pattern . '/', 'node', $node); - $file_name = $file_path . $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)) . $file['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); - } - //move file to new subfolder - if (file_move($file['filepath'], $file_name, FILE_EXISTS_RENAME)) { - //update node file array with new path, if needed - $node->files[$key]['filepath'] = $file_name; - // update file record in database - db_query("UPDATE {files} SET filepath = '%s' WHERE fid = %d", $file['filepath'], $file['fid']); - } - //drupal_set_message('
AFTER:'.print_r($node->files[$key],1).'
'); - } + if (!in_array($node->type, variable_get('uploadpath_excluded_node_types',array()))) { + if(isset($node->files) && user_access('upload files')) { + _uploadpath_process_files(&$node, &$node->files); } } + break; + } +} + +/** + * Implements hook_comment(). + */ +function uploadpath_comment($a1, $op) { + switch ($op) { + case 'insert': + case 'update': + $node = node_load($a1['nid']); + if (!in_array($node->type, variable_get('uploadpath_excluded_node_types',array()))){ + if (isset($a1['files']) && user_access('upload files')) { + _uploadpath_process_files(&$node, &$a1['files']); + } + } + break; + } +} + +/* + * Process the files array + */ +function _uploadpath_process_files(&$node, &$files) { + // Process entire array + foreach ($files as $key => $file) { + // If file is object then type cast as array + if(is_object($file)) { + $file = (array) $file; + } + // Only rewrite the path on new files to be saved + if ($file['new'] && !$file['remove']) { + // Get file name + $file_name = _uploadpath_get_filename(&$node, &$file); + + // Move file to new subfolder + if (file_move($file['filepath'], $file_name, FILE_EXISTS_RENAME)) { + // Update node file array with new path, if needed + $files[$key]['filepath'] = $file_name; + // Update file record in database + db_query("UPDATE {files} SET filepath = '%s' WHERE fid = %d", $file['filepath'], $file['fid']); + } + //drupal_set_message('
AFTER:'.print_r($files[$key],1).'
'); + } + } +} + +/* + * Construct new file name based on settings + */ +function _uploadpath_get_filename(&$node, &$file) { + // Get the token path pattern + $pattern = variable_get('uploadpath_prefix_'.$node->type, false); + // Default pattern + if (!$pattern) { + $pattern = variable_get('uploadpath_prefix', '[type]/[yyyy]/[mm]'); + } + + // Process clean files names as needed + if(variable_get('uploadpath_clean_filenames', false) && $node->title){ + // Convert filename into meaningful semantic name based on node title or file desc :-) + // e.g: 'DC100_1.jpg' becomes 'the_quick_brown_fox_a3de.jpg' + if($file['description'] && strlen($file['description']) > 3){ + $filename_root = $file['description']; // Base filename on file desc + } else { + $filename_root = $node->title; // Base filename on node title } - break; + // drupal_set_message($filename_root); + + // Get path info of file + $file_info = pathinfo($file['filename']); + // Crop lowercase node title to max + $file_name = substr($filename_root, 0, 50); + // Replace anything except numbers and letters with an underscore + $file_name = preg_replace("/([^a-z0-9])/", '_', strtolower($file_name)); + // Replace multiple underscores with a single one + $file_name = preg_replace("/_+/", '_', $file_name); + // Add 10 digit unique id and file extension + $file_name .= '_'. substr(uniqid(rand(), true),0,5). '.'. $file_info['extension']; + // Apply new, prefixed file name by token replacing the path pattern + $file_path = token_replace($pattern . '/', 'node', $node); + $file_name = $file_path . $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)) . $file['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); } + return $file_name; }