Index: image/image.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/image/image.module,v
retrieving revision 1.209.2.49
diff -u -p -r1.209.2.49 image.module
--- image/image.module 13 Nov 2007 03:23:07 -0000 1.209.2.49
+++ image/image.module 27 Nov 2007 03:53:03 -0000
@@ -89,11 +89,22 @@ function image_admin_settings() {
'#type' => 'fieldset',
'#title' => t('File paths')
);
- $form['paths']['image_default_path'] = array(
- '#type' => 'textfield',
- '#title' => t('Default image path'),
- '#default_value' => variable_get('image_default_path', 'images'),
- '#description' => t('Subdirectory in the directory "%dir" where pictures will be stored. Do not include trailing slash.', array('%dir' => variable_get('file_directory_path', 'files'))),
+
+ $example_tokens = array(
+ '%nodepath' => 'safe/url/example' ,
+ '%filename' => 'sample',
+ '%label' => 'thumb',
+ '%extension' => 'jpg',
+ '%nid' => 666,
+ '%uid' => $GLOBALS['user']->uid
+ );
+ $example_path = variable_get('file_directory_path', 'files') .'/'. strtr(variable_get('image_derivatives_filename_pattern', _image_default_filename_pattern()), $example_tokens );
+
+ $form['paths']['image_derivatives_filename_pattern'] = array(
+ '#type' => 'textfield',
+ '#title' => t('Filename naming pattern'),
+ '#default_value' => variable_get('image_derivatives_filename_pattern', _image_default_filename_pattern()),
+ '#description' => t('Pattern to use when creating derivatives (like thumbnails) for an image. Available tokens are: %tokens.
%example_path',array('%tokens' => join(', ', array_keys($example_tokens)), '%example_path' => $example_path) ) ); $form['image_max_upload_size'] = array( @@ -166,6 +177,15 @@ function image_admin_settings() { } /** + * Return the default filename pattern, incorporating the old 'images' directory + * path if appropriate. + */ +function _image_default_filename_pattern() { + // image_default_path is no longer used, but referenced here for backwards compatability + return variable_get('image_default_path', 'images') .'/%filename.%label.%extension'; +} + +/** * Check that the sizes provided have the required amount of information. */ function image_settings_sizes_validate(&$form) { @@ -336,7 +356,7 @@ function image_prepare(&$node, $field_na } // Save the file to the temp directory. - $file = file_save_upload($field_name, _image_filename($file->filename, IMAGE_ORIGINAL, TRUE)); + $file = file_save_upload($field_name, _image_filename($file->filename, IMAGE_ORIGINAL, TRUE, $node)); if (!$file) { return; } @@ -917,7 +937,7 @@ function _image_build_derivatives(&$node // Resize for the necessary sizes. foreach ($needed_sizes as $key => $size) { - $destination = _image_filename($original_path, $key, $temp); + $destination = _image_filename($original_path, $key, $temp, $node); if (!image_scale($original_path, $destination, $size['width'], $size['height'])) { drupal_set_message(t('Unable to create scaled %label image', array('%label' => $size['label'])), 'error'); return FALSE; @@ -930,29 +950,53 @@ function _image_build_derivatives(&$node /** * Creates an image filename. */ -function _image_filename($filename, $label = IMAGE_ORIGINAL, $temp = FALSE) { - $path = variable_get('image_default_path', 'images') .'/'; - if ($temp) { - $path .= 'temp/'; - } - +function _image_filename($filename, $label = IMAGE_ORIGINAL, $temp = FALSE, $node = NULL) { $filename = basename($filename); + $pos = strrpos($filename, '.'); - // Insert the resized name in non-original images - if ($label && ($label != IMAGE_ORIGINAL)) { - $pos = strrpos($filename, '.'); - if ($pos === false) { - // The file had no extension - which happens in really old image.module - // versions, so figure out the extension. - $image_info = image_get_info(file_create_path($path . $filename)); - $filename = $filename .'.'. $label .'.'. $image_info['extension']; - } - else { - $filename = substr($filename, 0, $pos) .'.'. $label . substr($filename, $pos); - } + // Build filename according to token pattern. + $tokens = array( + '%nodepath' => $node->path ? $node->path : 'node-'. $node->nid, + '%filename' => substr($filename, 0, strpos($filename, '.')), + '%label' => $label, + '%extension' => substr($filename, $pos+1), + '%nid' => $node->nid, + '%uid' => $node->uid, + ); + + // Even original images may be renamed, but they won't include the derivative label + + if ($label == IMAGE_ORIGINAL) { + $tokens['%label'] = ''; + } + + if ($pos === false) { + // The file had no extension - which happens in really old image.module + // versions, so figure out the extension, and construct the filename again. + $image_info = image_get_info(file_create_path($path . $filename)); + $tokens['%filename'] = $filename; + $tokens['%extension'] = $image_info['extension']; + $filepath = strtr(variable_get('image_derivatives_filename_pattern', _image_default_filename_pattern()), $tokens); } - return file_create_path($path . $filename); + $filepath = strtr(variable_get('image_derivatives_filename_pattern', _image_default_filename_pattern()), $tokens); + + // Sanitize possible typos and collapse dividers around tokens that are not there. + // TODO test edge cases + $filepath = preg_replace('|([/_\-\.])[/_\-\.]|', '$1', $filepath); + if ($temp) { + $filepath = 'temp/'. $filepath; + } + // TODO repair bad characters & spaces in uploaded filenames? + + $fullpath = file_directory_path() .'/'. $filepath; + #drupal_set_message("Returning image full filepath $fullpath"); + + // When using advanced filename patterns, we may need to ensure a directory to put this image into exists + $target_dir = dirname($fullpath); + if(! is_dir($target_dir)){ image_mkdirs($target_dir); } + + return $fullpath; } /** @@ -1029,7 +1073,7 @@ function _image_is_required_size($size) */ function _image_insert(&$node, $size, $image_path) { $original_path = $node->images[IMAGE_ORIGINAL]; - if (file_move($image_path, _image_filename($original_path, $size))) { + if (file_move($image_path, _image_filename($original_path, $size, FALSE, $node))) { // Update the node to reflect the actual filename, it may have been changed // if a file of the same name already existed. $node->images[$size] = $image_path; @@ -1117,3 +1161,11 @@ function image_create_node_from($filepat return $node; } +/** + * Recursive mkdir. Utility func + */ +function image_mkdirs($strPath, $mode = 0777) { + if(! $strPath){ trigger_error("Null call to image_mkdirs()", E_USER_WARNING); } + return is_dir($strPath) or ( image_mkdirs(dirname($strPath), $mode) and mkdir($strPath, $mode) ); +} +