WordPress.org

Make WordPress Core

Ticket #30062: 30062-1-image-edit-groups.patch

File 30062-1-image-edit-groups.patch, 25.8 KB (added by tomauger, 5 years ago)

Refactors wp-admin.includes/image-edit.php to move all Editor Groups into modular callbacks using add_image_edit_group()

  • src/wp-admin/edit-form-advanced.php

     
    160160if ( 'attachment' == $post_type ) {
    161161        wp_enqueue_script( 'image-edit' );
    162162        wp_enqueue_style( 'imgareaselect' );
     163
     164        /**
     165         * Allows plugin and theme developers to hook in their own enqueued scripts and styles to be used
     166         * exclusively in the Image Editor
     167         */
     168        do_action( 'enqueue_image_editor_scripts' );
     169
    163170        add_meta_box( 'submitdiv', __('Save'), 'attachment_submit_meta_box', null, 'side', 'core' );
    164171        add_action( 'edit_form_after_title', 'edit_form_image_editor' );
    165172
  • src/wp-admin/includes/image-edit.php

     
    66 * @subpackage Administration
    77 */
    88
     9$image_editor_groups = array();
     10
    911function wp_image_editor($post_id, $msg = false) {
    1012        $nonce = wp_create_nonce("image_editor-$post_id");
    1113        $meta = wp_get_attachment_metadata($post_id);
     
    3234                        $note = "<div class='updated'><p>$msg->msg</p></div>";
    3335        }
    3436
    35         ?>
    36         <div class="imgedit-wrap">
    37         <div id="imgedit-panel-<?php echo $post_id; ?>">
    3837
    39         <div class="imgedit-settings">
    40         <div class="imgedit-group">
    41         <div class="imgedit-group-top">
    42                 <h3><?php _e( 'Scale Image' ); ?> <a href="#" class="dashicons dashicons-editor-help imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;"></a></h3>
    43                 <div class="imgedit-help">
    44                 <p><?php _e('You can proportionally scale the original image. For best results, scaling should be done before you crop, flip, or rotate. Images can only be scaled down, not up.'); ?></p>
    45                 </div>
    46                 <?php if ( isset( $meta['width'], $meta['height'] ) ): ?>
    47                 <p><?php printf( __('Original dimensions %s'), $meta['width'] . ' &times; ' . $meta['height'] ); ?></p>
    48                 <?php endif ?>
    49                 <div class="imgedit-submit">
    50                 <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; ?>" />
    51                 <span class="imgedit-scale-warn" id="imgedit-scale-warn-<?php echo $post_id; ?>">!</span></span>
    52                 <input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'scale')" class="button button-primary" value="<?php esc_attr_e( 'Scale' ); ?>" />
    53                 </div>
    54         </div>
    55         </div>
     38        // Add the default Image Editor Groups
     39        add_image_edit_group(
     40                'image-scale',
     41                __( 'Scale Image' ),
     42                'imgedit_group_scale_image',
     43                'default',
     44                __( 'You can proportionally scale the original image. For best results, scaling should be done before you crop, flip, or rotate. Images can only be scaled down, not up.' ),
     45                '',
     46                compact( 'meta' )
     47        );
    5648
    57 <?php if ( $can_restore ) { ?>
     49        add_image_edit_group(
     50                'image-crop',
     51                __( 'Image Crop' ),
     52                'imgedit_group_crop_image',
     53                'default',
     54                array(
     55                        __('To crop the image, click on it and drag to make your selection.'),
     56                        sprintf( '<strong>%s</strong><br />', __( 'Crop Aspect Ratio' ) ),
     57                        __( 'The aspect ratio is the relationship between the width and height. You can preserve the aspect ratio by holding down the shift key while resizing your selection. Use the input box to specify the aspect ratio, e.g. 1:1 (square), 4:3, 16:9, etc.' ),
     58                        sprintf( '<strong>%s</strong><br />', __( 'Crop Selection' ) ),
     59                        __( 'Once you have made your selection, you can adjust it by entering the size in pixels. The minimum selection size is the thumbnail size as set in the Media settings.' )
     60                )
     61        );
    5862
    59         <div class="imgedit-group">
    60         <div class="imgedit-group-top">
    61                 <h3><a onclick="imageEdit.toggleHelp(this);return false;" href="#"><?php _e('Restore Original Image'); ?> <span class="dashicons dashicons-arrow-down imgedit-help-toggle"></span></a></h3>
    62                 <div class="imgedit-help">
    63                 <p><?php _e('Discard any changes and restore the original image.');
     63        if ( $thumb && $sub_sizes ) {
     64                $thumb_img = wp_constrain_dimensions( $thumb['width'], $thumb['height'], 160, 120 );
    6465
    65                 if ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE )
    66                         echo ' '.__('Previously edited copies of the image will not be deleted.');
     66                add_image_edit_group (
     67                        'thumbnail-settings',
     68                        __( 'Thumbnail Settings' ),
     69                        'imgedit_group_thumbnail_settings',
     70                        'default',
     71                        __( 'You can edit the image while preserving the thumbnail. For example, you may wish to have a square thumbnail that displays just a section of the image.' ),
     72                        'imgedit-applyto',
     73                        compact( 'thumb', 'thumb_img', 'sub_sizes' )
     74                );
     75        }
    6776
    68                 ?></p>
    69                 <div class="imgedit-submit">
    70                 <input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'restore')" class="button button-primary" value="<?php esc_attr_e( 'Restore image' ); ?>" <?php echo $can_restore; ?> />
    71                 </div>
    72                 </div>
    73         </div>
    74         </div>
     77        if ( $can_restore ){
     78                $help_text = __( 'Discard any changes and restore the original image.' );
     79                if ( ! defined('IMAGE_EDIT_OVERWRITE') || ! IMAGE_EDIT_OVERWRITE ){
     80                        $help_text .= ' ' . __('Previously edited copies of the image will not be deleted.' );
     81                }
    7582
    76 <?php } ?>
     83                add_image_edit_group(
     84                        'image-restore',
     85                        __( 'Restore Original Image' ),
     86                        'imgedit_group_restore_image',
     87                        'default',
     88                        $help_text,
     89                        '',
     90                        compact( 'can_restore' )
     91                );
     92        }
    7793
    78         <div class="imgedit-group">
    79         <div class="imgedit-group-top">
    80                 <h3><?php _e('Image Crop'); ?> <a href="#" class="dashicons dashicons-editor-help imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;"></a></h3>
    81 
    82                 <div class="imgedit-help">
    83                 <p><?php _e('To crop the image, click on it and drag to make your selection.'); ?></p>
    84 
    85                 <p><strong><?php _e('Crop Aspect Ratio'); ?></strong><br />
    86                 <?php _e('The aspect ratio is the relationship between the width and height. You can preserve the aspect ratio by holding down the shift key while resizing your selection. Use the input box to specify the aspect ratio, e.g. 1:1 (square), 4:3, 16:9, etc.'); ?></p>
    87 
    88                 <p><strong><?php _e('Crop Selection'); ?></strong><br />
    89                 <?php _e('Once you have made your selection, you can adjust it by entering the size in pixels. The minimum selection size is the thumbnail size as set in the Media settings.'); ?></p>
    90                 </div>
    91         </div>
    92 
    93         <p>
    94                 <?php _e('Aspect ratio:'); ?>
    95                 <span  class="nowrap">
    96                 <input type="text" id="imgedit-crop-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 0, this)" style="width:3em;" />
    97                 :
    98                 <input type="text" id="imgedit-crop-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 1, this)" style="width:3em;" />
    99                 </span>
    100         </p>
    101 
    102         <p id="imgedit-crop-sel-<?php echo $post_id; ?>">
    103                 <?php _e('Selection:'); ?>
    104                 <span  class="nowrap">
    105                 <input type="text" id="imgedit-sel-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>)" style="width:4em;" />
    106                 &times;
    107                 <input type="text" id="imgedit-sel-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>)" style="width:4em;" />
    108                 </span>
    109         </p>
    110         </div>
    111 
    112         <?php if ( $thumb && $sub_sizes ) {
    113                 $thumb_img = wp_constrain_dimensions( $thumb['width'], $thumb['height'], 160, 120 );
    11494        ?>
     95        <div class="imgedit-wrap">
     96                <div id="imgedit-panel-<?php echo $post_id; ?>">
    11597
    116         <div class="imgedit-group imgedit-applyto">
    117         <div class="imgedit-group-top">
    118                 <h3><?php _e('Thumbnail Settings'); ?> <a href="#" class="dashicons dashicons-editor-help imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;"></a></h3>
    119                 <p class="imgedit-help"><?php _e('You can edit the image while preserving the thumbnail. For example, you may wish to have a square thumbnail that displays just a section of the image.'); ?></p>
    120         </div>
     98                        <div class="imgedit-settings">
     99                        <?php
     100                                /**
     101                                 * Add image editor groups.
     102                                 *
     103                                 * Plugin / theme authors can use this action hook as the correct place to
     104                                 * remove / add image editor groups prior to their being displayed.
     105                                 *
     106                                 * @param int $post_id The ID of the current attachment post being edited.
     107                                 */
     108                                do_action( 'add_image_editor_groups', $post_id );
     109                                do_image_edit_groups( $post_id, $nonce );
     110                        ?>
     111                        </div><!-- /.imgedit-settings -->
    121112
    122         <p>
    123                 <img src="<?php echo $thumb['url']; ?>" width="<?php echo $thumb_img[0]; ?>" height="<?php echo $thumb_img[1]; ?>" class="imgedit-size-preview" alt="" draggable="false" />
    124                 <br /><?php _e('Current thumbnail'); ?>
    125         </p>
     113                        <div class="imgedit-panel-content">
     114                                <?php echo $note; ?>
     115                                <div class="imgedit-menu">
     116                                        <div onclick="imageEdit.crop(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-crop disabled" title="<?php esc_attr_e( 'Crop' ); ?>"></div><?php
    126117
    127         <p id="imgedit-save-target-<?php echo $post_id; ?>">
    128                 <strong><?php _e('Apply changes to:'); ?></strong><br />
     118                                // On some setups GD library does not provide imagerotate() - Ticket #11536
     119                                if ( wp_image_editor_supports( array( 'mime_type' => get_post_mime_type( $post_id ), 'methods' => array( 'rotate' ) ) ) ) { ?>
     120                                        <div class="imgedit-rleft"  onclick="imageEdit.rotate( 90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate counter-clockwise' ); ?>"></div>
     121                                        <div class="imgedit-rright" onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate clockwise' ); ?>"></div>
     122                        <?php } else {
     123                                        $note_no_rotate = esc_attr__('Image rotation is not supported by your web host.');
     124                        ?>
     125                                        <div class="imgedit-rleft disabled"  title="<?php echo $note_no_rotate; ?>"></div>
     126                                        <div class="imgedit-rright disabled" title="<?php echo $note_no_rotate; ?>"></div>
     127                        <?php } ?>
    129128
    130                 <label class="imgedit-label">
    131                 <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="all" checked="checked" />
    132                 <?php _e('All image sizes'); ?></label>
     129                                        <div onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-flipv" title="<?php esc_attr_e( 'Flip vertically' ); ?>"></div>
     130                                        <div onclick="imageEdit.flip(2, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-fliph" title="<?php esc_attr_e( 'Flip horizontally' ); ?>"></div>
    133131
    134                 <label class="imgedit-label">
    135                 <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="thumbnail" />
    136                 <?php _e('Thumbnail'); ?></label>
     132                                        <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>
     133                                        <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>
     134                                        <br class="clear" />
     135                                </div><!-- /.imgedit-menu -->
    137136
    138                 <label class="imgedit-label">
    139                 <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="nothumb" />
    140                 <?php _e('All sizes except thumbnail'); ?></label>
    141         </p>
    142         </div>
     137                                <input type="hidden" id="imgedit-sizer-<?php echo $post_id; ?>" value="<?php echo $sizer; ?>" />
     138                                <input type="hidden" id="imgedit-history-<?php echo $post_id; ?>" value="" />
     139                                <input type="hidden" id="imgedit-undone-<?php echo $post_id; ?>" value="0" />
     140                                <input type="hidden" id="imgedit-selection-<?php echo $post_id; ?>" value="" />
     141                                <input type="hidden" id="imgedit-x-<?php echo $post_id; ?>" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
     142                                <input type="hidden" id="imgedit-y-<?php echo $post_id; ?>" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
    143143
    144         <?php } ?>
     144                                <div id="imgedit-crop-<?php echo $post_id; ?>" class="imgedit-crop-wrap">
     145                                        <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); ?>" />
     146                                </div>
    145147
    146         </div>
     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 button-primary imgedit-submit-btn" value="<?php esc_attr_e( 'Save' ); ?>" />
     151                                </div>
     152                        </div><!-- /.imgedit-panel-content -->
     153                </div><!-- /.imgedit-panel-{$post_id} -->
    147154
    148         <div class="imgedit-panel-content">
    149                 <?php echo $note; ?>
    150                 <div class="imgedit-menu">
    151                         <div onclick="imageEdit.crop(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-crop disabled" title="<?php esc_attr_e( 'Crop' ); ?>"></div><?php
     155                <div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div>
     156                <script type="text/javascript">jQuery( function() { imageEdit.init(<?php echo $post_id; ?>); });</script>
     157                <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>
    152158
    153                 // On some setups GD library does not provide imagerotate() - Ticket #11536
    154                 if ( wp_image_editor_supports( array( 'mime_type' => get_post_mime_type( $post_id ), 'methods' => array( 'rotate' ) ) ) ) { ?>
    155                         <div class="imgedit-rleft"  onclick="imageEdit.rotate( 90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate counter-clockwise' ); ?>"></div>
    156                         <div class="imgedit-rright" onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate clockwise' ); ?>"></div>
    157         <?php } else {
    158                         $note_no_rotate = esc_attr__('Image rotation is not supported by your web host.');
    159         ?>
    160                     <div class="imgedit-rleft disabled"  title="<?php echo $note_no_rotate; ?>"></div>
    161                     <div class="imgedit-rright disabled" title="<?php echo $note_no_rotate; ?>"></div>
    162         <?php } ?>
     159                <?php
    163160
    164                         <div onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-flipv" title="<?php esc_attr_e( 'Flip vertically' ); ?>"></div>
    165                         <div onclick="imageEdit.flip(2, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-fliph" title="<?php esc_attr_e( 'Flip horizontally' ); ?>"></div>
     161                /**
     162                 * Output below the image editor.
     163                 *
     164                 * Plugin / Theme developers can use this action to place additional content beneath the image editor.
     165                 *
     166                 * @param int $post_id The image attachment's post ID.
     167                 */
     168                do_action( 'image_editor_below_image', $post_id );
     169                ?>
    166170
    167                         <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>
    168                         <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>
    169                         <br class="clear" />
    170                 </div>
    171 
    172                 <input type="hidden" id="imgedit-sizer-<?php echo $post_id; ?>" value="<?php echo $sizer; ?>" />
    173                 <input type="hidden" id="imgedit-history-<?php echo $post_id; ?>" value="" />
    174                 <input type="hidden" id="imgedit-undone-<?php echo $post_id; ?>" value="0" />
    175                 <input type="hidden" id="imgedit-selection-<?php echo $post_id; ?>" value="" />
    176                 <input type="hidden" id="imgedit-x-<?php echo $post_id; ?>" value="<?php echo isset( $meta['width'] ) ? $meta['width'] : 0; ?>" />
    177                 <input type="hidden" id="imgedit-y-<?php echo $post_id; ?>" value="<?php echo isset( $meta['height'] ) ? $meta['height'] : 0; ?>" />
    178 
    179                 <div id="imgedit-crop-<?php echo $post_id; ?>" class="imgedit-crop-wrap">
    180                 <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); ?>" />
    181                 </div>
    182 
    183                 <div class="imgedit-submit">
    184                         <input type="button" onclick="imageEdit.close(<?php echo $post_id; ?>, 1)" class="button" value="<?php esc_attr_e( 'Cancel' ); ?>" />
    185                         <input type="button" onclick="imageEdit.save(<?php echo "$post_id, '$nonce'"; ?>)" disabled="disabled" class="button button-primary imgedit-submit-btn" value="<?php esc_attr_e( 'Save' ); ?>" />
    186                 </div>
    187         </div>
    188 
    189         </div>
    190         <div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div>
    191         <script type="text/javascript">jQuery( function() { imageEdit.init(<?php echo $post_id; ?>); });</script>
    192         <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>
    193         </div>
     171        </div><!-- /.imgedit-wrap -->
    194172<?php
    195173}
    196174
     
    826804        $return->msg = esc_js( __('Image saved') );
    827805        return $return;
    828806}
     807
     808
     809/**
     810 * Adds a new image editor group to the Edit Image view.
     811 *
     812 * Should be called before {@link do_image_edit_groups()}, preferably from a 'add_image_edit_group' action callback.
     813 *
     814 * @global array $image_editor_groups
     815 *
     816 * @param int $id Unique ID for this editor group
     817 * @param string $title Title that appears in the editor group box
     818 * @param string|array $callback Function to be called to render the editor group content. Function signature is `( $post_id, $imgedit_group, $args )`
     819 * @param string $tab Optional. Default "default". The name of the tab this group appears in
     820 * @param string $help_text Optional. Help text that appears in the editor box content
     821 * @param string $class Optional. CSS class to be added to the editor group DIV
     822 * @param array $callback_args Optional. Additional arguments to be passed to the callback function.
     823 */
     824function add_image_edit_group( $id, $title, $callback, $tab = "default", $help_text = "", $class = "", $callback_args = null ){
     825        global $image_editor_groups;
     826
     827        /** @TODO make sure $id is unique **/
     828        $image_editor_groups[$tab][$id] = array(
     829                'id' => $id,
     830                'title' => $title,
     831                'callback' => $callback,
     832                'class' => $class,
     833                'help' => (array) $help_text,
     834                'callback_args' => $callback_args
     835        );
     836}
     837
     838function remove_image_edit_group( $remove_id ){
     839        global $image_editor_groups;
     840
     841        foreach ( $image_editor_groups as $tab_group => &$groups ){
     842                foreach ( $groups as $id => $group ){
     843                        if ( $id == $remove_id ){
     844                                unset ( $groups[$id] );
     845                                return true;
     846                        }
     847                }
     848        }
     849        return false;
     850}
     851
     852/**
     853 * @global array $image_editor_groups
     854 *
     855 * @param int $post_id
     856 * @param string $nonce
     857 *
     858 * @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.
     859 */
     860function do_image_edit_groups( $post_id, $nonce ){
     861        global $image_editor_groups;
     862
     863        /**
     864         * Allow modification of image editor groups.
     865         *
     866         * @since 3.9
     867         *
     868         * @param int $post_id The ID of the WP_Post (attachment) currently being edited.
     869         */
     870        $editor_groups = apply_filters( 'image_editor_groups', $image_editor_groups, $post_id );
     871
     872        // Only create the tabs structure if needed
     873        $has_tabs = count( $editor_groups ) > 1;
     874
     875        if ( $has_tabs ){
     876                echo '<div id="image-editor-group-tabs"><ul>';
     877
     878                foreach ( $editor_groups as $tab => $tab_groups ){
     879                        if ( $has_tabs ){
     880                                $tab_title = str_replace( array( '-', '_' ), ' ', strtoupper( $tab ) );
     881                                echo '<li><a href="#imgedit-group-tab-' . $tab . '">' . $tab_title . '</a></li>';
     882                        }
     883                }
     884
     885                echo '</ul>';
     886        }
     887
     888        foreach ( $editor_groups as $tab => $tab_groups ){
     889                if ( $has_tabs ) echo '<div id="#imgedit-group-tab-' . $tab . '">';
     890
     891                foreach ( $tab_groups as $imgedit_group ){
     892                        ?>
     893                        <div class="imgedit-group <?php echo $imgedit_group['class']?>">
     894                                <div class="imgedit-group-top">
     895                                        <h3><?php echo $imgedit_group['title'] ?>
     896                                        <?php if ( ! empty( $imgedit_group['help'] ) ): ?>
     897                                                <a href="#" class="dashicons dashicons-editor-help imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;"></a>
     898                                        <?php endif; ?>
     899                                        </h3>
     900
     901                                        <?php
     902                                        if ( ! empty( $imgedit_group['help'] ) ) {
     903                                                echo '<div class="imgedit-help">';
     904                                                foreach ( $imgedit_group['help'] as $help_paragraph ){
     905                                                        echo wpautop( $help_paragraph );
     906                                                }
     907                                                echo '</div>';
     908                                        }
     909                                        ?>
     910                                </div>
     911
     912                                <?php
     913                                        $imgedit_group['callback_args']['nonce'] = $nonce; // Add the nonce to the callback args of each item, in case it has a submit button
     914                                        call_user_func( $imgedit_group['callback'], $post_id, $imgedit_group, $imgedit_group['callback_args'] );
     915                                ?>
     916
     917                        </div>
     918                        <?php
     919                }
     920
     921                if ( $has_tabs ) echo '</div><!-- /#imgedit-group-tab-' . $tab . ' -->';
     922        }
     923
     924        if ( $has_tabs ) {
     925                echo '</div><!-- /#image-editor-group-tabs -->';
     926                ?>
     927                <script>jQuery( '#image-editor-group-tabs' ).tabs();</script>
     928                <?php
     929        }
     930}
     931
     932
     933/**
     934 * Image Editor Group callback for the Scale Image editor group.
     935 *
     936 * @param int $post_id Attachment post ID
     937 * @param array $imgedit_group The image editor group associative array
     938 * @param array $args Contains the image meta information (width and height)
     939 */
     940function imgedit_group_scale_image( $post_id, $imgedit_group, $args ){
     941        extract( $args );
     942
     943        if ( isset( $meta['width'], $meta['height'] ) ): ?>
     944                <p><?php printf( __('Original dimensions %s'), $meta['width'] . '&times;' . $meta['height'] ); ?></p>
     945        <?php endif ?>
     946        <div class="imgedit-submit">
     947                <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; ?>" />
     948                <span class="imgedit-scale-warn" id="imgedit-scale-warn-<?php echo $post_id; ?>">!</span></span>
     949                <input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'scale')" class="button button-primary" value="<?php esc_attr_e( 'Scale' ); ?>" />
     950        </div>
     951<?php
     952}
     953
     954/**
     955 * Image Editor Group callback for the Crop Image editor group.
     956 *
     957 * @param int $post_id Attachment post ID
     958 * @param array $imgedit_group The image editor group associative array
     959 * @param type $args Not used
     960 */
     961function imgedit_group_crop_image( $post_id, $imgedit_group, $args ){
     962        extract( $args );
     963        ?>
     964                <p>
     965                        <?php _e( 'Aspect ratio:' ); ?>
     966                        <span  class="nowrap">
     967                        <input type="text" id="imgedit-crop-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 0, this)" style="width:3em;" />
     968                        :
     969                        <input type="text" id="imgedit-crop-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setRatioSelection(<?php echo $post_id; ?>, 1, this)" style="width:3em;" />
     970                        </span>
     971                </p>
     972
     973                <p id="imgedit-crop-sel-<?php echo $post_id; ?>">
     974                        <?php _e( 'Selection:' ); ?>
     975                        <span  class="nowrap">
     976                        <input type="text" id="imgedit-sel-width-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>)" style="width:4em;" />
     977                        &times;
     978                        <input type="text" id="imgedit-sel-height-<?php echo $post_id; ?>" onkeyup="imageEdit.setNumSelection(<?php echo $post_id; ?>)" style="width:4em;" />
     979                        </span>
     980                </p>
     981        <?php
     982}
     983
     984/**
     985 * Image Editor Group callback for the Thumbnail Settings editor group.
     986 *
     987 * @param int $post_id Attachment post ID
     988 * @param array $imgedit_group The image editor group associative array
     989 * @param type $args Contains `thumb`, `thumb_img` and `sub_sizes` keys
     990 */
     991function imgedit_group_thumbnail_settings( $post_id, $imgedit_group, $args ){
     992        extract( $args );
     993        ?>
     994
     995        <?php if ( isset( $thumb ) ): ?>
     996        <p>
     997                <img src="<?php echo $thumb['url']; ?>" width="<?php echo $thumb_img[0]; ?>" height="<?php echo $thumb_img[1]; ?>" class="imgedit-size-preview" alt="" draggable="false" />
     998                <br /><?php _e( 'Current thumbnail' ); ?>
     999        </p>
     1000        <?php endif; ?>
     1001
     1002        <p id="imgedit-save-target-<?php echo $post_id; ?>">
     1003                <strong><?php _e( 'Apply changes to:' ); ?></strong><br />
     1004
     1005                <label class="imgedit-label">
     1006                <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="all" checked="checked" />
     1007                <?php _e( 'All image sizes' ); ?></label>
     1008
     1009                <label class="imgedit-label">
     1010                <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="thumbnail" />
     1011                <?php _e( 'Thumbnail' ); ?></label>
     1012
     1013                <label class="imgedit-label">
     1014                <input type="radio" name="imgedit-target-<?php echo $post_id; ?>" value="nothumb" />
     1015                <?php _e( 'All sizes except thumbnail' ); ?></label>
     1016        </p>
     1017
     1018        <?php
     1019}
     1020
     1021/**
     1022 * Image Editor Group callback for the Restore Image editor group.
     1023 *
     1024 * @param int $post_id Attachment post ID
     1025 * @param array $imgedit_group The image editor group associative array
     1026 * @param type $args Associative array with 'can_restore' as key
     1027 */
     1028function imgedit_group_restore_image( $post_id, $imgedit_group, $args ){
     1029        extract( $args );
     1030        ?>
     1031
     1032        <div class="imgedit-submit">
     1033                <input type="button" onclick="imageEdit.action(<?php echo "$post_id, '$nonce'"; ?>, 'restore')" class="button button-primary" value="<?php esc_attr_e( 'Restore image' ); ?>" <?php echo $can_restore; ?> />
     1034        </div>
     1035
     1036        <?php
     1037}
     1038 No newline at end of file