Wordpress 3.5
[autoinstalls/wordpress.git] / wp-admin / includes / image-edit.php
index d2d6dc2cf30f411a6dd977fdf107fb6aa11b852a..3e3b180267c32f08ca85bf1c32af53687fc6ae35 100644 (file)
@@ -40,14 +40,14 @@ function wp_image_editor($post_id, $msg = false) {
                <div onclick="imageEdit.crop(<?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-crop disabled" title="<?php esc_attr_e( 'Crop' ); ?>"></div><?php
 
        // On some setups GD library does not provide imagerotate() - Ticket #11536
-       if ( function_exists('imagerotate') ) { ?>
+       if ( wp_image_editor_supports( array( 'mime_type' => get_post_mime_type( $post_id ), 'methods' => array( 'rotate' ) ) ) ) { ?>
                <div class="imgedit-rleft"  onclick="imageEdit.rotate( 90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate counter-clockwise' ); ?>"></div>
                <div class="imgedit-rright" onclick="imageEdit.rotate(-90, <?php echo "$post_id, '$nonce'"; ?>, this)" title="<?php esc_attr_e( 'Rotate clockwise' ); ?>"></div>
 <?php } else {
-               $note_gdlib = esc_attr__('Image rotation is not supported by your web host (function imagerotate() is missing)');
+               $note_no_rotate = esc_attr__('Image rotation is not supported by your web host.');
 ?>
-           <div class="imgedit-rleft disabled"  title="<?php echo $note_gdlib; ?>"></div>
-           <div class="imgedit-rright disabled" title="<?php echo $note_gdlib; ?>"></div>
+           <div class="imgedit-rleft disabled"  title="<?php echo $note_no_rotate; ?>"></div>
+           <div class="imgedit-rright disabled" title="<?php echo $note_no_rotate; ?>"></div>
 <?php } ?>
 
                <div onclick="imageEdit.flip(1, <?php echo "$post_id, '$nonce'"; ?>, this)" class="imgedit-flipv" title="<?php esc_attr_e( 'Flip vertically' ); ?>"></div>
@@ -118,14 +118,6 @@ function wp_image_editor($post_id, $msg = false) {
                <a class="imgedit-help-toggle" onclick="imageEdit.toggleHelp(this);return false;" href="#"><?php _e('(help)'); ?></a>
                <div class="imgedit-help">
                <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>
-               <strong><?php _e('Keyboard Shortcuts'); ?></strong>
-               <ul>
-               <li><?php _e('Arrow: move by 10px'); ?></li>
-               <li><?php _e('Shift + arrow: move by 1px'); ?></li>
-               <li><?php _e('Ctrl + arrow: resize by 10px'); ?></li>
-               <li><?php _e('Ctrl + Shift + arrow: resize by 1px'); ?></li>
-               <li><?php _e('Shift + drag: lock aspect ratio'); ?></li>
-               </ul>
 
                <p><strong><?php _e('Crop Aspect Ratio'); ?></strong><br />
                <?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>
@@ -191,45 +183,87 @@ function wp_image_editor($post_id, $msg = false) {
        </td></tr>
        </tbody></table>
        <div class="imgedit-wait" id="imgedit-wait-<?php echo $post_id; ?>"></div>
-       <script type="text/javascript">imageEdit.init(<?php echo $post_id; ?>);</script>
+       <script type="text/javascript">jQuery( function() { imageEdit.init(<?php echo $post_id; ?>); });</script>
        <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>
        </div>
 <?php
 }
 
-function wp_stream_image($image, $mime_type, $post_id) {
-       $image = apply_filters('image_save_pre', $image, $post_id);
-
-       switch ( $mime_type ) {
-               case 'image/jpeg':
-                       header('Content-Type: image/jpeg');
-                       return imagejpeg($image, null, 90);
-               case 'image/png':
-                       header('Content-Type: image/png');
-                       return imagepng($image);
-               case 'image/gif':
-                       header('Content-Type: image/gif');
-                       return imagegif($image);
-               default:
+/**
+ * Streams image in WP_Image_Editor to browser.
+ * Provided for backcompat reasons
+ *
+ * @param WP_Image_Editor $image
+ * @param string $mime_type
+ * @param int $post_id
+ * @return boolean
+ */
+function wp_stream_image( $image, $mime_type, $post_id ) {
+       if ( $image instanceof WP_Image_Editor ) {
+               $image = apply_filters('image_editor_save_pre', $image, $post_id);
+
+               if ( is_wp_error( $image->stream( $mime_type ) ) )
                        return false;
+
+               return true;
+       } else {
+               _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) );
+
+               $image = apply_filters('image_save_pre', $image, $post_id);
+
+               switch ( $mime_type ) {
+                       case 'image/jpeg':
+                               header( 'Content-Type: image/jpeg' );
+                               return imagejpeg( $image, null, 90 );
+                       case 'image/png':
+                               header( 'Content-Type: image/png' );
+                               return imagepng( $image );
+                       case 'image/gif':
+                               header( 'Content-Type: image/gif' );
+                               return imagegif( $image );
+                       default:
+                               return false;
+               }
        }
 }
 
-function wp_save_image_file($filename, $image, $mime_type, $post_id) {
-       $image = apply_filters('image_save_pre', $image, $post_id);
-       $saved = apply_filters('wp_save_image_file', null, $filename, $image, $mime_type, $post_id);
-       if ( null !== $saved )
-               return $saved;
-
-       switch ( $mime_type ) {
-               case 'image/jpeg':
-                       return imagejpeg( $image, $filename, apply_filters( 'jpeg_quality', 90, 'edit_image' ) );
-               case 'image/png':
-                       return imagepng($image, $filename);
-               case 'image/gif':
-                       return imagegif($image, $filename);
-               default:
-                       return false;
+/**
+ * Saves Image to File
+ *
+ * @param string $filename
+ * @param WP_Image_Editor $image
+ * @param string $mime_type
+ * @param int $post_id
+ * @return boolean
+ */
+function wp_save_image_file( $filename, $image, $mime_type, $post_id ) {
+       if ( $image instanceof WP_Image_Editor ) {
+               $image = apply_filters('image_editor_save_pre', $image, $post_id);
+               $saved = apply_filters('wp_save_image_editor_file', null, $filename, $image, $mime_type, $post_id);
+
+               if ( null !== $saved )
+                       return $saved;
+
+               return $image->save( $filename, $mime_type );
+       } else {
+               _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) );
+
+               $image = apply_filters('image_save_pre', $image, $post_id);
+               $saved = apply_filters('wp_save_image_file', null, $filename, $image, $mime_type, $post_id);
+
+               if ( null !== $saved )
+                       return $saved;
+
+               switch ( $mime_type ) {
+                       case 'image/jpeg':
+                               return imagejpeg( $image, $filename, apply_filters( 'jpeg_quality', 90, 'edit_image' ) );
+                       case 'image/png':
+                               return imagepng( $image, $filename );
+                       case 'image/gif':
+                               return imagegif( $image, $filename );
+                       default:
+                               return false;
+               }
        }
 }
 
@@ -238,7 +272,9 @@ function _image_get_preview_ratio($w, $h) {
        return $max > 400 ? (400 / $max) : 1;
 }
 
+// @TODO: Returns GD resource, but is NOT public
 function _rotate_image_resource($img, $angle) {
+       _deprecated_function( __FUNCTION__, '3.5', __( 'Use WP_Image_Editor::rotate' ) );
        if ( function_exists('imagerotate') ) {
                $rotated = imagerotate($img, $angle, 0);
                if ( is_resource($rotated) ) {
@@ -249,7 +285,18 @@ function _rotate_image_resource($img, $angle) {
        return $img;
 }
 
+/**
+ * @TODO: Only used within image_edit_apply_changes
+ *               and receives/returns GD Resource.
+ *               Consider removal.
+ *
+ * @param GD_Resource $img
+ * @param boolean $horz
+ * @param boolean $vert
+ * @return GD_Resource
+ */
 function _flip_image_resource($img, $horz, $vert) {
+       _deprecated_function( __FUNCTION__, '3.5', __( 'Use WP_Image_Editor::flip' ) );
        $w = imagesx($img);
        $h = imagesy($img);
        $dst = wp_imagecreatetruecolor($w, $h);
@@ -267,6 +314,18 @@ function _flip_image_resource($img, $horz, $vert) {
        return $img;
 }
 
+/**
+ * @TODO: Only used within image_edit_apply_changes
+ *               and receives/returns GD Resource.
+ *               Consider removal.
+ *
+ * @param GD_Resource $img
+ * @param float $x
+ * @param float $y
+ * @param float $w
+ * @param float $h
+ * @return GD_Resource
+ */
 function _crop_image_resource($img, $x, $y, $w, $h) {
        $dst = wp_imagecreatetruecolor($w, $h);
        if ( is_resource($dst) ) {
@@ -278,10 +337,19 @@ function _crop_image_resource($img, $x, $y, $w, $h) {
        return $img;
 }
 
-function image_edit_apply_changes($img, $changes) {
+/**
+ * Performs group of changes on Editor specified.
+ *
+ * @param WP_Image_Editor $image
+ * @param type $changes
+ * @return WP_Image_Editor
+ */
+function image_edit_apply_changes( $image, $changes ) {
+       if ( is_resource( $image ) )
+               _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) );
 
        if ( !is_array($changes) )
-               return $img;
+               return $image;
 
        // expand change operations
        foreach ( $changes as $key => $obj ) {
@@ -326,55 +394,83 @@ function image_edit_apply_changes($img, $changes) {
        }
 
        // image resource before applying the changes
-       $img = apply_filters('image_edit_before_change', $img, $changes);
+       if ( $image instanceof WP_Image_Editor )
+               $image = apply_filters('wp_image_editor_before_change', $image, $changes);
+       elseif ( is_resource( $image ) )
+               $image = apply_filters('image_edit_before_change', $image, $changes);
 
        foreach ( $changes as $operation ) {
                switch ( $operation->type ) {
                        case 'rotate':
-                               if ( $operation->angle != 0 )
-                                       $img = _rotate_image_resource($img, $operation->angle);
+                               if ( $operation->angle != 0 ) {
+                                       if ( $image instanceof WP_Image_Editor )
+                                               $image->rotate( $operation->angle );
+                                       else
+                                               $image = _rotate_image_resource( $image, $operation->angle );
+                               }
                                break;
                        case 'flip':
                                if ( $operation->axis != 0 )
-                                       $img = _flip_image_resource($img, ($operation->axis & 1) != 0, ($operation->axis & 2) != 0);
+                                       if ( $image instanceof WP_Image_Editor )
+                                               $image->flip( ($operation->axis & 1) != 0, ($operation->axis & 2) != 0 );
+                                       else
+                                               $image = _flip_image_resource( $image, ( $operation->axis & 1 ) != 0, ( $operation->axis & 2 ) != 0 );
                                break;
                        case 'crop':
                                $sel = $operation->sel;
-                               $scale = 1 / _image_get_preview_ratio( imagesx($img), imagesy($img) ); // discard preview scaling
-                               $img = _crop_image_resource($img, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale);
+
+                               if ( $image instanceof WP_Image_Editor ) {
+                                       $size = $image->get_size();
+                                       $w = $size['width'];
+                                       $h = $size['height'];
+
+                                       $scale = 1 / _image_get_preview_ratio( $w, $h ); // discard preview scaling
+                                       $image->crop( $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale );
+                               } else {
+                                       $scale = 1 / _image_get_preview_ratio( imagesx( $image ), imagesy( $image ) ); // discard preview scaling
+                                       $image = _crop_image_resource( $image, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale );
+                               }
                                break;
                }
        }
 
-       return $img;
+       return $image;
 }
 
-function stream_preview_image($post_id) {
-       $post = get_post($post_id);
+
+/**
+ * Streams image in post to browser, along with enqueued changes
+ * in $_REQUEST['history']
+ *
+ * @param int $post_id
+ * @return boolean
+ */
+function stream_preview_image( $post_id ) {
+       $post = get_post( $post_id );
        @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
-       $img = load_image_to_edit( $post_id, $post->post_mime_type, array(400, 400) );
 
-       if ( !is_resource($img) )
-               return false;
+       $img = wp_get_image_editor( _load_image_to_edit_path( $post_id ) );
+
+    if ( is_wp_error( $img ) )
+        return false;
 
        $changes = !empty($_REQUEST['history']) ? json_decode( stripslashes($_REQUEST['history']) ) : null;
        if ( $changes )
-               $img = image_edit_apply_changes($img, $changes);
+               $img = image_edit_apply_changes( $img, $changes );
 
        // scale the image
-       $w = imagesx($img);
-       $h = imagesy($img);
-       $ratio = _image_get_preview_ratio($w, $h);
+       $size = $img->get_size();
+       $w = $size['width'];
+       $h = $size['height'];
+
+       $ratio = _image_get_preview_ratio( $w, $h );
        $w2 = $w * $ratio;
        $h2 = $h * $ratio;
 
-       $preview = wp_imagecreatetruecolor($w2, $h2);
-       imagecopyresampled( $preview, $img, 0, 0, 0, 0, $w2, $h2, $w, $h );
-       wp_stream_image($preview, $post->post_mime_type, $post_id);
+       if ( is_wp_error( $img->resize( $w2, $h2 ) ) )
+               return false;
 
-       imagedestroy($preview);
-       imagedestroy($img);
-       return true;
+       return wp_stream_image( $img, $post->post_mime_type, $post_id );
 }
 
 function wp_restore_image($post_id) {
@@ -414,8 +510,6 @@ function wp_restore_image($post_id) {
                $meta['file'] = _wp_relative_upload_path( $restored_file );
                $meta['width'] = $data['width'];
                $meta['height'] = $data['height'];
-               list ( $uwidth, $uheight ) = wp_constrain_dimensions($meta['width'], $meta['height'], 128, 96);
-               $meta['hwstring_small'] = "height='$uheight' width='$uwidth'";
        }
 
        foreach ( $default_sizes as $default_size ) {
@@ -452,14 +546,20 @@ function wp_restore_image($post_id) {
        return $msg;
 }
 
-function wp_save_image($post_id) {
+/**
+ * Saves image to post along with enqueued changes
+ * in $_REQUEST['history']
+ *
+ * @param int $post_id
+ * @return \stdClass
+ */
+function wp_save_image( $post_id ) {
        $return = new stdClass;
        $success = $delete = $scaled = $nocrop = false;
-       $post = get_post($post_id);
-       @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
-       $img = load_image_to_edit($post_id, $post->post_mime_type);
+       $post = get_post( $post_id );
 
-       if ( !is_resource($img) ) {
+       $img = wp_get_image_editor( _load_image_to_edit_path( $post_id, 'full' ) );
+       if ( is_wp_error( $img ) ) {
                $return->error = esc_js( __('Unable to create new image.') );
                return $return;
        }
@@ -470,19 +570,16 @@ function wp_save_image($post_id) {
        $scale = !empty($_REQUEST['do']) && 'scale' == $_REQUEST['do'];
 
        if ( $scale && $fwidth > 0 && $fheight > 0 ) {
-               $sX = imagesx($img);
-               $sY = imagesy($img);
+               $size = $img->get_size();
+               $sX = $size['width'];
+               $sY = $size['height'];
 
                // check if it has roughly the same w / h ratio
                $diff = round($sX / $sY, 2) - round($fwidth / $fheight, 2);
                if ( -0.1 < $diff && $diff < 0.1 ) {
                        // scale the full size image
-                       $dst = wp_imagecreatetruecolor($fwidth, $fheight);
-                       if ( imagecopyresampled( $dst, $img, 0, 0, 0, 0, $fwidth, $fheight, $sX, $sY ) ) {
-                               imagedestroy($img);
-                               $img = $dst;
+                       if ( $img->resize( $fwidth, $fheight ) )
                                $scaled = true;
-                       }
                }
 
                if ( !$scaled ) {
@@ -553,14 +650,13 @@ function wp_save_image($post_id) {
                if ( $tag )
                        $backup_sizes[$tag] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $path_parts['basename']);
 
-               $success = update_attached_file($post_id, $new_path);
+               $success = update_attached_file( $post_id, $new_path );
 
-               $meta['file'] = _wp_relative_upload_path($new_path);
-               $meta['width'] = imagesx($img);
-               $meta['height'] = imagesy($img);
+               $meta['file'] = _wp_relative_upload_path( $new_path );
 
-               list ( $uwidth, $uheight ) = wp_constrain_dimensions($meta['width'], $meta['height'], 128, 96);
-               $meta['hwstring_small'] = "height='$uheight' width='$uwidth'";
+               $size = $img->get_size();
+               $meta['width'] = $size['width'];
+               $meta['height'] = $size['height'];
 
                if ( $success && ('nothumb' == $target || 'all' == $target) ) {
                        $sizes = get_intermediate_image_sizes();
@@ -575,10 +671,12 @@ function wp_save_image($post_id) {
                $success = $delete = $nocrop = true;
        }
 
-       if ( isset($sizes) ) {
+       if ( isset( $sizes ) ) {
+               $_sizes = array();
+
                foreach ( $sizes as $size ) {
                        $tag = false;
-                       if ( isset($meta['sizes'][$size]) ) {
+                       if ( isset( $meta['sizes'][$size] ) ) {
                                if ( isset($backup_sizes["$size-orig"]) ) {
                                        if ( ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE ) && $backup_sizes["$size-orig"]['file'] != $meta['sizes'][$size]['file'] )
                                                $tag = "$size-$suffix";
@@ -591,25 +689,30 @@ function wp_save_image($post_id) {
                        }
 
                        $crop = $nocrop ? false : get_option("{$size}_crop");
-                       $resized = image_make_intermediate_size($new_path, get_option("{$size}_size_w"), get_option("{$size}_size_h"), $crop );
-
-                       if ( $resized )
-                               $meta['sizes'][$size] = $resized;
-                       else
-                               unset($meta['sizes'][$size]);
+                       $_sizes[ $size ] = array( 'width' => get_option("{$size}_size_w"), 'height' => get_option("{$size}_size_h"), 'crop' => $crop );
                }
+
+               $meta['sizes'] = $img->multi_resize( $_sizes );
        }
 
+       unset( $img );
+
        if ( $success ) {
-               wp_update_attachment_metadata($post_id, $meta);
+               wp_update_attachment_metadata( $post_id, $meta );
                update_post_meta( $post_id, '_wp_attachment_backup_sizes', $backup_sizes);
 
                if ( $target == 'thumbnail' || $target == 'all' || $target == 'full' ) {
-                       $file_url = wp_get_attachment_url($post_id);
-                       if ( $thumb = $meta['sizes']['thumbnail'] )
-                               $return->thumbnail = path_join( dirname($file_url), $thumb['file'] );
-                       else
-                               $return->thumbnail = "$file_url?w=128&h=128";
+                       // Check if it's an image edit from attachment edit screen
+                       if ( ! empty( $_REQUEST['context'] ) && 'edit-attachment' == $_REQUEST['context'] ) {
+                               $thumb_url = wp_get_attachment_image_src( $post_id, array( 900, 600 ), true );
+                               $return->thumbnail = $thumb_url[0];
+                       } else {
+                               $file_url = wp_get_attachment_url($post_id);
+                               if ( $thumb = $meta['sizes']['thumbnail'] )
+                                       $return->thumbnail = path_join( dirname($file_url), $thumb['file'] );
+                               else
+                                       $return->thumbnail = "$file_url?w=128&h=128";
+                       }
                }
        } else {
                $delete = true;
@@ -617,11 +720,9 @@ function wp_save_image($post_id) {
 
        if ( $delete ) {
                $delpath = apply_filters('wp_delete_file', $new_path);
-               @unlink($delpath);
+               @unlink( $delpath );
        }
 
-       imagedestroy($img);
-
        $return->msg = esc_js( __('Image saved') );
        return $return;
 }