5 * Administration pages for image settings.
9 * Menu callback; Listing of all current image styles.
11 function image_style_list() {
14 $styles = image_styles();
15 $page['image_style_list'] = array(
16 '#markup' => theme('image_style_list', array('styles' => $styles)),
18 'css' => array(drupal_get_path('module', 'image') . '/image.admin.css' => array()),
27 * Form builder; Edit an image style name and effects order.
30 * An associative array containing the current state of the form.
32 * An image style array.
34 * @see image_style_form_submit()
36 function image_style_form($form, &$form_state, $style) {
37 $title = t('Edit %name style', array('%name' => $style['label']));
38 drupal_set_title($title, PASS_THROUGH);
40 // Adjust this form for styles that must be overridden to edit.
41 $editable = (bool) ($style['storage'] & IMAGE_STORAGE_EDITABLE);
43 if (!$editable && empty($form_state['input'])) {
44 drupal_set_message(t('This image style is currently being provided by a module. Click the "Override defaults" button to change its settings.'), 'warning');
47 $form_state['image_style'] = $style;
48 $form['#tree'] = TRUE;
49 $form['#attached']['css'][drupal_get_path('module', 'image') . '/image.admin.css'] = array();
51 // Show the thumbnail preview.
52 $form['preview'] = array(
54 '#title' => t('Preview'),
55 '#markup' => theme('image_style_preview', array('style' => $style)),
58 // Show the Image Style label.
59 $form['label'] = array(
60 '#type' => 'textfield',
61 '#title' => t('Image style name'),
62 '#default_value' => $style['label'],
63 '#disabled' => !$editable,
67 // Allow the name of the style to be changed, unless this style is
68 // provided by a module's hook_default_image_styles().
69 $form['name'] = array(
70 '#type' => 'machine_name',
72 '#default_value' => $style['name'],
73 '#disabled' => !$editable,
74 '#description' => t('The name is used in URLs for generated images. Use only lowercase alphanumeric characters, underscores (_), and hyphens (-).'),
76 '#machine_name' => array(
77 'exists' => 'image_style_load',
78 'source' => array('label'),
79 'replace_pattern' => '[^0-9a-z_\-]',
80 'error' => t('Please only use lowercase alphanumeric characters, underscores (_), and hyphens (-) for style names.'),
84 // Build the list of existing image effects for this image style.
85 $form['effects'] = array(
86 '#theme' => 'image_style_effects',
88 foreach ($style['effects'] as $key => $effect) {
89 $form['effects'][$key]['#weight'] = isset($form_state['input']['effects']) ? $form_state['input']['effects'][$key]['weight'] : NULL;
90 $form['effects'][$key]['label'] = array(
91 '#markup' => $effect['label'],
93 $form['effects'][$key]['summary'] = array(
94 '#markup' => isset($effect['summary theme']) ? theme($effect['summary theme'], array('data' => $effect['data'])) : '',
96 $form['effects'][$key]['weight'] = array(
98 '#title' => t('Weight for @title', array('@title' => $effect['label'])),
99 '#title_display' => 'invisible',
100 '#default_value' => $effect['weight'],
101 '#access' => $editable,
104 // Only attempt to display these fields for editable styles as the 'ieid'
105 // key is not set for styles defined in code.
107 $form['effects'][$key]['configure'] = array(
109 '#title' => t('edit'),
110 '#href' => 'admin/config/media/image-styles/edit/' . $style['name'] . '/effects/' . $effect['ieid'],
111 '#access' => $editable && isset($effect['form callback']),
113 $form['effects'][$key]['remove'] = array(
115 '#title' => t('delete'),
116 '#href' => 'admin/config/media/image-styles/edit/' . $style['name'] . '/effects/' . $effect['ieid'] . '/delete',
117 '#access' => $editable,
122 // Build the new image effect addition form and add it to the effect list.
123 $new_effect_options = array();
124 foreach (image_effect_definitions() as $effect => $definition) {
125 $new_effect_options[$effect] = check_plain($definition['label']);
127 $form['effects']['new'] = array(
129 '#weight' => isset($form_state['input']['weight']) ? $form_state['input']['weight'] : NULL,
130 '#access' => $editable,
132 $form['effects']['new']['new'] = array(
134 '#title' => t('Effect'),
135 '#title_display' => 'invisible',
136 '#options' => $new_effect_options,
137 '#empty_option' => t('Select a new effect'),
139 $form['effects']['new']['weight'] = array(
141 '#title' => t('Weight for new effect'),
142 '#title_display' => 'invisible',
143 '#default_value' => count($form['effects']) - 1,
145 $form['effects']['new']['add'] = array(
147 '#value' => t('Add'),
148 '#validate' => array('image_style_form_add_validate'),
149 '#submit' => array('image_style_form_submit', 'image_style_form_add_submit'),
152 // Show the Override or Submit button for this style.
153 $form['actions'] = array('#type' => 'actions');
154 $form['actions']['override'] = array(
156 '#value' => t('Override defaults'),
157 '#validate' => array(),
158 '#submit' => array('image_style_form_override_submit'),
159 '#access' => !$editable,
161 $form['actions']['submit'] = array(
163 '#value' => t('Update style'),
164 '#access' => $editable,
171 * Validate handler for adding a new image effect to an image style.
173 function image_style_form_add_validate($form, &$form_state) {
174 if (!$form_state['values']['new']) {
175 form_error($form['effects']['new']['new'], t('Select an effect to add.'));
180 * Submit handler for adding a new image effect to an image style.
182 function image_style_form_add_submit($form, &$form_state) {
183 $style = $form_state['image_style'];
184 // Check if this field has any configuration options.
185 $effect = image_effect_definition_load($form_state['values']['new']);
187 // Load the configuration form for this option.
188 if (isset($effect['form callback'])) {
189 $path = 'admin/config/media/image-styles/edit/' . $form_state['image_style']['name'] . '/add/' . $form_state['values']['new'];
190 $form_state['redirect'] = array($path, array('query' => array('weight' => $form_state['values']['weight'])));
192 // If there's no form, immediately add the image effect.
194 $effect['isid'] = $style['isid'];
195 $effect['weight'] = $form_state['values']['weight'];
196 image_effect_save($effect);
197 drupal_set_message(t('The image effect was successfully applied.'));
202 * Submit handler for overriding a module-defined style.
204 function image_style_form_override_submit($form, &$form_state) {
205 drupal_set_message(t('The %style style has been overridden, allowing you to change its settings.', array('%style' => $form_state['image_style']['label'])));
206 image_default_style_save($form_state['image_style']);
210 * Submit handler for saving an image style.
212 function image_style_form_submit($form, &$form_state) {
213 // Update the image style.
214 $style = $form_state['image_style'];
215 $style['name'] = $form_state['values']['name'];
216 $style['label'] = $form_state['values']['label'];
218 // Update image effect weights.
219 if (!empty($form_state['values']['effects'])) {
220 foreach ($form_state['values']['effects'] as $ieid => $effect_data) {
221 if (isset($style['effects'][$ieid])) {
222 $effect = $style['effects'][$ieid];
223 $effect['weight'] = $effect_data['weight'];
224 image_effect_save($effect);
229 image_style_save($style);
230 if ($form_state['values']['op'] == t('Update style')) {
231 drupal_set_message(t('Changes to the style have been saved.'));
233 $form_state['redirect'] = 'admin/config/media/image-styles/edit/' . $style['name'];
237 * Form builder; Form for adding a new image style.
240 * @see image_style_add_form_submit()
242 function image_style_add_form($form, &$form_state) {
243 $form['label'] = array(
244 '#type' => 'textfield',
245 '#title' => t('Style name'),
246 '#default_value' => '',
249 $form['name'] = array(
250 '#type' => 'machine_name',
251 '#description' => t('The name is used in URLs for generated images. Use only lowercase alphanumeric characters, underscores (_), and hyphens (-).'),
254 '#machine_name' => array(
255 'exists' => 'image_style_load',
256 'source' => array('label'),
257 'replace_pattern' => '[^0-9a-z_\-]',
258 'error' => t('Please only use lowercase alphanumeric characters, underscores (_), and hyphens (-) for style names.'),
262 $form['submit'] = array(
264 '#value' => t('Create new style'),
271 * Submit handler for adding a new image style.
273 function image_style_add_form_submit($form, &$form_state) {
275 'name' => $form_state['values']['name'],
276 'label' => $form_state['values']['label'],
278 $style = image_style_save($style);
279 drupal_set_message(t('Style %name was created.', array('%name' => $style['label'])));
280 $form_state['redirect'] = 'admin/config/media/image-styles/edit/' . $style['name'];
284 * Element validate function to ensure unique, URL safe style names.
286 * This function is no longer used in Drupal core since image style names are
287 * now validated using #machine_name functionality. It is kept for backwards
288 * compatibility (since non-core modules may be using it) and will be removed
291 function image_style_name_validate($element, $form_state) {
292 // Check for duplicates.
293 $styles = image_styles();
294 if (isset($styles[$element['#value']]) && (!isset($form_state['image_style']['isid']) || $styles[$element['#value']]['isid'] != $form_state['image_style']['isid'])) {
295 form_set_error($element['#name'], t('The image style name %name is already in use.', array('%name' => $element['#value'])));
298 // Check for illegal characters in image style names.
299 if (preg_match('/[^0-9a-z_\-]/', $element['#value'])) {
300 form_set_error($element['#name'], t('Please only use lowercase alphanumeric characters, underscores (_), and hyphens (-) for style names.'));
305 * Form builder; Form for deleting an image style.
308 * An image style array.
311 * @see image_style_delete_form_submit()
313 function image_style_delete_form($form, &$form_state, $style) {
314 $form_state['image_style'] = $style;
316 $replacement_styles = array_diff_key(image_style_options(TRUE, PASS_THROUGH), array($style['name'] => ''));
317 $form['replacement'] = array(
318 '#title' => t('Replacement style'),
320 '#options' => $replacement_styles,
321 '#empty_option' => t('No replacement, just delete'),
326 t('Optionally select a style before deleting %style', array('%style' => $style['label'])),
327 'admin/config/media/image-styles',
328 t('If this style is in use on the site, you may select another style to replace it. All images that have been generated for this style will be permanently deleted.'),
329 t('Delete'), t('Cancel')
334 * Submit handler to delete an image style.
336 function image_style_delete_form_submit($form, &$form_state) {
337 $style = $form_state['image_style'];
339 image_style_delete($style, $form_state['values']['replacement']);
340 drupal_set_message(t('Style %name was deleted.', array('%name' => $style['label'])));
341 $form_state['redirect'] = 'admin/config/media/image-styles';
345 * Confirmation form to revert a database style to its default.
347 function image_style_revert_form($form, &$form_state, $style) {
348 $form_state['image_style'] = $style;
352 t('Revert the %style style?', array('%style' => $style['label'])),
353 'admin/config/media/image-styles',
354 t('Reverting this style will delete the customized settings and restore the defaults provided by the @module module.', array('@module' => $style['module'])),
355 t('Revert'), t('Cancel')
360 * Submit handler to convert an overridden style to its default.
362 function image_style_revert_form_submit($form, &$form_state) {
363 drupal_set_message(t('The %style style has been reverted to its defaults.', array('%style' => $form_state['image_style']['label'])));
364 image_default_style_revert($form_state['image_style']);
365 $form_state['redirect'] = 'admin/config/media/image-styles';
369 * Form builder; Form for adding and editing image effects.
371 * This form is used universally for editing all image effects. Each effect adds
372 * its own custom section to the form by calling the form function specified in
373 * hook_image_effects().
376 * An associative array containing the current state of the form.
378 * An image style array.
380 * An image effect array.
383 * @see hook_image_effects()
384 * @see image_effects()
385 * @see image_resize_form()
386 * @see image_scale_form()
387 * @see image_rotate_form()
388 * @see image_crop_form()
389 * @see image_effect_form_submit()
391 function image_effect_form($form, &$form_state, $style, $effect) {
392 if (!empty($effect['data'])) {
393 $title = t('Edit %label effect', array('%label' => $effect['label']));
396 $title = t('Add %label effect', array('%label' => $effect['label']));
398 drupal_set_title($title, PASS_THROUGH);
400 $form_state['image_style'] = $style;
401 $form_state['image_effect'] = $effect;
403 // If no configuration for this image effect, return to the image style page.
404 if (!isset($effect['form callback'])) {
405 drupal_goto('admin/config/media/image-styles/edit/' . $style['name']);
408 $form['#tree'] = TRUE;
409 $form['#attached']['css'][drupal_get_path('module', 'image') . '/image.admin.css'] = array();
410 if (function_exists($effect['form callback'])) {
411 $form['data'] = call_user_func($effect['form callback'], $effect['data']);
414 // Check the URL for a weight, then the image effect, otherwise use default.
415 $form['weight'] = array(
417 '#value' => isset($_GET['weight']) ? intval($_GET['weight']) : (isset($effect['weight']) ? $effect['weight'] : count($style['effects'])),
420 $form['actions'] = array('#tree' => FALSE, '#type' => 'actions');
421 $form['actions']['submit'] = array(
423 '#value' => isset($effect['ieid']) ? t('Update effect') : t('Add effect'),
425 $form['actions']['cancel'] = array(
427 '#title' => t('Cancel'),
428 '#href' => 'admin/config/media/image-styles/edit/' . $style['name'],
435 * Submit handler for updating an image effect.
437 function image_effect_form_submit($form, &$form_state) {
438 $style = $form_state['image_style'];
439 $effect = array_merge($form_state['image_effect'], $form_state['values']);
440 $effect['isid'] = $style['isid'];
441 image_effect_save($effect);
442 drupal_set_message(t('The image effect was successfully applied.'));
443 $form_state['redirect'] = 'admin/config/media/image-styles/edit/' . $style['name'];
447 * Form builder; Form for deleting an image effect.
450 * Name of the image style from which the image effect will be removed.
452 * Name of the image effect to remove.
454 * @see image_effect_delete_form_submit()
456 function image_effect_delete_form($form, &$form_state, $style, $effect) {
457 $form_state['image_style'] = $style;
458 $form_state['image_effect'] = $effect;
460 $question = t('Are you sure you want to delete the @effect effect from the %style style?', array('%style' => $style['label'], '@effect' => $effect['label']));
461 return confirm_form($form, $question, 'admin/config/media/image-styles/edit/' . $style['name'], '', t('Delete'));
465 * Submit handler to delete an image effect.
467 function image_effect_delete_form_submit($form, &$form_state) {
468 $style = $form_state['image_style'];
469 $effect = $form_state['image_effect'];
471 image_effect_delete($effect);
472 drupal_set_message(t('The image effect %name has been deleted.', array('%name' => $effect['label'])));
473 $form_state['redirect'] = 'admin/config/media/image-styles/edit/' . $style['name'];
477 * Element validate handler to ensure an integer pixel value.
479 * The property #allow_negative = TRUE may be set to allow negative integers.
481 function image_effect_integer_validate($element, &$form_state) {
482 $value = empty($element['#allow_negative']) ? $element['#value'] : preg_replace('/^-/', '', $element['#value']);
483 if ($element['#value'] != '' && (!is_numeric($value) || intval($value) <= 0)) {
484 if (empty($element['#allow_negative'])) {
485 form_error($element, t('!name must be an integer.', array('!name' => $element['#title'])));
488 form_error($element, t('!name must be a positive integer.', array('!name' => $element['#title'])));
494 * Element validate handler to ensure a hexadecimal color value.
496 function image_effect_color_validate($element, &$form_state) {
497 if ($element['#value'] != '') {
498 $hex_value = preg_replace('/^#/', '', $element['#value']);
499 if (!preg_match('/^#[0-9A-F]{3}([0-9A-F]{3})?$/', $element['#value'])) {
500 form_error($element, t('!name must be a hexadecimal color value.', array('!name' => $element['#title'])));
506 * Element validate handler to ensure that either a height or a width is
509 function image_effect_scale_validate($element, &$form_state) {
510 if (empty($element['width']['#value']) && empty($element['height']['#value'])) {
511 form_error($element, t('Width and height can not both be blank.'));
516 * Form structure for the image resize form.
518 * Note that this is not a complete form, it only contains the portion of the
519 * form for configuring the resize options. Therefore it does not not need to
520 * include metadata about the effect, nor a submit button.
523 * The current configuration for this resize effect.
525 function image_resize_form($data) {
526 $form['width'] = array(
527 '#type' => 'textfield',
528 '#title' => t('Width'),
529 '#default_value' => isset($data['width']) ? $data['width'] : '',
530 '#field_suffix' => ' ' . t('pixels'),
533 '#element_validate' => array('image_effect_integer_validate'),
534 '#allow_negative' => FALSE,
536 $form['height'] = array(
537 '#type' => 'textfield',
538 '#title' => t('Height'),
539 '#default_value' => isset($data['height']) ? $data['height'] : '',
540 '#field_suffix' => ' ' . t('pixels'),
543 '#element_validate' => array('image_effect_integer_validate'),
544 '#allow_negative' => FALSE,
550 * Form structure for the image scale form.
552 * Note that this is not a complete form, it only contains the portion of the
553 * form for configuring the scale options. Therefore it does not not need to
554 * include metadata about the effect, nor a submit button.
557 * The current configuration for this scale effect.
559 function image_scale_form($data) {
560 $form = image_resize_form($data);
561 $form['#element_validate'] = array('image_effect_scale_validate');
562 $form['width']['#required'] = FALSE;
563 $form['height']['#required'] = FALSE;
564 $form['upscale'] = array(
565 '#type' => 'checkbox',
566 '#default_value' => (isset($data['upscale'])) ? $data['upscale'] : 0,
567 '#title' => t('Allow Upscaling'),
568 '#description' => t('Let scale make images larger than their original size'),
574 * Form structure for the image crop form.
576 * Note that this is not a complete form, it only contains the portion of the
577 * form for configuring the crop options. Therefore it does not not need to
578 * include metadata about the effect, nor a submit button.
581 * The current configuration for this crop effect.
583 function image_crop_form($data) {
587 'anchor' => 'center-center',
590 $form = image_resize_form($data);
591 $form['anchor'] = array(
593 '#title' => t('Anchor'),
595 'left-top' => t('Top left'),
596 'center-top' => t('Top center'),
597 'right-top' => t('Top right'),
598 'left-center' => t('Center left'),
599 'center-center' => t('Center'),
600 'right-center' => t('Center right'),
601 'left-bottom' => t('Bottom left'),
602 'center-bottom' => t('Bottom center'),
603 'right-bottom' => t('Bottom right'),
605 '#theme' => 'image_anchor',
606 '#default_value' => $data['anchor'],
607 '#description' => t('The part of the image that will be retained during the crop.'),
614 * Form structure for the image rotate form.
616 * Note that this is not a complete form, it only contains the portion of the
617 * form for configuring the rotate options. Therefore it does not not need to
618 * include metadata about the effect, nor a submit button.
621 * The current configuration for this rotate effect.
623 function image_rotate_form($data) {
624 $form['degrees'] = array(
625 '#type' => 'textfield',
626 '#default_value' => (isset($data['degrees'])) ? $data['degrees'] : 0,
627 '#title' => t('Rotation angle'),
628 '#description' => t('The number of degrees the image should be rotated. Positive numbers are clockwise, negative are counter-clockwise.'),
629 '#field_suffix' => '°',
633 '#element_validate' => array('image_effect_integer_validate'),
634 '#allow_negative' => TRUE,
636 $form['bgcolor'] = array(
637 '#type' => 'textfield',
638 '#default_value' => (isset($data['bgcolor'])) ? $data['bgcolor'] : '#FFFFFF',
639 '#title' => t('Background color'),
640 '#description' => t('The background color to use for exposed areas of the image. Use web-style hex colors (#FFFFFF for white, #000000 for black). Leave blank for transparency on image types that support it.'),
643 '#element_validate' => array('image_effect_color_validate'),
645 $form['random'] = array(
646 '#type' => 'checkbox',
647 '#default_value' => (isset($data['random'])) ? $data['random'] : 0,
648 '#title' => t('Randomize'),
649 '#description' => t('Randomize the rotation angle for each image. The angle specified above is used as a maximum.'),
655 * Returns HTML for the page containing the list of image styles.
658 * An associative array containing:
659 * - styles: An array of all the image styles returned by image_get_styles().
661 * @see image_get_styles()
664 function theme_image_style_list($variables) {
665 $styles = $variables['styles'];
667 $header = array(t('Style name'), t('Settings'), array('data' => t('Operations'), 'colspan' => 3));
669 foreach ($styles as $style) {
671 $row[] = l($style['label'], 'admin/config/media/image-styles/edit/' . $style['name']);
672 $link_attributes = array(
673 'attributes' => array(
674 'class' => array('image-style-link'),
677 if ($style['storage'] == IMAGE_STORAGE_NORMAL) {
678 $row[] = t('Custom');
679 $row[] = l(t('edit'), 'admin/config/media/image-styles/edit/' . $style['name'], $link_attributes);
680 $row[] = l(t('delete'), 'admin/config/media/image-styles/delete/' . $style['name'], $link_attributes);
682 elseif ($style['storage'] == IMAGE_STORAGE_OVERRIDE) {
683 $row[] = t('Overridden');
684 $row[] = l(t('edit'), 'admin/config/media/image-styles/edit/' . $style['name'], $link_attributes);
685 $row[] = l(t('revert'), 'admin/config/media/image-styles/revert/' . $style['name'], $link_attributes);
688 $row[] = t('Default');
689 $row[] = l(t('edit'), 'admin/config/media/image-styles/edit/' . $style['name'], $link_attributes);
696 $rows[] = array(array(
698 'data' => t('There are currently no styles. <a href="!url">Add a new one</a>.', array('!url' => url('admin/config/media/image-styles/add'))),
702 return theme('table', array('header' => $header, 'rows' => $rows));
706 * Returns HTML for a listing of the effects within a specific image style.
709 * An associative array containing:
710 * - form: A render element representing the form.
714 function theme_image_style_effects($variables) {
715 $form = $variables['form'];
719 foreach (element_children($form) as $key) {
721 $form[$key]['weight']['#attributes']['class'] = array('image-effect-order-weight');
722 if (is_numeric($key)) {
723 $summary = drupal_render($form[$key]['summary']);
724 $row[] = drupal_render($form[$key]['label']) . (empty($summary) ? '' : ' ' . $summary);
725 $row[] = drupal_render($form[$key]['weight']);
726 $row[] = drupal_render($form[$key]['configure']);
727 $row[] = drupal_render($form[$key]['remove']);
730 // Add the row for adding a new image effect.
731 $row[] = '<div class="image-style-new">' . drupal_render($form['new']['new']) . drupal_render($form['new']['add']) . '</div>';
732 $row[] = drupal_render($form['new']['weight']);
733 $row[] = array('data' => '', 'colspan' => 2);
736 if (!isset($form[$key]['#access']) || $form[$key]['#access']) {
739 'class' => !empty($form[$key]['weight']['#access']) || $key == 'new' ? array('draggable') : array(),
747 array('data' => t('Operations'), 'colspan' => 2),
750 if (count($rows) == 1 && $form['new']['#access']) {
751 array_unshift($rows, array(array(
752 'data' => t('There are currently no effects in this style. Add one by selecting an option below.'),
757 $output = theme('table', array('header' => $header, 'rows' => $rows, 'attributes' => array('id' => 'image-style-effects')));
758 drupal_add_tabledrag('image-style-effects', 'order', 'sibling', 'image-effect-order-weight');
763 * Returns HTML for a preview of an image style.
766 * An associative array containing:
767 * - style: The image style array being previewed.
771 function theme_image_style_preview($variables) {
772 $style = $variables['style'];
774 $sample_image = variable_get('image_style_preview_image', drupal_get_path('module', 'image') . '/sample.png');
776 $sample_height = 160;
778 // Set up original file information.
779 $original_path = $sample_image;
780 $original_image = image_get_info($original_path);
781 if ($original_image['width'] > $original_image['height']) {
782 $original_width = min($original_image['width'], $sample_width);
783 $original_height = round($original_width / $original_image['width'] * $original_image['height']);
786 $original_height = min($original_image['height'], $sample_height);
787 $original_width = round($original_height / $original_image['height'] * $original_image['width']);
789 $original_attributes = array_intersect_key($original_image, array('width' => '', 'height' => ''));
790 $original_attributes['style'] = 'width: ' . $original_width . 'px; height: ' . $original_height . 'px;';
792 // Set up preview file information.
793 $preview_file = image_style_path($style['name'], $original_path);
794 if (!file_exists($preview_file)) {
795 image_style_create_derivative($style, $original_path, $preview_file);
797 $preview_image = image_get_info($preview_file);
798 if ($preview_image['width'] > $preview_image['height']) {
799 $preview_width = min($preview_image['width'], $sample_width);
800 $preview_height = round($preview_width / $preview_image['width'] * $preview_image['height']);
803 $preview_height = min($preview_image['height'], $sample_height);
804 $preview_width = round($preview_height / $preview_image['height'] * $preview_image['width']);
806 $preview_attributes = array_intersect_key($preview_image, array('width' => '', 'height' => ''));
807 $preview_attributes['style'] = 'width: ' . $preview_width . 'px; height: ' . $preview_height . 'px;';
809 // In the previews, timestamps are added to prevent caching of images.
810 $output = '<div class="image-style-preview preview clearfix">';
812 // Build the preview of the original image.
813 $original_url = file_create_url($original_path);
814 $output .= '<div class="preview-image-wrapper">';
815 $output .= t('original') . ' (' . l(t('view actual size'), $original_url) . ')';
816 $output .= '<div class="preview-image original-image" style="' . $original_attributes['style'] . '">';
817 $output .= '<a href="' . $original_url . '">' . theme('image', array('path' => $original_path, 'alt' => t('Sample original image'), 'title' => '', 'attributes' => $original_attributes)) . '</a>';
818 $output .= '<div class="height" style="height: ' . $original_height . 'px"><span>' . $original_image['height'] . 'px</span></div>';
819 $output .= '<div class="width" style="width: ' . $original_width . 'px"><span>' . $original_image['width'] . 'px</span></div>';
820 $output .= '</div>'; // End preview-image.
821 $output .= '</div>'; // End preview-image-wrapper.
823 // Build the preview of the image style.
824 $preview_url = file_create_url($preview_file) . '?cache_bypass=' . REQUEST_TIME;
825 $output .= '<div class="preview-image-wrapper">';
826 $output .= check_plain($style['label']) . ' (' . l(t('view actual size'), file_create_url($preview_file) . '?' . time()) . ')';
827 $output .= '<div class="preview-image modified-image" style="' . $preview_attributes['style'] . '">';
828 $output .= '<a href="' . file_create_url($preview_file) . '?' . time() . '">' . theme('image', array('path' => $preview_url, 'alt' => t('Sample modified image'), 'title' => '', 'attributes' => $preview_attributes)) . '</a>';
829 $output .= '<div class="height" style="height: ' . $preview_height . 'px"><span>' . $preview_image['height'] . 'px</span></div>';
830 $output .= '<div class="width" style="width: ' . $preview_width . 'px"><span>' . $preview_image['width'] . 'px</span></div>';
831 $output .= '</div>'; // End preview-image.
832 $output .= '</div>'; // End preview-image-wrapper.
834 $output .= '</div>'; // End image-style-preview.
840 * Returns HTML for a 3x3 grid of checkboxes for image anchors.
843 * An associative array containing:
844 * - element: A render element containing radio buttons.
848 function theme_image_anchor($variables) {
849 $element = $variables['element'];
853 foreach (element_children($element) as $n => $key) {
854 $element[$key]['#attributes']['title'] = $element[$key]['#title'];
855 unset($element[$key]['#title']);
856 $row[] = drupal_render($element[$key]);
857 if ($n % 3 == 3 - 1) {
863 return theme('table', array('header' => array(), 'rows' => $rows, 'attributes' => array('class' => array('image-anchor'))));
867 * Returns HTML for a summary of an image resize effect.
870 * An associative array containing:
871 * - data: The current configuration for this resize effect.
875 function theme_image_resize_summary($variables) {
876 $data = $variables['data'];
878 if ($data['width'] && $data['height']) {
879 return check_plain($data['width']) . 'x' . check_plain($data['height']);
882 return ($data['width']) ? t('width @width', array('@width' => $data['width'])) : t('height @height', array('@height' => $data['height']));
887 * Returns HTML for a summary of an image scale effect.
890 * An associative array containing:
891 * - data: The current configuration for this scale effect.
895 function theme_image_scale_summary($variables) {
896 $data = $variables['data'];
897 return theme('image_resize_summary', array('data' => $data)) . ' ' . ($data['upscale'] ? '(' . t('upscaling allowed') . ')' : '');
901 * Returns HTML for a summary of an image crop effect.
904 * An associative array containing:
905 * - data: The current configuration for this crop effect.
909 function theme_image_crop_summary($variables) {
910 return theme('image_resize_summary', $variables);
914 * Returns HTML for a summary of an image rotate effect.
917 * An associative array containing:
918 * - data: The current configuration for this rotate effect.
922 function theme_image_rotate_summary($variables) {
923 $data = $variables['data'];
924 return ($data['random']) ? t('random between -@degrees° and @degrees°', array('@degrees' => str_replace('-', '', $data['degrees']))) : t('@degrees°', array('@degrees' => $data['degrees']));