[ Index ] |
WordPress Cross Reference |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress Image Editor 4 * 5 * @package WordPress 6 * @subpackage Administration 7 */ 8 9 function wp_image_editor($post_id, $msg = false) { 10 $nonce = wp_create_nonce("image_editor-$post_id"); 11 $meta = wp_get_attachment_metadata($post_id); 12 $thumb = image_get_intermediate_size($post_id, 'thumbnail'); 13 $sub_sizes = isset($meta['sizes']) && is_array($meta['sizes']); 14 $note = ''; 15 16 if ( isset( $meta['width'], $meta['height'] ) ) 17 $big = max( $meta['width'], $meta['height'] ); 18 else 19 die( __('Image data does not exist. Please re-upload the image.') ); 20 21 $sizer = $big > 400 ? 400 / $big : 1; 22 23 $backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); 24 $can_restore = false; 25 if ( ! empty( $backup_sizes ) && isset( $backup_sizes['full-orig'], $meta['file'] ) ) 26 $can_restore = $backup_sizes['full-orig']['file'] != basename( $meta['file'] ); 27 28 if ( $msg ) { 29 if ( isset($msg->error) ) 30 $note = "<div class='error'><p>$msg->error</p></div>"; 31 elseif ( isset($msg->msg) ) 32 $note = "<div class='updated'><p>$msg->msg</p></div>"; 33 } 34 35 ?> 36 <div class="imgedit-wrap"> 37 <?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 42 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 } ?> 53 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> 56 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> 61 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; ?>" /> 69 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&_ajax_nonce=<?php echo $nonce; ?>&postid=<?php echo $post_id; ?>&rand=<?php echo rand(1, 99999); ?>" /> 72 </div> 73 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> 79 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'] . '×' . $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; ?>" />×<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> 96 97 <?php if ( $can_restore ) { ?> 98 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.'); 103 104 if ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE ) 105 echo ' '.__('Previously edited copies of the image will not be deleted.'); 106 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> 113 114 <?php } ?> 115 116 </div> 117 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> 131 </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> 192 <?php 193 } 194 195 /** 196 * Streams image in WP_Image_Editor to browser. 197 * Provided for backcompat reasons 198 * 199 * @param WP_Image_Editor $image 200 * @param string $mime_type 201 * @param int $post_id 202 * @return boolean 203 */ 204 function wp_stream_image( $image, $mime_type, $post_id ) { 205 if ( $image instanceof WP_Image_Editor ) { 206 $image = apply_filters('image_editor_save_pre', $image, $post_id); 207 208 if ( is_wp_error( $image->stream( $mime_type ) ) ) 209 return false; 210 211 return true; 212 } else { 213 _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) ); 214 215 $image = apply_filters('image_save_pre', $image, $post_id); 216 217 switch ( $mime_type ) { 218 case 'image/jpeg': 219 header( 'Content-Type: image/jpeg' ); 220 return imagejpeg( $image, null, 90 ); 221 case 'image/png': 222 header( 'Content-Type: image/png' ); 223 return imagepng( $image ); 224 case 'image/gif': 225 header( 'Content-Type: image/gif' ); 226 return imagegif( $image ); 227 default: 228 return false; 229 } 230 } 231 } 232 233 /** 234 * Saves Image to File 235 * 236 * @param string $filename 237 * @param WP_Image_Editor $image 238 * @param string $mime_type 239 * @param int $post_id 240 * @return boolean 241 */ 242 function wp_save_image_file( $filename, $image, $mime_type, $post_id ) { 243 if ( $image instanceof WP_Image_Editor ) { 244 $image = apply_filters('image_editor_save_pre', $image, $post_id); 245 $saved = apply_filters('wp_save_image_editor_file', null, $filename, $image, $mime_type, $post_id); 246 247 if ( null !== $saved ) 248 return $saved; 249 250 return $image->save( $filename, $mime_type ); 251 } else { 252 _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) ); 253 254 $image = apply_filters('image_save_pre', $image, $post_id); 255 $saved = apply_filters('wp_save_image_file', null, $filename, $image, $mime_type, $post_id); 256 257 if ( null !== $saved ) 258 return $saved; 259 260 switch ( $mime_type ) { 261 case 'image/jpeg': 262 /** This filter is documented in wp-includes/class-wp-image-editor.php */ 263 return imagejpeg( $image, $filename, apply_filters( 'jpeg_quality', 90, 'edit_image' ) ); 264 case 'image/png': 265 return imagepng( $image, $filename ); 266 case 'image/gif': 267 return imagegif( $image, $filename ); 268 default: 269 return false; 270 } 271 } 272 } 273 274 function _image_get_preview_ratio($w, $h) { 275 $max = max($w, $h); 276 return $max > 400 ? (400 / $max) : 1; 277 } 278 279 // @TODO: Returns GD resource, but is NOT public 280 function _rotate_image_resource($img, $angle) { 281 _deprecated_function( __FUNCTION__, '3.5', __( 'Use WP_Image_Editor::rotate' ) ); 282 if ( function_exists('imagerotate') ) { 283 $rotated = imagerotate($img, $angle, 0); 284 if ( is_resource($rotated) ) { 285 imagedestroy($img); 286 $img = $rotated; 287 } 288 } 289 return $img; 290 } 291 292 /** 293 * @TODO: Only used within image_edit_apply_changes 294 * and receives/returns GD Resource. 295 * Consider removal. 296 * 297 * @param GD_Resource $img 298 * @param boolean $horz 299 * @param boolean $vert 300 * @return GD_Resource 301 */ 302 function _flip_image_resource($img, $horz, $vert) { 303 _deprecated_function( __FUNCTION__, '3.5', __( 'Use WP_Image_Editor::flip' ) ); 304 $w = imagesx($img); 305 $h = imagesy($img); 306 $dst = wp_imagecreatetruecolor($w, $h); 307 if ( is_resource($dst) ) { 308 $sx = $vert ? ($w - 1) : 0; 309 $sy = $horz ? ($h - 1) : 0; 310 $sw = $vert ? -$w : $w; 311 $sh = $horz ? -$h : $h; 312 313 if ( imagecopyresampled($dst, $img, 0, 0, $sx, $sy, $w, $h, $sw, $sh) ) { 314 imagedestroy($img); 315 $img = $dst; 316 } 317 } 318 return $img; 319 } 320 321 /** 322 * @TODO: Only used within image_edit_apply_changes 323 * and receives/returns GD Resource. 324 * Consider removal. 325 * 326 * @param GD_Resource $img 327 * @param float $x 328 * @param float $y 329 * @param float $w 330 * @param float $h 331 * @return GD_Resource 332 */ 333 function _crop_image_resource($img, $x, $y, $w, $h) { 334 $dst = wp_imagecreatetruecolor($w, $h); 335 if ( is_resource($dst) ) { 336 if ( imagecopy($dst, $img, 0, 0, $x, $y, $w, $h) ) { 337 imagedestroy($img); 338 $img = $dst; 339 } 340 } 341 return $img; 342 } 343 344 /** 345 * Performs group of changes on Editor specified. 346 * 347 * @param WP_Image_Editor $image 348 * @param type $changes 349 * @return WP_Image_Editor 350 */ 351 function image_edit_apply_changes( $image, $changes ) { 352 if ( is_resource( $image ) ) 353 _deprecated_argument( __FUNCTION__, '3.5', __( '$image needs to be an WP_Image_Editor object' ) ); 354 355 if ( !is_array($changes) ) 356 return $image; 357 358 // expand change operations 359 foreach ( $changes as $key => $obj ) { 360 if ( isset($obj->r) ) { 361 $obj->type = 'rotate'; 362 $obj->angle = $obj->r; 363 unset($obj->r); 364 } elseif ( isset($obj->f) ) { 365 $obj->type = 'flip'; 366 $obj->axis = $obj->f; 367 unset($obj->f); 368 } elseif ( isset($obj->c) ) { 369 $obj->type = 'crop'; 370 $obj->sel = $obj->c; 371 unset($obj->c); 372 } 373 $changes[$key] = $obj; 374 } 375 376 // combine operations 377 if ( count($changes) > 1 ) { 378 $filtered = array($changes[0]); 379 for ( $i = 0, $j = 1; $j < count($changes); $j++ ) { 380 $combined = false; 381 if ( $filtered[$i]->type == $changes[$j]->type ) { 382 switch ( $filtered[$i]->type ) { 383 case 'rotate': 384 $filtered[$i]->angle += $changes[$j]->angle; 385 $combined = true; 386 break; 387 case 'flip': 388 $filtered[$i]->axis ^= $changes[$j]->axis; 389 $combined = true; 390 break; 391 } 392 } 393 if ( !$combined ) 394 $filtered[++$i] = $changes[$j]; 395 } 396 $changes = $filtered; 397 unset($filtered); 398 } 399 400 // image resource before applying the changes 401 if ( $image instanceof WP_Image_Editor ) 402 $image = apply_filters('wp_image_editor_before_change', $image, $changes); 403 elseif ( is_resource( $image ) ) 404 $image = apply_filters('image_edit_before_change', $image, $changes); 405 406 foreach ( $changes as $operation ) { 407 switch ( $operation->type ) { 408 case 'rotate': 409 if ( $operation->angle != 0 ) { 410 if ( $image instanceof WP_Image_Editor ) 411 $image->rotate( $operation->angle ); 412 else 413 $image = _rotate_image_resource( $image, $operation->angle ); 414 } 415 break; 416 case 'flip': 417 if ( $operation->axis != 0 ) 418 if ( $image instanceof WP_Image_Editor ) 419 $image->flip( ($operation->axis & 1) != 0, ($operation->axis & 2) != 0 ); 420 else 421 $image = _flip_image_resource( $image, ( $operation->axis & 1 ) != 0, ( $operation->axis & 2 ) != 0 ); 422 break; 423 case 'crop': 424 $sel = $operation->sel; 425 426 if ( $image instanceof WP_Image_Editor ) { 427 $size = $image->get_size(); 428 $w = $size['width']; 429 $h = $size['height']; 430 431 $scale = 1 / _image_get_preview_ratio( $w, $h ); // discard preview scaling 432 $image->crop( $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale ); 433 } else { 434 $scale = 1 / _image_get_preview_ratio( imagesx( $image ), imagesy( $image ) ); // discard preview scaling 435 $image = _crop_image_resource( $image, $sel->x * $scale, $sel->y * $scale, $sel->w * $scale, $sel->h * $scale ); 436 } 437 break; 438 } 439 } 440 441 return $image; 442 } 443 444 445 /** 446 * Streams image in post to browser, along with enqueued changes 447 * in $_REQUEST['history'] 448 * 449 * @param int $post_id 450 * @return boolean 451 */ 452 function stream_preview_image( $post_id ) { 453 $post = get_post( $post_id ); 454 @ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) ); 455 456 $img = wp_get_image_editor( _load_image_to_edit_path( $post_id ) ); 457 458 if ( is_wp_error( $img ) ) 459 return false; 460 461 $changes = !empty($_REQUEST['history']) ? json_decode( wp_unslash($_REQUEST['history']) ) : null; 462 if ( $changes ) 463 $img = image_edit_apply_changes( $img, $changes ); 464 465 // scale the image 466 $size = $img->get_size(); 467 $w = $size['width']; 468 $h = $size['height']; 469 470 $ratio = _image_get_preview_ratio( $w, $h ); 471 $w2 = max ( 1, $w * $ratio ); 472 $h2 = max ( 1, $h * $ratio ); 473 474 if ( is_wp_error( $img->resize( $w2, $h2 ) ) ) 475 return false; 476 477 return wp_stream_image( $img, $post->post_mime_type, $post_id ); 478 } 479 480 function wp_restore_image($post_id) { 481 $meta = wp_get_attachment_metadata($post_id); 482 $file = get_attached_file($post_id); 483 $backup_sizes = get_post_meta( $post_id, '_wp_attachment_backup_sizes', true ); 484 $restored = false; 485 $msg = new stdClass; 486 487 if ( !is_array($backup_sizes) ) { 488 $msg->error = __('Cannot load image metadata.'); 489 return $msg; 490 } 491 492 $parts = pathinfo($file); 493 $suffix = time() . rand(100, 999); 494 $default_sizes = get_intermediate_image_sizes(); 495 496 if ( isset($backup_sizes['full-orig']) && is_array($backup_sizes['full-orig']) ) { 497 $data = $backup_sizes['full-orig']; 498 499 if ( $parts['basename'] != $data['file'] ) { 500 if ( defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE ) { 501 // delete only if it's edited image 502 if ( preg_match('/-e[0-9]{13}\./', $parts['basename']) ) { 503 /** This filter is documented in wp-admin/custom-header.php */ 504 $delpath = apply_filters('wp_delete_file', $file); 505 @unlink($delpath); 506 } 507 } elseif ( isset( $meta['width'], $meta['height'] ) ) { 508 $backup_sizes["full-$suffix"] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $parts['basename']); 509 } 510 } 511 512 $restored_file = path_join($parts['dirname'], $data['file']); 513 $restored = update_attached_file($post_id, $restored_file); 514 515 $meta['file'] = _wp_relative_upload_path( $restored_file ); 516 $meta['width'] = $data['width']; 517 $meta['height'] = $data['height']; 518 } 519 520 foreach ( $default_sizes as $default_size ) { 521 if ( isset($backup_sizes["$default_size-orig"]) ) { 522 $data = $backup_sizes["$default_size-orig"]; 523 if ( isset($meta['sizes'][$default_size]) && $meta['sizes'][$default_size]['file'] != $data['file'] ) { 524 if ( defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE ) { 525 // delete only if it's edited image 526 if ( preg_match('/-e[0-9]{13}-/', $meta['sizes'][$default_size]['file']) ) { 527 /** This filter is documented in wp-admin/custom-header.php */ 528 $delpath = apply_filters( 'wp_delete_file', path_join($parts['dirname'], $meta['sizes'][$default_size]['file']) ); 529 @unlink($delpath); 530 } 531 } else { 532 $backup_sizes["$default_size-{$suffix}"] = $meta['sizes'][$default_size]; 533 } 534 } 535 536 $meta['sizes'][$default_size] = $data; 537 } else { 538 unset($meta['sizes'][$default_size]); 539 } 540 } 541 542 if ( !wp_update_attachment_metadata($post_id, $meta) || !update_post_meta( $post_id, '_wp_attachment_backup_sizes', $backup_sizes) ) { 543 $msg->error = __('Cannot save image metadata.'); 544 return $msg; 545 } 546 547 if ( !$restored ) 548 $msg->error = __('Image metadata is inconsistent.'); 549 else 550 $msg->msg = __('Image restored successfully.'); 551 552 return $msg; 553 } 554 555 /** 556 * Saves image to post along with enqueued changes 557 * in $_REQUEST['history'] 558 * 559 * @param int $post_id 560 * @return \stdClass 561 */ 562 function wp_save_image( $post_id ) { 563 $return = new stdClass; 564 $success = $delete = $scaled = $nocrop = false; 565 $post = get_post( $post_id ); 566 567 $img = wp_get_image_editor( _load_image_to_edit_path( $post_id, 'full' ) ); 568 if ( is_wp_error( $img ) ) { 569 $return->error = esc_js( __('Unable to create new image.') ); 570 return $return; 571 } 572 573 $fwidth = !empty($_REQUEST['fwidth']) ? intval($_REQUEST['fwidth']) : 0; 574 $fheight = !empty($_REQUEST['fheight']) ? intval($_REQUEST['fheight']) : 0; 575 $target = !empty($_REQUEST['target']) ? preg_replace('/[^a-z0-9_-]+/i', '', $_REQUEST['target']) : ''; 576 $scale = !empty($_REQUEST['do']) && 'scale' == $_REQUEST['do']; 577 578 if ( $scale && $fwidth > 0 && $fheight > 0 ) { 579 $size = $img->get_size(); 580 $sX = $size['width']; 581 $sY = $size['height']; 582 583 // check if it has roughly the same w / h ratio 584 $diff = round($sX / $sY, 2) - round($fwidth / $fheight, 2); 585 if ( -0.1 < $diff && $diff < 0.1 ) { 586 // scale the full size image 587 if ( $img->resize( $fwidth, $fheight ) ) 588 $scaled = true; 589 } 590 591 if ( !$scaled ) { 592 $return->error = esc_js( __('Error while saving the scaled image. Please reload the page and try again.') ); 593 return $return; 594 } 595 } elseif ( !empty($_REQUEST['history']) ) { 596 $changes = json_decode( wp_unslash($_REQUEST['history']) ); 597 if ( $changes ) 598 $img = image_edit_apply_changes($img, $changes); 599 } else { 600 $return->error = esc_js( __('Nothing to save, the image has not changed.') ); 601 return $return; 602 } 603 604 $meta = wp_get_attachment_metadata($post_id); 605 $backup_sizes = get_post_meta( $post->ID, '_wp_attachment_backup_sizes', true ); 606 607 if ( !is_array($meta) ) { 608 $return->error = esc_js( __('Image data does not exist. Please re-upload the image.') ); 609 return $return; 610 } 611 612 if ( !is_array($backup_sizes) ) 613 $backup_sizes = array(); 614 615 // generate new filename 616 $path = get_attached_file($post_id); 617 $path_parts = pathinfo( $path ); 618 $filename = $path_parts['filename']; 619 $suffix = time() . rand(100, 999); 620 621 if ( defined('IMAGE_EDIT_OVERWRITE') && IMAGE_EDIT_OVERWRITE && 622 isset($backup_sizes['full-orig']) && $backup_sizes['full-orig']['file'] != $path_parts['basename'] ) { 623 624 if ( 'thumbnail' == $target ) 625 $new_path = "{$path_parts['dirname']}/{$filename}-temp.{$path_parts['extension']}"; 626 else 627 $new_path = $path; 628 } else { 629 while( true ) { 630 $filename = preg_replace( '/-e([0-9]+)$/', '', $filename ); 631 $filename .= "-e{$suffix}"; 632 $new_filename = "{$filename}.{$path_parts['extension']}"; 633 $new_path = "{$path_parts['dirname']}/$new_filename"; 634 if ( file_exists($new_path) ) 635 $suffix++; 636 else 637 break; 638 } 639 } 640 641 // save the full-size file, also needed to create sub-sizes 642 if ( !wp_save_image_file($new_path, $img, $post->post_mime_type, $post_id) ) { 643 $return->error = esc_js( __('Unable to save the image.') ); 644 return $return; 645 } 646 647 if ( 'nothumb' == $target || 'all' == $target || 'full' == $target || $scaled ) { 648 $tag = false; 649 if ( isset($backup_sizes['full-orig']) ) { 650 if ( ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE ) && $backup_sizes['full-orig']['file'] != $path_parts['basename'] ) 651 $tag = "full-$suffix"; 652 } else { 653 $tag = 'full-orig'; 654 } 655 656 if ( $tag ) 657 $backup_sizes[$tag] = array('width' => $meta['width'], 'height' => $meta['height'], 'file' => $path_parts['basename']); 658 659 $success = update_attached_file( $post_id, $new_path ); 660 661 $meta['file'] = _wp_relative_upload_path( $new_path ); 662 663 $size = $img->get_size(); 664 $meta['width'] = $size['width']; 665 $meta['height'] = $size['height']; 666 667 if ( $success && ('nothumb' == $target || 'all' == $target) ) { 668 $sizes = get_intermediate_image_sizes(); 669 if ( 'nothumb' == $target ) 670 $sizes = array_diff( $sizes, array('thumbnail') ); 671 } 672 673 $return->fw = $meta['width']; 674 $return->fh = $meta['height']; 675 } elseif ( 'thumbnail' == $target ) { 676 $sizes = array( 'thumbnail' ); 677 $success = $delete = $nocrop = true; 678 } 679 680 if ( isset( $sizes ) ) { 681 $_sizes = array(); 682 683 foreach ( $sizes as $size ) { 684 $tag = false; 685 if ( isset( $meta['sizes'][$size] ) ) { 686 if ( isset($backup_sizes["$size-orig"]) ) { 687 if ( ( !defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE ) && $backup_sizes["$size-orig"]['file'] != $meta['sizes'][$size]['file'] ) 688 $tag = "$size-$suffix"; 689 } else { 690 $tag = "$size-orig"; 691 } 692 693 if ( $tag ) 694 $backup_sizes[$tag] = $meta['sizes'][$size]; 695 } 696 697 $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 ); 699 } 700 701 $meta['sizes'] = array_merge( $meta['sizes'], $img->multi_resize( $_sizes ) ); 702 } 703 704 unset( $img ); 705 706 if ( $success ) { 707 wp_update_attachment_metadata( $post_id, $meta ); 708 update_post_meta( $post_id, '_wp_attachment_backup_sizes', $backup_sizes); 709 710 if ( $target == 'thumbnail' || $target == 'all' || $target == 'full' ) { 711 // Check if it's an image edit from attachment edit screen 712 if ( ! empty( $_REQUEST['context'] ) && 'edit-attachment' == $_REQUEST['context'] ) { 713 $thumb_url = wp_get_attachment_image_src( $post_id, array( 900, 600 ), true ); 714 $return->thumbnail = $thumb_url[0]; 715 } else { 716 $file_url = wp_get_attachment_url($post_id); 717 if ( $thumb = $meta['sizes']['thumbnail'] ) 718 $return->thumbnail = path_join( dirname($file_url), $thumb['file'] ); 719 else 720 $return->thumbnail = "$file_url?w=128&h=128"; 721 } 722 } 723 } else { 724 $delete = true; 725 } 726 727 if ( $delete ) { 728 /** This filter is documented in wp-admin/custom-header.php */ 729 $delpath = apply_filters('wp_delete_file', $new_path); 730 @unlink( $delpath ); 731 } 732 733 $return->msg = esc_js( __('Image saved') ); 734 return $return; 735 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Mar 25 01:41:18 2014 | WordPress honlapkészítés: online1.hu |