Index: imagecache/imagecache.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/imagecache/imagecache.module,v retrieving revision 1.112.2.9 diff -u -p -r1.112.2.9 imagecache.module --- imagecache/imagecache.module 26 May 2010 21:08:58 -0000 1.112.2.9 +++ imagecache/imagecache.module 4 Jun 2010 07:45:50 -0000 @@ -960,6 +960,112 @@ function imagecache_presets($reset = FAL } /** + * Implementation of hook_image_operations. (image.module) + * + * Declare the operations we make available for use as derivative sizes. + * + * @return + * an array of operations, keyed by id, declaring the name and operations + * used to create derivatives. + * + * @see image_admin_settings() + * + * @ingroup image.module integration + */ +function imagecache_image_operations() { + $operations = array(); + foreach (imagecache_presets() as $preset_id => $preset) { + $operations['imagecache-'. $preset_id] = array( + 'name' => $preset['presetname'], + 'callback' => 'imagecache_image_build_derivative', + 'module' => 'imagecache', + 'extra' => l(t('Settings'), 'admin/build/imagecache/' . $preset_id), + ); + }; + return $operations; +} + + +/** + * Wrapper to imagecache_build_derivative. Used so we can invoke this as a + * callback by name from image.module:_image_build_derivatives() + * + * This function acts like the utilities image_scale() image_scale_and_crop() + * that image.module uses. + * + * It is invoked by name when an image preset notes the function as a callback. + * + * @param $original_path + * Source image + * @param $destination + * Save image as + * @param $derivative_info + * an array of data that image.module settings form may save. Normally this + * includes the derivative name, operation id, and width and height. + * $derivative_info['operation'] will be of the form 'imagecache-n' where n is a + * preset id that we will build + * @return bool + * success + * + * @see _image_build_derivatives() + * @see _image_build_derivative() + * + * @ingroup image.module integration + */ +function imagecache_image_build_derivative($original_path, $destination, $derivative_info = array()) { + $operation_id = $derivative_info['operation']; + if (preg_match('/^imagecache-(.*)$/', $operation_id, $matches)) { + $preset_id = $matches[1]; + if (! $preset = imagecache_preset($preset_id)) { + trigger_error("Failed to build derivative with the imagecache ID $preset_id", E_USER_WARNING); + watchdog('imagecache', 'Failed to build derivative with the imagecache ID %preset_id is not really an imagecache preset operation. It may have been deleted.', array('%operation_id' => $operation_id), WATCHDOG_ERROR); + return FALSE; + } + // Note the reversal of the args. imag.module :src,dst,action imagecache.module: action,src,dst + return imagecache_build_derivative($preset['actions'], $original_path, $destination); + } +} + + + +/** + * Additional action to fire when a change is made to presets. It's possible + * that image. module needs to regenerate its derivatives as a result of changes + * made here. + * + * When a preset is modified, check to see if that preset was already being used + * as an image.module derivative operation. If so, we must freshen ALL images by + * touching the derivative timestamp. + * + * @ingroup image.module integration + * @see imagecache_preset_flush() + */ +function imagecache_image_trigger_rebuild($preset) { + // imagecache_preset_flush(), which calls this, gets called multiple times when + // saving a preset (once for each action then again for the preset) so try not + // to repeat any work too much here. + static $rebuild_triggered; + if ($rebuild_triggered) return; + + $presetid = $preset['presetid']; + // Check the current image.module derivative definitions. + $sizes = image_get_sizes() ; + foreach ($sizes as $sizename => $size_def) { + if (@$size_def['operation'] == 'imagecache-' . $presetid) { + // Yes, this preset is being used by an image operation. + drupal_set_message(t("Due do a change in the '%preset' preset, all derived image.module '%sizename' images need updating. This should happen over time as needed.", array('%preset' => $preset['presetname'], '%sizename' => $sizename))); + // Trigger expiry on (all!) image.module derivatives. + // This is inefficient, but image.module doesn't let us trigger just one + // preset change. + variable_set('image_updated', time()); + // Once is enough. + $rebuild_triggered = TRUE; + return; + } + } +} + +/** * Load a preset by preset_id. * * @param preset_id @@ -1056,6 +1162,7 @@ function imagecache_preset_flush($preset _imagecache_recursive_delete($presetdir); } } + imagecache_image_trigger_rebuild($preset); } /**