? imagecache/cvs ? imagecache/actions/cvs ? imagecache/po/cvs Index: imagecache/imagecache.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/imagecache/imagecache.module,v retrieving revision 1.54 diff -u -p -r1.54 imagecache.module --- imagecache/imagecache.module 21 Feb 2008 12:44:54 -0000 1.54 +++ imagecache/imagecache.module 8 Mar 2008 15:21:42 -0000 @@ -8,24 +8,24 @@ * Imagecache allows you to setup specialized identifiers for dynamic image * processing and caching. It abuses the rewrite rules used for drupal's clean * URLs to provide dynamic image generation. - * + * * Earlier security flaws were overcome by using 'presets' similar to * image.module. We don't fuss with the database, and creating data that we have * to keep up within Drupal. We do it on the fly and flush it when we want to, * or when a preset changes. - * + * * URLs are of the form: files/imagecache//path - * + * * @todo: improve image resizing, reduce distortion. * @todo: add watermarking capabilities. * @todo: split action/handlers into their own little .inc files. * @todo: enforce permissions. - * + * * Notes: * To add a new handler, * add fields and select option to _imagecache_actions_form; * add handling code to imagecache_cache - * + * */ @@ -53,19 +53,19 @@ function imagecache_menu($may_cache) { // standard imagecache callback. $items[] = array( - 'path' => file_directory_path() .'/imagecache', + 'path' => file_directory_path() .'/imagecache', 'callback' => 'imagecache_cache', 'access' => TRUE, 'type' => MENU_CALLBACK ); - // private downloads imagecache callback - $items[] = array( + // private downloads imagecache callback + $items[] = array( 'path' => 'system/files/imagecache', 'callback' => 'imagecache_cache_private', 'access' => TRUE, 'type' => MENU_CALLBACK - ); + ); } return $items; } @@ -97,10 +97,10 @@ function imagecache_requirements($phase) 'title' => $t('GD !format Support', array('!format' => drupal_ucfirst($format))), 'value' => $t('Not installed'), 'severity' => REQUIREMENT_INFO, - 'description' => $t('PHP was not compiled with %format support. Imagecache will not be able to process %format images.', array('%format' => $format)), + 'description' => $t('PHP was not compiled with %format support. Imagecache will not be able to process %format images.', array('%format' => $format)), ); } - } + } } } return $requirements; @@ -110,13 +110,13 @@ function imagecache_requirements($phase) * Implementation of hook_imagecache_actions. * * @return array - * An array of information on the actions implemented by a module. The array contains a - * sub-array for each action node type, with the machine-readable action name as the key. + * An array of information on the actions implemented by a module. The array contains a + * sub-array for each action node type, with the machine-readable action name as the key. * Each sub-array has up to 3 attributes. Possible attributes: - * + * * "name": the human-readable name of the action. Required. * "description": a brief description of the action. Required. - * "file": the name of the include file the action can be found + * "file": the name of the include file the action can be found * in relative to the implementing module's path. */ function imagecache_imagecache_actions() { @@ -202,14 +202,14 @@ function imagecache_action_definition($a if (!isset($definition_cache[$action])) { $definitions = imagecache_action_definitions(); $definition = (isset($definitions[$action])) ? $definitions[$action] : array(); - + if ($definition && $definition['file']) { require_once($definition['file']); } $definition_cache[$action] = $definition; } return $definition_cache[$action]; -} +} /** * Return a URL that points to the location of a derivative of the @@ -243,7 +243,7 @@ function _imagecache_strip_file_director } -/** +/** * callback for handling public files imagecache requests. */ function imagecache_cache() { @@ -263,7 +263,7 @@ function imagecache_cache_private() { if (user_access('view imagecache '. $preset)) { _imagecache_cache($preset, $source); - } + } else { // if there is a 403 image, display it. $accesspath = file_create_path('imagecache/'. $preset .'.403.png'); @@ -277,21 +277,21 @@ function imagecache_cache_private() { } /** - * handle request validation and responses to imagecache requests. + * handle request validation and responses to imagecache requests. */ function _imagecache_cache($presetname, $path) { if (!$preset = imagecache_preset_by_name($presetname)) { - // send a 404 if we dont' know of a preset. + // send a 404 if we dont' know of a preset. header("HTTP/1.0 404 Not Found"); exit; } // umm yeah deliver it early if it is there. especially useful - // to prevent lock files from being created when delivering private files. + // to prevent lock files from being created when delivering private files. $dst = imagecache_create_path($preset['presetname'], $path); if (file_exists($dst)) { imagecache_transfer($dst); - } + } $src = file_create_path($path); if (!is_file($src)) { @@ -311,7 +311,7 @@ function _imagecache_cache($presetname, } } } - + // if there is a 404 image uploaded for the preset display it. $notfoundpath = file_create_path('imagecache/'. $preset['presetname'] .'.404.png'); if (file_exists($notfoundpath)) { @@ -326,7 +326,7 @@ function _imagecache_cache($presetname, $lockfile = file_directory_temp() .'/'. $preset['presetname'] . basename($src) ; if (file_exists($lockfile)) { watchdog('imagecache', t('Imagecache already generating: %dst, Lock file: %tmp.', array('%dst' => $dst, '%tmp' => $lockfile)), WATCHDOG_NOTICE); - // send a response code that will make the browser wait and reload in a 1/2 sec. + // send a response code that will make the browser wait and reload in a 1/2 sec. // header() exit; } @@ -335,19 +335,19 @@ function _imagecache_cache($presetname, register_shutdown_function('file_delete', $lockfile); // check if deriv exists... (file was created between apaches request handler and reaching this code) - // otherwise try to create the derivative. + // otherwise try to create the derivative. if (!file_exists($dst) && !imagecache_build_derivative($preset['actions'], $src, $dst)) { // Generate an error if image could not generate. watchdog('imagecache', t('Failed generating an image from %image using imagecache preset %preset.', array('%image' => $path, '%preset' => $preset)), WATCHDOG_ERROR); header("HTTP/1.0 500 Internal Server Error"); exit; - } + } imagecache_transfer($dst); } function _imagecache_apply_action($action, &$image) { $actions = imagecache_action_definitions(); - + if ($definition = imagecache_action_definition($action['action'])) { return call_user_func($action['action'] .'_image', $image, $action['data']); } @@ -430,7 +430,7 @@ function _imagecache_mkdir($dir) { if (is_file($path)) { watchdog('imagecache', t('file exists where we would like a directory: %path', array('%path' => $path)), WATCHDOG_ERROR); return FALSE; - } + } if (!@mkdir($path)) { watchdog('imagecache', t('Could not create destination: %dir halted at: %path', array('%dir' => $dir, '%path' => $path)), WATCHDOG_ERROR); return FALSE; @@ -438,14 +438,14 @@ function _imagecache_mkdir($dir) { if (!@chmod($path, 0775)) { watchdog('imagecache', t('Could not set permissons on created directory: %dir halted at: %path', array('%dir' => $dir, '%path' => $path)), WATCHDOG_ERROR); return FALSE; - } + } } return TRUE; } - + /** * build an image cache derivative - * + * * @param $actions Array of imagecache actions. * @param $src Path of the source file. * @param $dst Path of the destination file. @@ -463,7 +463,7 @@ function imagecache_build_derivative($ac } if (!$image = imageapi_image_open($src)) { - return FALSE; + return FALSE; } @@ -495,16 +495,16 @@ function imagecache_build_derivative($ac return TRUE; } - + function imagecache_imagefield_file($op, $file) { switch($op) { // Delete imagecache presets when imagecache images are deleted. case 'delete': imagecache_image_flush($file['filepath']); break; - // Create imagecache derivatives when files are saved. - case 'save': - break; + // Create imagecache derivatives when files are saved. + case 'save': + break; } } @@ -535,7 +535,7 @@ function imagecache_field_formatter_info */ function imagecache_field_formatter($field, $item, $formatter) { if (empty($item['fid']) && $field['use_default_image']) { - $item = $field['default_image']; + $item = $field['default_image']; } // Views does not load the file for us, while CCK display fields does. if (!isset($item['filepath'])) { @@ -704,10 +704,10 @@ function theme_imagecache_resize($elemen /** * ImageCache 2.x API * - * The API for imagecache has changed. There is a compatibility layer for + * The API for imagecache has changed. There is a compatibility layer for * imagecache 1.x. Please see the imagecache_compat.module - * - * The 2.x API returns more structured data, has shorter function names, and + * + * The 2.x API returns more structured data, has shorter function names, and * implements more aggressive metadata caching. * */ @@ -717,7 +717,7 @@ function theme_imagecache_resize($elemen * * @param reset * if set to true it will clear the preset cache - * + * * @return * array of presets array( $preset_id => array('presetid' => integer, 'presetname' => string)) */ @@ -759,7 +759,7 @@ function imagecache_presets($reset = FAL * * @param preset_id * The numeric id of a preset. - * + * * @return * preset array( 'presetname' => string, 'presetid' => integet) * empty array if preset_id is an invalid preset @@ -778,7 +778,7 @@ function imagecache_preset($preset_id, $ * preset array( 'presetname' => string, 'presetid' => integer) * empty array if preset_name is an invalid preset */ - + function imagecache_preset_by_name($preset_name) { static $presets_by_name = array(); if (!$presets_by_name && $presets = imagecache_presets()) { @@ -786,7 +786,7 @@ function imagecache_preset_by_name($pres $presets_by_name[$preset['presetname']] = $preset; } } - return (isset($presets_by_name[$preset_name])) ? $presets_by_name[$preset_name] : array(); + return (isset($presets_by_name[$preset_name])) ? $presets_by_name[$preset_name] : array(); } /** @@ -829,7 +829,7 @@ function imagecache_preset_actions($pres while ($row = db_fetch_array($result)) { $row['data'] = unserialize($row['data']); $actions_cache[$preset['presetid']][] = $row; - } + } } return isset($actions_cache[$preset['presetid']]) ? $actions_cache[$preset['presetid']] : array(); @@ -875,7 +875,7 @@ function imagecache_action($actionid) { $action = array_merge($definition, $action); $actions[$actionid] = $action; } - } + } return $actions[$actionid]; } @@ -890,7 +890,7 @@ function imagecache_action_save($action) $preset = imagecache_preset($action['presetid']); imagecache_preset_flush($preset); imagecache_presets(TRUE); - return $action; + return $action; } function imagecache_action_delete($action) { @@ -901,3 +901,73 @@ function imagecache_action_delete($actio } + + +/** + * Add imagecache pipelining to the the image.module size derivatives form + */ +function imagecache_form_alter($form_id, &$form) { + if ($form_id == 'image_admin_settings') { + // Sneak in our own little setting alongside the usual image dimensions + // UI layout is not perfect, but image.module hard-coded their table formatting. + // I want to over-ride theme_image_settings_sizes_form() + // + // image.module also slightly changed this structure and its API at one point + // this code against 1.209.2.51 2008/01/06 + // test against other image.module releases + $sizes = function_exists('image_get_sizes') ? image_get_sizes() : _image_get_sizes(); + $size_form = $form['image_sizes']; + + $presets = imagecache_presets(); + $imagecache_options = array(0 => "(no imagecache process)"); + foreach ($presets as $preset) { + $imagecache_options[$preset['presetid']] = $preset['presetname']; + } + foreach (element_children($size_form) as $key) { + // Hijack the layout of the 'link' column + $options = array(); + $options['link'] = $form['image_sizes'][$key]['link']; + $options['imagecache'] = array( + '#type' => 'select', + '#default_value' => $sizes[$key]['imagecache'], + '#options' => $imagecache_options, + ); + // Manipulate parents to avoid 'tree' problem. + // This is all to work around the new image module theme_image_settings_sizes_form() + $options['link']['#parents'] = array('image_sizes', $key, 'link'); + $options['imagecache']['#parents'] = array('image_sizes', $key, 'imagecache'); + $form['image_sizes'][$key]['link'] = $options; + // With the right name, the imagecache setting made here will be stored as usual within the variables in a systems_setting_form. + } + $form['image_sizes']['#description'] .= t('

+ Optionally, choose an imagecache preset + to use to generate this derivative image. + The dimensions shown here are used after the imagecache process, + so for best results, make the imagecache result the same size as that defined here. +

', array('!imagecache_settings' => url('admin/build/imagecache')) + ); + + // Capture the form submission so we can save this setting + $form['#submit']['imagecache_save_image_size_settings'] = array(); + } +} + +/** + * Implementation of hook_image_alter() + * + * Capture the image_build_derivatives phase of image.module + * and insert our own manipulations to it any time an image is manipulated. + * + * This runs the imagecache builder over the input file and places it in the + * output destination. + */ +function imagecache_image_alter($node, $destination, $sizename) { + $sizes = image_get_sizes(); + $size_def = $sizes[$sizename]; + // Appended to the dimensions is our 'imagecache' id value. Maybe. + if ($presetid = $size_def['imagecache']) { + $original = file_create_path($node->images['_original']); + $preset = imagecache_preset($presetid); + $result = imagecache_build_derivative($preset['actions'], $original, $destination ); + } +}