imagecache_customactions.module 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <?php
  2. /**
  3. * @file Allow advanced users to code their own PHP image manipulation routines
  4. * as part of imagecache processing.
  5. *
  6. * @author Originally contributed by crea http://drupal.org/node/325103#comment-
  7. * 1076011
  8. *
  9. * @author merged into imagecache_actions by dman http://coders.co.nz
  10. *
  11. * Needs review - currently a security risk etc
  12. */
  13. /**
  14. *
  15. * Notes about imagecache action extensions. For each action:
  16. *
  17. * 1: Implement imagecache_HOOK_form($formdata) to define the config form.
  18. *
  19. * 1a: Implement theme_imagecache_HOOK_form if needed - optional
  20. *
  21. * 2: Implement imagecache_HOOK_image($image, $data) to DO the process
  22. *
  23. * 3: Impliment theme_imagecache_HOOK($element) to return a text description of
  24. * the setting
  25. *
  26. * 4: Declare the action in HOOK_imagecache_actions()
  27. *
  28. *
  29. * API ref for hook_image()
  30. *
  31. * @param $image array defining an image file, including :
  32. *
  33. * $image- >source as the filename,
  34. *
  35. * $image->info array
  36. *
  37. * $image->resource handle on the image object
  38. *
  39. * @param $action array of settings as defined in your form.
  40. */
  41. function imagecache_customactions_image_effect_info() {
  42. $effects = array();
  43. $effects['imagecache_customactions'] = array(
  44. 'label' => t('Custom action'),
  45. 'help' => t('Runs custom PHP code.'),
  46. 'effect callback' => 'imagecache_customactions_image',
  47. 'dimensions callback' => 'imagecache_customactions_dimensions',
  48. 'form callback' => 'imagecache_customactions_form',
  49. );
  50. $effects['imagecache_subroutine'] = array(
  51. 'label' => t('Subroutine'),
  52. 'help' => t('Runs another defined preset on the image.'),
  53. 'effect callback' => 'imagecache_subroutine_image',
  54. 'dimensions callback' => 'imagecache_subroutine_dimensions',
  55. 'form callback' => 'imagecache_subroutine_form',
  56. );
  57. return $effects;
  58. }
  59. /**
  60. * Implementation of theme_hook() for imagecache_customactions.module
  61. */
  62. function imagecache_customactions_theme() {
  63. return array(
  64. 'imagecache_subroutine' => array(
  65. 'render element' => 'element',
  66. ),
  67. );
  68. }
  69. /**
  70. * Implements hook_form().
  71. *
  72. * @param $action array of settings for this action
  73. * @return a form definition
  74. */
  75. function imagecache_customactions_form($data) {
  76. // Add defaults.
  77. $data += array('php' => 'return TRUE;');
  78. // Note: we also need to check for the existence of the module: admin has
  79. // all rights, so user_acccess(...) returns TRUE even if the module is not
  80. // enabled and the permission does not exist.
  81. $allow_dynamic = user_access('use PHP for settings') && module_exists('php');
  82. // @todo: for imagemagick, the PHP code should add a set of commands to the
  83. // ops aray of $image. Document this in description.
  84. $form = array(
  85. 'php' => array(
  86. '#type' => 'textarea',
  87. '#rows' => 10,
  88. '#title' => t('PHP code'),
  89. '#default_value' => $data['php'],
  90. '#disabled' => !$allow_dynamic,
  91. '#description' => t("<p>A piece of PHP code that modifies the image.
  92. It should return a boolean indicating success or failure.
  93. You will need the '%use_php' permission, defined by the 'PHP filter' module.
  94. See the help for an extensive explanation of the possibilities.</p>",
  95. array('%use_php' => t('Use PHP for settings'))),
  96. '#wysiwyg' => FALSE,
  97. ),
  98. );
  99. return $form;
  100. }
  101. /**
  102. * Implements hook_image().
  103. *
  104. * @param $image
  105. * @param $data
  106. */
  107. function imagecache_customactions_image($image, $data) {
  108. // Check that the PHP filter module is enabled.
  109. $result = module_exists('php');
  110. if ($result) {
  111. // Get context about the image.
  112. $GLOBALS['image_context'] = imagecache_actions_get_image_context($image, $data);
  113. $GLOBALS['image'] = $image;
  114. $result = php_eval('<'.'?php global $image, $image_context; ' . $data['php'] . ' ?'.'>');
  115. // php_eval returns '1' if the snippet returns true.
  116. $result = $result === '1';
  117. unset($GLOBALS['image']);
  118. unset($GLOBALS['image_context']);
  119. }
  120. if ($result && $image->toolkit == 'GD') {
  121. $image->info['width'] = imagesx($image->resource);
  122. $image->info['height'] = imagesy($image->resource);
  123. }
  124. return $result;
  125. }
  126. /**
  127. * Image dimensions callback; Custom action.
  128. *
  129. * @param array $dimensions
  130. * Dimensions to be modified - an array with components width and height, in
  131. * pixels.
  132. * @param array $data
  133. * An array with the effect options.
  134. */
  135. function imagecache_customactions_dimensions(array &$dimensions, array $data) {
  136. // @todo: add form field asking if dimensions stay the same (or if they know
  137. // the new dimesions).
  138. $dimensions['width'] = NULL;
  139. $dimensions['height'] = NULL;
  140. }
  141. /**
  142. * Implementation of theme_hook() for imagecache_ui.module
  143. */
  144. function theme_imagecache_customactions($element) {
  145. // TODO: Should this theme imagecache_customactions be declared in hook_theme()?
  146. $data = $element['#value'];
  147. return "<em><strong>" . $data['text'] . "</strong></em>";
  148. }
  149. /**
  150. * Subroutine - an imagecache action that just calls another one.
  151. *
  152. * Contributed by Alan D
  153. * http://drupal.org/node/618784
  154. *
  155. * Reworked into customactions by dman 2010-07
  156. */
  157. /**
  158. * Config form for this preset.
  159. *
  160. * Implementation of imagecache_hook_form()
  161. *
  162. * @param $action array of settings for this action
  163. * @return a form definition
  164. */
  165. function imagecache_subroutine_form($action) {
  166. $action = (array) $action;
  167. $form = array();
  168. // List available presets
  169. $presets = array();
  170. foreach (image_styles(TRUE) as $preset) {
  171. $presets[$preset['name']] = $preset['name'];
  172. }
  173. $form['subroutine_presetname'] = array(
  174. '#type' => 'select',
  175. '#title' => t('Preset to call'),
  176. '#default_value' => $action['subroutine_presetname'],
  177. '#options' => $presets,
  178. );
  179. return $form;
  180. }
  181. /**
  182. * Actually invoke the action - which means just handing off to the named real
  183. * preset to do the job.
  184. *
  185. * Implementation of hook_image()
  186. *
  187. * @param $image
  188. * @param $action
  189. */
  190. function imagecache_subroutine_image($image, $data) {
  191. if ($preset = image_style_load($data['subroutine_presetname'])) {
  192. foreach ($preset['effects'] as $effect) {
  193. image_effect_apply($image, $effect);
  194. }
  195. }
  196. return TRUE;
  197. }
  198. /**
  199. * Image dimensions callback; Subroutine.
  200. *
  201. * @param array $dimensions
  202. * Dimensions to be modified - an array with components width and height, in
  203. * pixels.
  204. * @param array $data
  205. * An array with the effect options.
  206. */
  207. function imagecache_subroutine_dimensions(array &$dimensions, array $data) {
  208. // @todo: dimensions
  209. // @todo: call dimensions callback on subroutine style.
  210. $dimensions['width'] = NULL;
  211. $dimensions['height'] = NULL;
  212. }
  213. /**
  214. * This lets the user see what parameters were selected for the action
  215. */
  216. function theme_imagecache_subroutine($variables) {
  217. $element = $variables['element'];
  218. $data = $element['#value'];
  219. if ($preset = imagecache_preset_by_name($data['subroutine_presetname'])) {
  220. return t('%name (pid: !presetid)', array('%name' => $preset['presetname'], '!presetid' => $preset['presetid']));
  221. }
  222. return t('<span class="error">Invalid reference. The referenced preset may have been deleted!</span>');
  223. }