WordPress.org

Make WordPress Core

Ticket #21811: trac-21811-image-edit-intermediate-crop-sizes.patch

File trac-21811-image-edit-intermediate-crop-sizes.patch, 25.6 KB (added by tomauger, 6 years ago)

Allows intermediate image sizes to be targeted for cropping in wp_save_image()

  • wp-admin/includes/image-edit.php

     
    66 * @subpackage Administration
    77 */
    88
     9$image_editor_groups = array();
     10
     11/**
     12 * @uses do_action( 'add_image_editor_groups' ) to allow plugins / themes to register / unregister image editor groups
     13 * @uses apply_filters( 'image_editor_groups' ) to allow direct filtering of the $image_editor_groups global array
     14 *
     15 * @global array $image_editor_groups
     16 * @param type $post_id
     17 * @param type $msg
     18 */
    919function wp_image_editor($post_id, $msg = false) {
    1020        $nonce = wp_create_nonce("image_editor-$post_id");
    1121        $meta = wp_get_attachment_metadata($post_id);
     
    1323        $sub_sizes = isset($meta['sizes']) && is_array($meta['sizes']);
    1424        $note = '';
    1525
     26        if ( $thumb && $sub_sizes ) {
     27                $thumb_img = wp_constrain_dimensions( $thumb['width'], $thumb['height'], 160, 120 );
     28
     29                add_image_edit_group (
     30                        'thumbnail-settings',
     31                        __( 'Thumbnail Settings' ),
     32                        'imgedit_group_thumbnail_settings',
     33                        'default',
     34                        __('The thumbnail image can be cropped differently. For example it can be square or contain only a portion of the original image to showcase it better. Here you can select whether to apply changes to all image sizes or make the thumbnail different.'),
     35                        'imgedit-applyto',
     36                        compact( 'thumb', 'thumb_img', 'sub_sizes' )
     37                );
     38        }
     39
     40        add_image_edit_group(
     41                'image-scale',
     42                __( 'Scale Image' ),
     43                'imgedit_group_scale_image',
     44                'default',
     45                __( 'You can proportionally scale the original image. For best results the scaling should be done before performing any other operations on it like crop, rotate, etc. Note that images can only be scaled down, not up.' ),
     46                '',
     47                compact( 'meta' )
     48        );
     49
     50
     51        add_image_edit_group(
     52                'image-crop',
     53                __( 'Crop Image' ),
     54                'imgedit_group_crop_image',
     55                'default',
     56                sprintf(
     57                        '<p>%1$s</p><p><strong>%2$s</strong><br />%3$s</p><p><strong>%4s</strong><br />%5$s</p>',
     58                        __('The image can be cropped by clicking on it and dragging to select the desired part. While dragging the dimensions of the selection are displayed below.'),
     59                        __('Crop Aspect Ratio'),
     60                        __('You can specify the crop selection aspect ratio then hold down the Shift key while dragging to lock it. The values can be 1:1 (square), 4:3, 16:9, etc. If there is a selection, specifying aspect ratio will set it immediately.'),
     61                        __('Crop Selection'),
     62                        __('Once started, the selection can be adjusted by entering new values (in pixels). Note that these values are scaled to approximately match the original image dimensions. The minimum selection size equals the thumbnail size as set in the Media settings.')
     63                )
     64        );
     65
    1666        if ( isset( $meta['width'], $meta['height'] ) )
    1767                $big = max( $meta['width'], $meta['height'] );
    1868        else
     
    2575        if ( ! empty( $backup_sizes ) && isset( $backup_sizes['full-orig'], $meta['file'] ) )
    2676                $can_restore = $backup_sizes['full-orig']['file'] != basename( $meta['file'] );
    2777
     78        if ( $can_restore ) {
     79                add_image_edit_group(
     80                        'image-restore',
     81                        __( 'Restore Original Image'),
     82                        'imgedit_group_restore_image',
     83                        'default',
     84                        __('Discard any changes and restore the original image.'),
     85                        ''
     86                );
     87        }
     88
     89
    2890        if ( $msg ) {
    2991                if ( isset($msg->error) )
    3092                        $note = "<div class='error'><p>$msg->error</p></div>";
     
    3597        ?>
    3698        <div class="imgedit-wrap">
    3799        <?php echo $note; ?>
    38         <table id="imgedit-panel-<?php echo $post_id; ?>"><tbody>
    39         <tr><td>
    40         <div class="imgedit-menu">
    41                 <div onclick="imageEdit.crop(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-crop disabled" title="<?php esc_attr_e( 'Crop' ); ?>"></div><?php
     100                <table id="imgedit-panel-<?php echo $post_id; ?>"><tbody>
     101                        <tr><td>
     102                                <div class="imgedit-menu">
     103                                        <div onclick="imageEdit.crop(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-crop disabled" title="<?php esc_attr_e( 'Crop' ); ?>"></div><?php
    42104
    43         // On some setups GD library does not provide imagerotate() - Ticket #11536
    44         if ( wp_image_editor_supports( array( 'mime_type' => get_post_mime_type( $post_id ), 'methods' => array( 'rotate' ) ) ) ) { ?>
    45                 <div class="imgedit-rleft"  onclick="imageEdit.rotate( 90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate counter-clockwise' ); ?>"></div>
    46                 <div class="imgedit-rright" onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate clockwise' ); ?>"></div>
    47 <?php } else {
    48                 $note_no_rotate = esc_attr__('Image rotation is not supported by your web host.');
    49 ?>
    50             <div class="imgedit-rleft disabled"  title="<?php echo $note_no_rotate; ?>"></div>
    51             <div class="imgedit-rright disabled" title="<?php echo $note_no_rotate; ?>"></div>
    52 <?php } ?>
     105                                // On some setups GD library does not provide imagerotate() - Ticket #11536
     106                                if ( wp_image_editor_supports( array( 'mime_type' => get_post_mime_type( $post_id ), 'methods' => array( 'rotate' ) ) ) ) { ?>
     107                                        <div class="imgedit-rleft"  onclick="imageEdit.rotate( 90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate counter-clockwise' ); ?>"></div>
     108                                        <div class="imgedit-rright" onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate clockwise' ); ?>"></div>
     109                        <?php } else {
     110                                        $note_no_rotate = esc_attr__('Image rotation is not supported by your web host.');
     111                        ?>
     112                                        <div class="imgedit-rleft disabled"  title="<?php echo $note_no_rotate; ?>"></div>
     113                                        <div class="imgedit-rright disabled" title="<?php echo $note_no_rotate; ?>"></div>
     114                        <?php } ?>
    53115
    54                 <div onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-flipv" title="<?php esc_attr_e( 'Flip vertically' ); ?>"></div>
    55                 <div onclick="imageEdit.flip(2, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-fliph" title="<?php esc_attr_e( 'Flip horizontally' ); ?>"></div>
     116                                        <div onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-flipv" title="<?php esc_attr_e( 'Flip vertically' ); ?>"></div>
     117                                        <div onclick="imageEdit.flip(2, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-fliph" title="<?php esc_attr_e( 'Flip horizontally' ); ?>"></div>
    56118
    57                 <div id="image-undo-<?php echo $post_id; ?>" onclick="imageEdit.undo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-undo disabled" title="<?php esc_attr_e( 'Undo' ); ?>"></div>
    58                 <div id="image-redo-<?php echo $post_id; ?>" onclick="imageEdit.redo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-redo disabled" title="<?php esc_attr_e( 'Redo' ); ?>"></div>
    59                 <br class="clear" />
    60         </div>
     119                                        <div id="image-undo-<?php echo $post_id; ?>" onclick="imageEdit.undo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-undo disabled" title="<?php esc_attr_e( 'Undo' ); ?>"></div>
     120                                        <div id="image-redo-<?php echo $post_id; ?>" onclick="imageEdit.redo(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-redo disabled" title="<?php esc_attr_e( 'Redo' ); ?>"></div>
     121                                        <br class="clear" />
     122                                </div>
    61123
    62         <input type="hidden" id="imgedit-sizer-<?php echo $post_id; ?>" value="<?php echo $sizer; ?>" />
    63         <input type="hidden" id="imgedit-minthumb-<?php echo $post_id; ?>" value="<?php echo ( get_option('thumbnail_size_w') . ':' . get_option('thumbnail_size_h') ); ?>" />
    64         <input type="hidden" id="imgedit-history-<?php echo $post_id; ?>" value="" />
    65         <input type="hidden" id="imgedit-undone-<?php echo $post_id; ?>" value="0" />
    66         <input type="hidden" id="imgedit-selection-<?php echo $post_id; ?>" value="" />
    67         <input type="hidden" id="imgedit-x-<?php echo $post_id; ?>" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
    68         <input type="hidden" id="imgedit-y-<?php echo $post_id; ?>" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
     124                                <input type="hidden" id="imgedit-sizer-<?php echo $post_id; ?>" value="<?php echo $sizer; ?>" />
     125                                <input type="hidden" id="imgedit-minthumb-<?php echo $post_id; ?>" value="<?php echo ( get_option('thumbnail_size_w') . ':' . get_option('thumbnail_size_h') ); ?>" />
     126                                <input type="hidden" id="imgedit-history-<?php echo $post_id; ?>" value="" />
     127                                <input type="hidden" id="imgedit-undone-<?php echo $post_id; ?>" value="0" />
     128                                <input type="hidden" id="imgedit-selection-<?php echo $post_id; ?>" value="" />
     129                                <input type="hidden" id="imgedit-x-<?php echo $post_id; ?>" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
     130                                <input type="hidden" id="imgedit-y-<?php echo $post_id; ?>" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
    69131
    70         <div id="imgedit-crop-<?php echo $post_id; ?>" class="imgedit-crop-wrap">
    71         <img id="image-preview-<?php echo $post_id; ?>" onload="imageEdit.imgLoaded('<?php echo $post_id; ?>')" src="<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>?action=imgedit-preview&amp;_ajax_nonce=<?php echo $nonce; ?>&amp;postid=<?php echo $post_id; ?>&amp;rand=<?php echo rand(1, 99999); ?>" />
    72         </div>
     132                                <div id="imgedit-crop-<?php echo $post_id; ?>" class="imgedit-crop-wrap">
     133                                <img id="image-preview-<?php echo $post_id; ?>" onload="imageEdit.imgLoaded('<?php echo $post_id; ?>')" src="<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>?action=imgedit-preview&amp;_ajax_nonce=<?php echo $nonce; ?>&amp;postid=<?php echo $post_id; ?>&amp;rand=<?php echo rand(1, 99999); ?>" />
     134                                </div>
    73135
    74         <div class="imgedit-submit">
    75                 <input type="button" onclick="imageEdit.close(<?php echo $post_id; ?>, 1)" class="button" value="<?php esc_attr_e( 'Cancel' ); ?>" />
    76                 <input type="button" onclick="imageEdit.save(<?php echo "$post_id, '$nonce'"; ?>)" disabled="disabled" class="button-primary imgedit-submit-btn" value="<?php esc_attr_e( 'Save' ); ?>" />
    77         </div>
    78         </td>
     136                                <?php do_action( 'image_editor_below_image' ) ?>
     137                        </td>
    79138
    80         <td class="imgedit-settings">
    81         <div class="imgedit-group">
    82         <div class="imgedit-group-top">
    83                 <a class="imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;" href="#"><strong><?php _e('Scale Image'); ?></strong></a>
    84                 <div class="imgedit-help">
    85                 <p><?php _e('You can proportionally scale the original image. For best results the scaling should be done before performing any other operations on it like crop, rotate, etc. Note that images can only be scaled down, not up.'); ?></p>
    86                 <?php if ( isset( $meta['width'], $meta['height'] ) ): ?>
    87                 <p><?php printf( __('Original dimensions %s'), $meta['width'] . '&times;' . $meta['height'] ); ?></p>
    88                 <?php endif ?>
    89                 <div class="imgedit-submit">
    90                 <span class="nowrap"><input type="text" id="imgedit-scale-width-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1)" style="width:4em;" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />&times;<input type="text" id="imgedit-scale-height-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0)" style="width:4em;" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
    91                 <span class="imgedit-scale-warn" id="imgedit-scale-warn-<?php echo $post_id; ?>">!</span></span>
    92                 <input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'scale')" class="button-primary" value="<?php esc_attr_e( 'Scale' ); ?>" />
    93                 </div>
    94                 </div>
    95         </div>
     139                        <td class="imgedit-settings">
    96140
    97 <?php if ( $can_restore ) { ?>
     141                        <?php
     142                                /* Image Editor Groups */
     143                                do_action( 'add_image_editor_groups', $post_id );
    98144
    99         <div class="imgedit-group-top">
    100                 <a class="imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;" href="#"><strong><?php _e('Restore Original Image'); ?></strong></a>
    101                 <div class="imgedit-help">
    102                 <p><?php _e('Discard any changes and restore the original image.');
     145                                do_image_edit_groups( $post_id, $nonce );
     146                        ?>
    103147
    104                 if ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE )
    105                         echo ' '.__('Previously edited copies of the image will not be deleted.');
     148                                <div class="imgedit-submit">
     149                                        <input type="button" onclick="imageEdit.close(<?php echo $post_id; ?>, 1)" class="button" value="<?php esc_attr_e( 'Cancel' ); ?>" />
     150                                        <input type="button" onclick="imageEdit.save(<?php echo "$post_id, '$nonce'"; ?>)" disabled="disabled" class="button-primary imgedit-submit-btn" value="<?php esc_attr_e( 'Save' ); ?>" />
     151                                </div>
    106152
    107                 ?></p>
    108                 <div class="imgedit-submit">
    109                 <input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'restore')" class="button-primary" value="<?php esc_attr_e( 'Restore image' ); ?>" <?php echo $can_restore; ?> />
    110                 </div>
    111                 </div>
    112         </div>
    113153
    114 <?php } ?>
     154                        </td><!-- /.imgedit-settings --></tr>
    115155
    116         </div>
     156                </tbody></table>
    117157
    118         <div class="imgedit-group">
    119         <div class="imgedit-group-top">
    120                 <strong><?php _e('Image Crop'); ?></strong>
    121                 <a class="imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;" href="#"><?php _e('(help)'); ?></a>
    122                 <div class="imgedit-help">
    123                 <p><?php _e('The image can be cropped by clicking on it and dragging to select the desired part. While dragging the dimensions of the selection are displayed below.'); ?></p>
    124 
    125                 <p><strong><?php _e('Crop Aspect Ratio'); ?></strong><br />
    126                 <?php _e('You can specify the crop selection aspect ratio then hold down the Shift key while dragging to lock it. The values can be 1:1 (square), 4:3, 16:9, etc. If there is a selection, specifying aspect ratio will set it immediately.'); ?></p>
    127 
    128                 <p><strong><?php _e('Crop Selection'); ?></strong><br />
    129                 <?php _e('Once started, the selection can be adjusted by entering new values (in pixels). Note that these values are scaled to approximately match the original image dimensions. The minimum selection size equals the thumbnail size as set in the Media settings.'); ?></p>
    130                 </div>
     158                <div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div>
     159                <script type="text/javascript">jQuery( function() { imageEdit.init(<?php echo $post_id; ?>); });</script>
     160                <div class="hidden" id="imgedit-leaving-<?php echo $post_id; ?>"><?php _e("There are unsaved changes that will be lost. 'OK' to continue, 'Cancel' to return to the Image Editor."); ?></div>
    131161        </div>
    132 
    133         <p>
    134                 <?php _e('Aspect ratio:'); ?>
    135                 <span  class="nowrap">
    136                 <input type="text" id="imgedit-crop-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 0, this)" style="width:3em;" />
    137                 :
    138                 <input type="text" id="imgedit-crop-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 1, this)" style="width:3em;" />
    139                 </span>
    140         </p>
    141 
    142         <p id="imgedit-crop-sel-<?php echo $post_id; ?>">
    143                 <?php _e('Selection:'); ?>
    144                 <span  class="nowrap">
    145                 <input type="text" id="imgedit-sel-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>)" style="width:4em;" />
    146                 :
    147                 <input type="text" id="imgedit-sel-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>)" style="width:4em;" />
    148                 </span>
    149         </p>
    150         </div>
    151 
    152         <?php if ( $thumb && $sub_sizes ) {
    153                 $thumb_img = wp_constrain_dimensions( $thumb['width'], $thumb['height'], 160, 120 );
    154         ?>
    155 
    156         <div class="imgedit-group imgedit-applyto">
    157         <div class="imgedit-group-top">
    158                 <strong><?php _e('Thumbnail Settings'); ?></strong>
    159                 <a class="imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;" href="#"><?php _e('(help)'); ?></a>
    160                 <p class="imgedit-help"><?php _e('The thumbnail image can be cropped differently. For example it can be square or contain only a portion of the original image to showcase it better. Here you can select whether to apply changes to all image sizes or make the thumbnail different.'); ?></p>
    161         </div>
    162 
    163         <p>
    164                 <img src="<?php echo $thumb['url']; ?>" width="<?php echo $thumb_img[0]; ?>" height="<?php echo $thumb_img[1]; ?>" class="imgedit-size-preview" alt="" /><br /><?php _e('Current thumbnail'); ?>
    165         </p>
    166 
    167         <p id="imgedit-save-target-<?php echo $post_id; ?>">
    168                 <strong><?php _e('Apply changes to:'); ?></strong><br />
    169 
    170                 <label class="imgedit-label">
    171                 <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="all" checked="checked" />
    172                 <?php _e('All image sizes'); ?></label>
    173 
    174                 <label class="imgedit-label">
    175                 <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="thumbnail" />
    176                 <?php _e('Thumbnail'); ?></label>
    177 
    178                 <label class="imgedit-label">
    179                 <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="nothumb" />
    180                 <?php _e('All sizes except thumbnail'); ?></label>
    181         </p>
    182         </div>
    183 
    184         <?php } ?>
    185 
    186         </td></tr>
    187         </tbody></table>
    188         <div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div>
    189         <script type="text/javascript">jQuery( function() { imageEdit.init(<?php echo $post_id; ?>); });</script>
    190         <div class="hidden" id="imgedit-leaving-<?php echo $post_id; ?>"><?php _e("There are unsaved changes that will be lost. 'OK' to continue, 'Cancel' to return to the Image Editor."); ?></div>
    191         </div>
    192162<?php
    193163}
    194164
     
    675645        } elseif ( 'thumbnail' == $target ) {
    676646                $sizes = array( 'thumbnail' );
    677647                $success = $delete = $nocrop = true;
     648        } else {
     649                // Allow custom intermediate sizes to be individually targeted
     650                $sizes = array( $target );
     651                $success = $delete = true;
    678652        }
    679653
    680654        if ( isset( $sizes ) ) {
     
    695669                        }
    696670
    697671                        $crop = $nocrop ? false : get_option("{$size}_crop");
    698                         $_sizes[ $size ] = array( 'width' => get_option("{$size}_size_w"), 'height' => get_option("{$size}_size_h"), 'crop' => $crop );
     672
     673                        // Accommodate custom defined sizes defined with add_image_size()
     674                        global $_wp_additional_image_sizes;
     675                        if ( isset( $_wp_additional_image_sizes[$size] ) ){
     676                                $size_w = $_wp_additional_image_sizes[$size]['width'];
     677                                $size_h = $_wp_additional_image_sizes[$size]['height'];
     678                                $crop = $_wp_additional_image_sizes[$size]['crop'];
     679                        } else {
     680                                $size_w = get_option("{$size}_size_w");
     681                                $size_h = get_option("{$size}_size_h");
     682                        }
     683
     684                        $_sizes[ $size ] = array( 'width' => $size_w, 'height' => $size_h, 'crop' => $crop );
    699685                }
    700686
    701687                $meta['sizes'] = array_merge( $meta['sizes'], $img->multi_resize( $_sizes ) );
     
    733719        $return->msg = esc_js( __('Image saved') );
    734720        return $return;
    735721}
     722
     723/**
     724 * Adds a new image editor group to the Edit Image view.
     725 *
     726 * Should be called before {@link do_image_edit_groups()}, preferably from a 'add_image_edit_group' action callback.
     727 *
     728 * @global array $image_editor_groups
     729 *
     730 * @param int $id Unique ID for this editor group
     731 * @param string $title Title that appears in the editor group box
     732 * @param string|array $callback Function to be called to render the editor group content. Function signature is `( $post_id, $imgedit_group, $args )`
     733 * @param string $tab Optional. Default "default". The name of the tab this group appears in
     734 * @param string $help_text Optional. Help text that appears in the editor box content
     735 * @param string $class Optional. CSS class to be added to the editor group DIV
     736 * @param array $callback_args Optional. Additional arguments to be passed to the callback function.
     737 */
     738function add_image_edit_group( $id, $title, $callback, $tab = "default", $help_text = "", $class = "", $callback_args = null ){
     739        global $image_editor_groups;
     740
     741        /** @TODO make sure $id is unique **/
     742        $image_editor_groups[$tab][$id] = array(
     743                'id' => $id,
     744                'title' => $title,
     745                'callback' => $callback,
     746                'class' => $class,
     747                'help' => $help_text,
     748                'callback_args' => $callback_args
     749        );
     750}
     751
     752function remove_image_edit_group( $remove_id ){
     753        global $image_editor_groups;
     754
     755        foreach ( $image_editor_groups as $tab_group => &$groups ){
     756                foreach ( $groups as $id => $group ){
     757                        if ( $id == $remove_id ){
     758                                unset ( $groups[$id] );
     759                                return true;
     760                        }
     761                }
     762        }
     763        return false;
     764}
     765
     766function imgedit_group_scale_image( $post_id, $imgedit_group, $args ){
     767        extract( $args );
     768        ?>
     769
     770                <?php if ( isset( $meta['width'], $meta['height'] ) ): ?>
     771                <p><?php printf( __('Original dimensions %s'), $meta['width'] . '&times;' . $meta['height'] ); ?></p>
     772                <?php endif ?>
     773                <div class="imgedit-submit">
     774                        <span class="nowrap"><input type="text" id="imgedit-scale-width-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 1)" style="width:4em;" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />&times;<input type="text" id="imgedit-scale-height-<?php echo $post_id; ?>" onkeyup="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0)" onblur="imageEdit.scaleChanged(<?php echo $post_id; ?>, 0)" style="width:4em;" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
     775                        <span class="imgedit-scale-warn" id="imgedit-scale-warn-<?php echo $post_id; ?>">!</span></span>
     776                        <input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'scale')" class="button-primary" value="<?php esc_attr_e( 'Scale' ); ?>" />
     777                </div>
     778                </div>
     779
     780        <?php
     781}
     782
     783function imgedit_group_crop_image( $post_id, $imgedit_group, $args ){
     784        extract( $args );
     785        ?>
     786                <p>
     787                        <?php _e('Aspect ratio:'); ?>
     788                        <span  class="nowrap">
     789                        <input type="text" id="imgedit-crop-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 0, this)" style="width:3em;" />
     790                        :
     791                        <input type="text" id="imgedit-crop-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 1, this)" style="width:3em;" />
     792                        </span>
     793                </p>
     794
     795                <p id="imgedit-crop-sel-<?php echo $post_id; ?>">
     796                        <?php _e('Selection:'); ?>
     797                        <span  class="nowrap">
     798                        <input type="text" id="imgedit-sel-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>)" style="width:4em;" />
     799                        &times;
     800                        <input type="text" id="imgedit-sel-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>)" style="width:4em;" />
     801                        </span>
     802                </p>
     803        <?php
     804}
     805
     806function imgedit_group_thumbnail_settings( $post_id, $imgedit_group, $args ){
     807        extract( $args );
     808        ?>
     809
     810        <?php if ( isset( $thumb ) ): ?>
     811        <p>
     812                <img src="<?php echo $thumb['url']; ?>" width="<?php echo $thumb_img[0]; ?>" height="<?php echo $thumb_img[1]; ?>" class="imgedit-size-preview" alt="" /><br /><?php _e('Current thumbnail'); ?>
     813        </p>
     814        <?php endif; ?>
     815
     816        <p id="imgedit-save-target-<?php echo $post_id; ?>">
     817                <strong><?php _e('Apply changes to:'); ?></strong><br />
     818
     819                <label class="imgedit-label">
     820                <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="all" checked="checked" />
     821                <?php _e('All image sizes'); ?></label>
     822
     823                <label class="imgedit-label">
     824                <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="thumbnail" />
     825                <?php _e('Thumbnail'); ?></label>
     826
     827                <label class="imgedit-label">
     828                <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="nothumb" />
     829                <?php _e('All sizes except thumbnail'); ?></label>
     830        </p>
     831
     832        <?php
     833}
     834
     835function imgedit_group_restore_image( $post_id, $imgedit_group, $args ){
     836        extract( $args );
     837        ?>
     838
     839        <p>
     840        <?php
     841                if ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE )
     842                echo ' '.__('Previously edited copies of the image will not be deleted.');
     843        ?>
     844        </p>
     845
     846        <div class="imgedit-submit">
     847                <input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'restore')" class="button-primary" value="<?php esc_attr_e( 'Restore image' ); ?>" />
     848        </div>
     849
     850        <?php
     851}
     852
     853/**
     854 * @global array $image_editor_groups
     855 *
     856 * @param int $post_id
     857 * @param string $nonce
     858 *
     859 * @TODO Currently, tabs auto-create themselves just by defining them in add_image_edit_group(). Eventually we'll want a add_editor_tab() suite of functions so we can better control these tabs.
     860 */
     861function do_image_edit_groups( $post_id, $nonce ){
     862        global $image_editor_groups;
     863
     864        /**
     865         * Allow modification of image editor groups.
     866         *
     867         * @since 3.9
     868         *
     869         * @param int $post_id The ID of the WP_Post (attachment) currently being edited.
     870         */
     871        $editor_groups = apply_filters( 'image_editor_groups', $image_editor_groups, $post_id );
     872
     873        // Only create the tabs structure if needed
     874        $has_tabs = count( $editor_groups ) > 1;
     875
     876        if ( $has_tabs ){
     877                echo '<div id="image-editor-group-tabs"><ul>';
     878
     879                foreach ( $editor_groups as $tab => $tab_groups ){
     880                        if ( $has_tabs ){
     881                                $tab_title = str_replace( array( '-', '_' ), ' ', strtoupper( $tab ) );
     882                                echo '<li><a href="#imgedit-group-tab-' . $tab . '">' . $tab_title . '</a></li>';
     883                        }
     884                }
     885
     886                echo '</ul>';
     887        }
     888
     889        foreach ( $editor_groups as $tab => $tab_groups ){
     890                if ( $has_tabs ) echo '<div id="#imgedit-group-tab-' . $tab . '">';
     891
     892                foreach ( $tab_groups as $imgedit_group ){
     893                        ?>
     894                        <div class="imgedit-group <?php echo $imgedit_group['class']?>">
     895                                <div class="imgedit-group-top">
     896                                        <strong><?php echo $imgedit_group['title'] ?></strong>
     897                                        <?php if ( ! empty( $imgedit_group['help'] ) ): ?>
     898                                                <a class="imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;" href="#"><?php _e('(help)'); ?></a>
     899                                                <div class="imgedit-help"><?php echo $imgedit_group['help'] ?></div>
     900                                        <?php endif; ?>
     901                                </div>
     902
     903                                <?php
     904                                        $imgedit_group['callback_args']['nonce'] = $nonce; // Add the nonce to the callback args of each item, in case it has a submit button
     905                                        call_user_func( $imgedit_group['callback'], $post_id, $imgedit_group, $imgedit_group['callback_args'] );
     906                                ?>
     907
     908                        </div>
     909                        <?php
     910                }
     911
     912                if ( $has_tabs ) echo '</div><!-- /#imgedit-group-tab-' . $tab . ' -->';
     913        }
     914
     915        if ( $has_tabs ) {
     916                echo '</div><!-- /#image-editor-group-tabs -->';
     917                ?>
     918                <script>jQuery( '#image-editor-group-tabs' ).tabs();</script>
     919                <?php
     920        }
     921
     922}