imagecache_customactions.module 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. /**
  3. * @file Allows advanced users to code their own PHP image manipulation routines
  4. * as part of image style processing.
  5. *
  6. * @author Originally contributed by crea https://drupal.org/node/325103#comment-
  7. * 1076011
  8. *
  9. * @author merged into imagecache_actions by dman http://coders.co.nz
  10. *
  11. * custom action effect:
  12. * @todo: add description field that editors can use to define their own summary?
  13. * @todo: add form field asking if dimensions stay the same (or if the new dimensions are known).
  14. * subroutine effect:
  15. * @todo: use isid to allow for image style renaming, but also use name to allow export and import (features)
  16. */
  17. /**
  18. * Implements hook_image_effect_info().
  19. *
  20. * Defines information about the supported effects.
  21. */
  22. function imagecache_customactions_image_effect_info() {
  23. $effects = array();
  24. $effects['imagecache_customactions'] = array(
  25. 'label' => t('Custom action'),
  26. 'help' => t('Runs custom PHP code.'),
  27. 'effect callback' => 'imagecache_customactions_effect',
  28. 'dimensions callback' => 'imagecache_customactions_dimensions',
  29. 'form callback' => 'imagecache_customactions_form',
  30. 'summary theme' => 'imagecache_customactions_summary',
  31. );
  32. $effects['imagecache_subroutine'] = array(
  33. 'label' => t('Subroutine'),
  34. 'help' => t('Runs another defined preset on the image.'),
  35. 'effect callback' => 'imagecache_subroutine_effect',
  36. 'dimensions callback' => 'imagecache_subroutine_dimensions',
  37. 'form callback' => 'imagecache_subroutine_form',
  38. 'summary theme' => 'imagecache_subroutine_summary',
  39. );
  40. return $effects;
  41. }
  42. /**
  43. * Implements hook_theme().
  44. *
  45. * Registers theme functions for the effect summaries.
  46. */
  47. function imagecache_customactions_theme() {
  48. return array(
  49. 'imagecache_customactions_summary' => array(
  50. 'variables' => array('data' => NULL),
  51. ),
  52. 'imagecache_subroutine_summary' => array(
  53. 'variables' => array('data' => NULL),
  54. ),
  55. );
  56. }
  57. /**
  58. * Implements hook_image_style_flush().
  59. *
  60. * This hook checks if the image style that is being flushed is used in a
  61. * subroutine effect. If so, the style that contains the subroutine effect
  62. * should be flushed as well.
  63. *
  64. * This may lead to recursive calls to image_style_flush() and thus to this
  65. * hook. Without loops in styles that call each other as subroutine, this
  66. * recursion will always end.
  67. *
  68. * @param array $flushed_style
  69. * The image style that is being flushed.
  70. */
  71. function imagecache_customactions_image_style_flush(/*array*/ $flushed_style) {
  72. $styles = image_styles();
  73. foreach ($styles as $style) {
  74. if ($style['name'] !== $flushed_style['name']) {
  75. foreach ($style['effects'] as $effect) {
  76. if ($effect['name'] === 'imagecache_subroutine') {
  77. if (isset($effect['data']['subroutine_presetname']) && $effect['data']['subroutine_presetname'] === $flushed_style['name']) {
  78. image_style_flush($style);
  79. }
  80. }
  81. }
  82. }
  83. }
  84. }
  85. /**
  86. * Image effect form callback for the custom action effect.
  87. *
  88. * Note that this is not a complete form, it only contains the portion of the
  89. * form for configuring the effect options. Therefore it does not not need to
  90. * include metadata about the effect, nor a submit button.
  91. *
  92. * @param array $data
  93. * The current configuration for this image effect.
  94. *
  95. * @return array
  96. * The form definition for this effect.
  97. */
  98. function imagecache_customactions_form(array $data) {
  99. // Add defaults.
  100. $data += array('php' => 'return TRUE;');
  101. // Note: we also need to check for the existence of the module: admin has
  102. // all rights, so user_acccess(...) returns TRUE even if the module is not
  103. // enabled and the permission does not exist.
  104. $allow_php = module_exists('php') && user_access('use PHP for settings');
  105. $form = array(
  106. 'php' => array(
  107. '#type' => 'textarea',
  108. '#rows' => 12,
  109. '#title' => t('PHP code'),
  110. '#default_value' => $data['php'],
  111. '#disabled' => !$allow_php,
  112. '#description' => t("<p>A piece of PHP code that modifies the image.
  113. It should return a boolean indicating success or failure.
  114. You will need the '%use_php' permission, defined by the 'PHP filter' module.
  115. See the help for an extensive explanation of the possibilities.</p>",
  116. array('%use_php' => t('Use PHP for settings'))),
  117. '#wysiwyg' => FALSE,
  118. ),
  119. );
  120. return $form;
  121. }
  122. /**
  123. * Implements theme_hook() for the custom action effect summary.
  124. *
  125. * param array $variables
  126. * An associative array containing:
  127. * - data: The current configuration for this image effect.
  128. *
  129. * @return string
  130. * The HTML for the summary of this image effect.
  131. * @ingroup themeable
  132. */
  133. function theme_imagecache_customactions_summary(/*array $variables*/) {
  134. return 'Custom PHP code';
  135. }
  136. /**
  137. * Image effect callback for the custom action effect.
  138. *
  139. * @param stdClass $image
  140. * @param array $data
  141. *
  142. * @return boolean
  143. * true on success, false otherwise.
  144. */
  145. function imagecache_customactions_effect(stdClass $image, array $data) {
  146. // Check that the PHP filter module is enabled.
  147. $result = module_exists('php');
  148. if ($result) {
  149. // Get context about the image.
  150. module_load_include('inc', 'imagecache_actions', 'utility');
  151. $GLOBALS['image_context'] = imagecache_actions_get_image_context($image, $data);
  152. $GLOBALS['image'] = $image;
  153. $result = php_eval('<' . '?php global $image, $image_context; ' . $data['php'] . ' ?' . '>');
  154. // php_eval returns '1' if the snippet returns true.
  155. $result = $result === '1';
  156. unset($GLOBALS['image']);
  157. unset($GLOBALS['image_context']);
  158. }
  159. if ($result && $image->toolkit == 'GD') {
  160. $image->info['width'] = imagesx($image->resource);
  161. $image->info['height'] = imagesy($image->resource);
  162. }
  163. return $result;
  164. }
  165. /**
  166. * Image dimensions callback for the custom action effect.
  167. *
  168. * @param array $dimensions
  169. * Dimensions to be modified - an associative array containing the items
  170. * 'width' and 'height' (in pixels).
  171. * param array $data
  172. * An associative array containing the effect data.
  173. */
  174. function imagecache_customactions_dimensions(array &$dimensions/*, array $data*/) {
  175. $dimensions['width'] = NULL;
  176. $dimensions['height'] = NULL;
  177. }
  178. /**
  179. * Subroutine - an imagecache action that just calls another one.
  180. *
  181. * Contributed by Alan D
  182. * https://drupal.org/node/618784
  183. *
  184. * Reworked into customactions by dman 2010-07
  185. */
  186. /**
  187. * Image effect form callback for the subroutine effect.
  188. *
  189. * @param array $data
  190. * The current configuration for this image effect.
  191. *
  192. * @return array
  193. * The form definition for this effect.
  194. */
  195. function imagecache_subroutine_form(array $data) {
  196. // Add defaults.
  197. $data += array('subroutine_presetname' => '');
  198. // List available image styles.
  199. // The PASS_THROUGH parameter is new as of D7.23, and is added here to prevent
  200. // image_style_options() from double-encoding the human-readable image style
  201. // name, since the form API will already sanitize options in a select list.
  202. $styles = image_style_options(TRUE, PASS_THROUGH);
  203. //@todo: unset the current style to prevent obvious recursion.
  204. $form = array();
  205. $form['subroutine_presetname'] = array(
  206. '#type' => 'select',
  207. '#title' => t('Image style to call'),
  208. '#default_value' => $data['subroutine_presetname'],
  209. '#options' => $styles,
  210. '#required' => TRUE,
  211. );
  212. return $form;
  213. }
  214. /**
  215. * Implements theme_hook() for the subroutine effect summary.
  216. *
  217. * @param array $variables
  218. * An associative array containing:
  219. * - data: The current configuration for this image effect.
  220. *
  221. * @return string
  222. * The HTML for the summary of this image effect.
  223. * @ingroup themeable
  224. */
  225. function theme_imagecache_subroutine_summary(array $variables) {
  226. $data = $variables['data'];
  227. module_load_include('inc', 'imagecache_actions', 'utility');
  228. $label = imagecache_actions_get_style_label($data['subroutine_presetname']);
  229. return t('Apply image style %label', array('%label' => $label));
  230. }
  231. /**
  232. * Image effect callback for the subroutine effect.
  233. *
  234. * @param stdClass $image
  235. * @param array $data
  236. *
  237. * @return boolean
  238. * true on success, false otherwise.
  239. */
  240. function imagecache_subroutine_effect(stdClass $image, array $data) {
  241. $result = FALSE;
  242. if ($style = image_style_load($data['subroutine_presetname'])) {
  243. $result = TRUE;
  244. foreach ($style['effects'] as $effect) {
  245. $result = $result && image_effect_apply($image, $effect);
  246. }
  247. }
  248. return $result;
  249. }
  250. /**
  251. * Image dimensions callback for the subroutine effect.
  252. *
  253. * @param array $dimensions
  254. * Dimensions to be modified - an array with components width and height, in
  255. * pixels.
  256. * @param array $data
  257. * An array with the effect options.
  258. */
  259. function imagecache_subroutine_dimensions(array &$dimensions, array $data) {
  260. // Let the subroutine transform the dimensions.
  261. image_style_transform_dimensions($data['subroutine_presetname'], $dimensions);
  262. }