[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-admin/includes/ -> image-edit.php (source)

   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&amp;_ajax_nonce=<?php echo $nonce; ?>&amp;postid=<?php echo $post_id; ?>&amp;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'] . '&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>
  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  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu