Ticket #40439: 40439.patch
File 40439.patch, 21.1 KB (added by , 6 years ago) |
---|
-
src/js/_enqueues/admin/media.js
204 204 $( this ).find( '.found-radio input' ).prop( 'checked', true ); 205 205 }); 206 206 }); 207 208 /** 209 * Handle request to create missing image sizes. 210 */ 211 $( document ).ready( function() { 212 $( document ).on( 'click.wp-update-image-sizes', function( event ) { 213 const $target = $( event.target ); 214 215 if ( $target.is( 'button.wp-update-image-sizes' ) ) { 216 var $parent = $target.parent(); 217 var $message = $parent.find( 'span.message' ); 218 var $spinner = $parent.find( 'span.spinner' ); 219 220 $spinner.addClass( 'is-active' ); 221 222 $.ajax({ 223 type: 'post', 224 url: window.ajaxurl, 225 dataType: 'json', 226 data: { 227 action: 'wp-update-image-sizes', 228 update_sizes_nonce: $target.attr( 'data-wp-nonce' ), 229 attachment_id: $target.attr( 'data-wp-attachment-id' ), 230 } 231 }).always( function() { 232 $spinner.removeClass( 'is-active' ); 233 }).done( function( response ) { 234 if ( response.data && response.data.message ) { 235 $message.text( response.data.message ); 236 } 237 }).fail( function() { 238 $message.text( attachMediaBoxL10n.error ); 239 }); 240 } 241 } ); 242 } ); 207 243 })( jQuery ); -
src/wp-admin/admin-ajax.php
131 131 'edit-theme-plugin-file', 132 132 'wp-privacy-export-personal-data', 133 133 'wp-privacy-erase-personal-data', 134 'wp-update-image-sizes', 134 135 ); 135 136 136 137 // Deprecated -
src/wp-admin/css/list-tables.css
360 360 vertical-align: top; /* Remove descender white-space. */ 361 361 } 362 362 363 table.media .column-title .has-media-icon ~ .row-actions { 363 table.media .column-title .has-media-icon ~ .row-actions, 364 table.media .column-title .has-media-icon ~ .update-image-sizes { 364 365 margin-left: 70px; /* 60px image + margin */ 365 366 } 366 367 … … 368 369 margin-bottom: 0.2em; 369 370 } 370 371 372 table.media .update-image-sizes .spinner { 373 float: none; 374 margin: 2px 10px; 375 } 376 371 377 /* @todo: pick a consistent list table selector */ 372 378 .wp-list-table a { 373 379 transition: none; -
src/wp-admin/includes/ajax-actions.php
4726 4726 4727 4727 wp_send_json_success( $response ); 4728 4728 } 4729 4730 /** 4731 * Ajax handler for updating image sizes. 4732 * 4733 * @since 5.0.0 4734 */ 4735 function wp_ajax_wp_update_image_sizes() { 4736 if ( empty( $_POST['attachment_id'] ) ) { 4737 wp_send_json_error( __( 'Missing attachment ID.' ) ); 4738 } 4739 4740 $attachment_id = (int) $_POST['attachment_id']; 4741 4742 if ( ! current_user_can( 'edit_post', $attachment_id ) || ! wp_verify_nonce( $_POST['update_sizes_nonce'], 'update_image_sizes' . $attachment_id ) ) { 4743 wp_send_json_error( __( 'Invalid request.' ) ); 4744 } 4745 4746 $result = wp_update_image_attachment_sizes( $attachment_id ); 4747 4748 if ( false === $result ) { 4749 $response = array( 'message' => __( 'New image sub-sizes were not created. All sub-sizes already exist.' ) ); 4750 } else { 4751 $count = count( $result ); 4752 $response = array( 'message' => sprintf( _n( 'Created %d image sub-size.', 'Created %d image sub-sizes.', $count ), $count ) ); 4753 } 4754 4755 wp_send_json_success( $response ); 4756 } -
src/wp-admin/includes/class-wp-media-list-table.php
411 411 ?> 412 412 </p> 413 413 <?php 414 $missing_sizes = wp_check_image_attachment_sizes( $post->ID ); 415 416 if ( ! empty( $missing_sizes ) ) { 417 $nonce = wp_create_nonce( 'update_image_sizes' . $post->ID ); 418 $count = count( $missing_sizes ); 419 420 ?> 421 <p class="update-image-sizes"> 422 <span class="message"> 423 <?php printf( _n( '%s image sub-size file is missing.', '%s image sub-size files are missing.', $count ), $count ); ?> 424 </span> 425 <button type="button" class="button button-small wp-update-image-sizes" data-wp-nonce="<?php echo $nonce; ?>" data-wp-attachment-id="<?php echo $post->ID; ?>"> 426 <?php _e( 'Refresh image sizes' ); ?> 427 </button> 428 <span class="spinner"></span> 429 </p> 430 <?php 431 } 414 432 } 415 433 416 434 /** -
src/wp-admin/includes/image.php
66 66 return $dst_file; 67 67 } 68 68 69 function wp_check_image_attachment_sizes( $attachment_id ) { 70 if ( ! wp_attachment_is_image( $attachment_id ) ) { 71 return false; 72 } 73 74 $image_meta = wp_get_attachment_metadata( $attachment_id ); 75 $defined_sizes = _wp_get_intermediate_image_sizes_with_data(); 76 77 // Skip sizes that are too large. 78 foreach ( $defined_sizes as $size_name => $size_data ) { 79 $width = ! empty( $size_data['width'] ) ? (int) $size_data['width'] : 0; 80 $height = ! empty( $size_data['height'] ) ? (int) $size_data['height'] : 0; 81 82 if ( $width && $height ) { 83 if ( $width > $image_meta['width'] && $height > $image_meta['height'] ) { 84 unset( $defined_sizes[ $size_name ] ); 85 } 86 } elseif ( ! $width ) { 87 if ( $height > $image_meta['height'] ) { 88 unset( $defined_sizes[ $size_name ] ); 89 } 90 } elseif ( ! $height ) { 91 if ( $width > $image_meta['width'] ) { 92 unset( $defined_sizes[ $size_name ] ); 93 } 94 } 95 } 96 97 if ( empty( $image_meta['sizes'] ) ) { 98 $image_meta['sizes'] = array(); 99 } 100 101 $missing_sizes = array_diff( array_keys( $defined_sizes ), array_keys( $image_meta['sizes'] ) ); 102 103 /** 104 * Filters the missing image size files per attachment. 105 * 106 * @since 5.0.0 107 * 108 * @param array $missing_sizes Array with the missing image sizes. 109 * @param array $image_meta The image attachment meta data. 110 * @param string $attachment_id The attachment post ID. 111 */ 112 return apply_filters( 'wp_check_image_attachment_sizes', $missing_sizes, $image_meta, $attachment_id ); 113 } 114 69 115 /** 70 * Generate post thumbnail attachment meta data. 116 * For an image attachment, if any of the currently defined image sub-sizes are missing, 117 * creates them and updates the image meta data. 71 118 * 119 * @since 5.0 120 * 121 * @param int $attachment_id The image attachment post ID. 122 * @return bool Whether any sizes were added. 123 */ 124 function wp_update_image_attachment_sizes( $attachment_id ) { 125 $missing_sizes = wp_check_image_attachment_sizes( $attachment_id ); 126 127 if ( ! empty( $missing_sizes ) ) { 128 $file = get_attached_file( $attachment_id ); 129 $image_meta = wp_get_attachment_metadata( $attachment_id ); 130 $new_meta = _wp_create_image_subsizes( $file, $image_meta, $attachment_id ); 131 132 $updated_sizes = array_diff_assoc( $new_meta['sizes'], $image_meta['sizes'] ); 133 134 if ( ! empty( $updated_sizes ) ) { 135 return $updated_sizes; 136 } 137 } 138 139 return false; 140 } 141 142 function _wp_get_intermediate_image_sizes_with_data() { 143 $_wp_additional_image_sizes = wp_get_additional_image_sizes(); 144 $sizes = array(); 145 146 foreach ( get_intermediate_image_sizes() as $size ) { 147 $size_data = array( 148 'width' => '', 149 'height' => '', 150 'crop' => false, 151 ); 152 153 if ( isset( $_wp_additional_image_sizes[ $size ]['width'] ) ) { 154 // For theme-added sizes 155 $size_data['width'] = intval( $_wp_additional_image_sizes[ $size ]['width'] ); 156 } else { 157 // For default sizes set in options 158 $size_data['width'] = get_option( "{$size}_size_w" ); 159 } 160 161 if ( isset( $_wp_additional_image_sizes[ $size ]['height'] ) ) { 162 // For theme-added sizes 163 $size_data['height'] = intval( $_wp_additional_image_sizes[ $size ]['height'] ); 164 } else { 165 // For default sizes set in options 166 $size_data['height'] = get_option( "{$size}_size_h" ); 167 } 168 169 if ( isset( $_wp_additional_image_sizes[ $size ]['crop'] ) ) { 170 // For theme-added sizes 171 $size_data['crop'] = $_wp_additional_image_sizes[ $size ]['crop']; 172 } else { 173 // For default sizes set in options 174 $size_data['crop'] = get_option( "{$size}_crop" ); 175 } 176 177 if ( empty( $size_data['width'] ) && empty( $size_data['height'] ) ) { 178 continue; 179 } 180 181 $sizes[ $size ] = $size_data; 182 } 183 184 return $sizes; 185 } 186 187 /** 188 * Create image sub-sizes and add the related data to the image meta `sizes` array. 189 * 190 * Saves/updates the image meta after each sub-size is created. 191 * 192 * @since 5.0 193 * 194 * @param string $file Full filepath of the attached image. 195 * @param array $image_meta The attachment meta data. 196 * @param int $attachment_id Attachment Id to process. 197 * @return array The attachment meta data with updated `sizes` array. 198 */ 199 function _wp_create_image_subsizes( $file, $image_meta, $attachment_id ) { 200 $new_sizes = _wp_get_intermediate_image_sizes_with_data(); 201 /** 202 * Filters the image sizes automatically generated when uploading an image. 203 * 204 * @since 2.9.0 205 * @since 4.4.0 Added the `$metadata` argument. 206 * @since 5.0.0 Added the `$attachment_id` argument. 207 * 208 * @param array $sizes An associative array of image sizes. 209 * @param array $metadata An associative array of image metadata: width, height, file. 210 * @param int $attachment_id Current attachment ID. 211 */ 212 $new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id ); 213 214 // Check if any of the sizes already exist. 215 if ( ! empty( $image_meta['sizes'] ) && is_array( $image_meta['sizes'] ) ) { 216 foreach ( $image_meta['sizes'] as $size_name => $size_data ) { 217 if ( array_key_exists( $size_name, $new_sizes ) ) { 218 // Can check here if file exists..? 219 unset( $new_sizes[ $size_name ] ); 220 } else { 221 // Make sure we are not adding the exact same file under different "size name". 222 foreach ( $new_sizes as $new_size_name => $new_size_data ) { 223 if ( $size_data['width'] === $new_size_data['width'] || $size_data['height'] === $new_size_data['height'] ) { 224 // $new_size_data['width'] or $new_size_data['height'] may be empty (meaning the new image size has either max-width or max-height), 225 // or they may be set to max-width and max-height like the default "large" size (1024px width and 1024px height). 226 $check = wp_constrain_dimensions( $size_data['width'], $size_data['height'], $new_size_data['width'], $new_size_data['height'] ); 227 228 if ( $check[0] === $size_data['width'] && $check[1] === $size_data['height'] ) { 229 unset( $new_sizes[ $new_size_name ] ); 230 } 231 } 232 } 233 } 234 } 235 } 236 237 if ( ! empty( $new_sizes ) ) { 238 $editor = wp_get_image_editor( $file ); 239 240 if ( ! is_wp_error( $editor ) ) { 241 if ( empty( $image_meta['sizes'] ) ) { 242 $image_meta['sizes'] = array(); 243 } 244 245 foreach ( $new_sizes as $new_size_name => $new_size_data ) { 246 $size_meta = $editor->make_subsize( $new_size_data ); 247 248 if ( ! is_wp_error( $size_meta ) ) { 249 // The sub-size was created successfully. Save the size meta value. 250 $image_meta['sizes'][ $new_size_name ] = $size_meta; 251 wp_update_attachment_metadata( $attachment_id, $image_meta ); 252 } 253 } 254 } 255 } 256 257 return $image_meta; 258 } 259 260 /** 261 * Generate attachment meta data and create image sub-sizes for images. 262 * 72 263 * @since 2.1.0 73 264 * 74 265 * @param int $attachment_id Attachment Id to process. … … 90 281 // Make the file path relative to the upload dir. 91 282 $metadata['file'] = _wp_relative_upload_path( $file ); 92 283 93 // Make thumbnails and other intermediate sizes.94 $_wp_additional_image_sizes = wp_get_additional_image_sizes();95 96 $sizes = array();97 foreach ( get_intermediate_image_sizes() as $s ) {98 $sizes[ $s ] = array(99 'width' => '',100 'height' => '',101 'crop' => false,102 );103 if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) {104 // For theme-added sizes105 $sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] );106 } else {107 // For default sizes set in options108 $sizes[ $s ]['width'] = get_option( "{$s}_size_w" );109 }110 111 if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) {112 // For theme-added sizes113 $sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] );114 } else {115 // For default sizes set in options116 $sizes[ $s ]['height'] = get_option( "{$s}_size_h" );117 }118 119 if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) {120 // For theme-added sizes121 $sizes[ $s ]['crop'] = $_wp_additional_image_sizes[ $s ]['crop'];122 } else {123 // For default sizes set in options124 $sizes[ $s ]['crop'] = get_option( "{$s}_crop" );125 }126 }127 128 /**129 * Filters the image sizes automatically generated when uploading an image.130 *131 * @since 2.9.0132 * @since 4.4.0 Added the `$metadata` argument.133 * @since 5.0.0 Added the `$attachment_id` argument.134 *135 * @param array $sizes An associative array of image sizes.136 * @param array $metadata An associative array of image metadata: width, height, file.137 * @param int $attachment_id Current attachment ID.138 */139 $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes, $metadata, $attachment_id );140 141 if ( $sizes ) {142 $editor = wp_get_image_editor( $file );143 144 if ( ! is_wp_error( $editor ) ) {145 $metadata['sizes'] = $editor->multi_resize( $sizes );146 }147 } else {148 $metadata['sizes'] = array();149 }150 151 284 // Fetch additional metadata from EXIF/IPTC. 152 285 $image_meta = wp_read_image_metadata( $file ); 153 286 if ( $image_meta ) { 154 287 $metadata['image_meta'] = $image_meta; 155 288 } 289 290 // Make thumbnails and other intermediate sizes. 291 $metadata = _wp_create_image_subsizes( $file, $metadata, $attachment_id ); 156 292 } elseif ( wp_attachment_is( 'video', $attachment ) ) { 157 293 $metadata = wp_read_video_metadata( $file ); 158 294 $support = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' ); … … 437 573 } 438 574 } 439 575 440 $exif = array(); 576 $exif = array(); 441 577 442 578 /** 443 579 * Filters the image types to check for exif data. -
src/wp-includes/class-wp-image-editor-gd.php
217 217 * @return array An array of resized images' metadata by size. 218 218 */ 219 219 public function multi_resize( $sizes ) { 220 $metadata = array(); 221 $orig_size = $this->size; 220 $metadata = array(); 222 221 223 222 foreach ( $sizes as $size => $size_data ) { 224 if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { 225 continue; 226 } 223 $meta = $this->make_subsize( $size_data ); 227 224 228 if ( ! is set( $size_data['width']) ) {229 $ size_data['width'] = null;225 if ( ! is_wp_error( $meta ) ) { 226 $metadata[ $size ] = $meta; 230 227 } 231 if ( ! isset( $size_data['height'] ) ) { 232 $size_data['height'] = null; 233 } 228 } 234 229 235 if ( ! isset( $size_data['crop'] ) ) { 236 $size_data['crop'] = false; 237 } 230 return $metadata; 231 } 238 232 239 $image = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); 240 $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) ); 233 /** 234 * Create an image sub-size and return the image meta data value for it. 235 * 236 * @since 5.0 237 * 238 * @param array $size_data Array of height, width and whether to crop. 239 * @return WP_Error|array WP_Error on error, or the image data array for inclusion in the `sizes` array in the image meta. 240 */ 241 public function make_subsize( $size_data ) { 242 if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { 243 return new WP_Error( 'image_subsize_create_error', __( 'Cannot resize the image. Both width and height are not set.' ) ); 244 } 241 245 242 if ( ! is_wp_error( $image ) && ! $duplicate ) {243 $resized = $this->_save( $image );246 $orig_size = $this->size; 247 $resized = false; 244 248 245 imagedestroy( $image ); 249 if ( ! isset( $size_data['width'] ) ) { 250 $size_data['width'] = null; 251 } 246 252 247 if ( ! is_wp_error( $resized ) && $resized ) { 248 unset( $resized['path'] ); 249 $metadata[ $size ] = $resized; 250 } 253 if ( ! isset( $size_data['height'] ) ) { 254 $size_data['height'] = null; 255 } 256 257 if ( ! isset( $size_data['crop'] ) ) { 258 $size_data['crop'] = false; 259 } 260 261 $image = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); 262 $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) ); 263 264 if ( is_wp_error( $image ) ) { 265 return $image; 266 } 267 268 if ( ! $duplicate ) { 269 $resized = $this->_save( $image ); 270 271 imagedestroy( $image ); 272 273 if ( is_wp_error( $resized ) ) { 274 return $resized; 251 275 } 252 276 253 $this->size = $orig_size; 277 if ( $resized ) { 278 unset( $resized['path'] ); 279 } 254 280 } 255 281 256 return $metadata; 282 $this->size = $orig_size; 283 284 if ( ! $resized ) { 285 return new WP_Error( 'image_subsize_create_error', __( 'Failed to create image sub-size.' ) ); 286 } 287 288 return $resized; 257 289 } 258 290 259 291 /** -
src/wp-includes/class-wp-image-editor-imagick.php
413 413 * @since 3.5.0 414 414 * 415 415 * @param array $sizes { 416 * An array of image size arrays. Default sizes are ' small', 'medium', 'medium_large', 'large'.416 * An array of image size arrays. Default sizes are 'thumbnail', 'medium', 'medium_large', 'large'. 417 417 * 418 418 * Either a height or width must be provided. 419 419 * If one of the two is set to null, the resize will … … 430 430 * @return array An array of resized images' metadata by size. 431 431 */ 432 432 public function multi_resize( $sizes ) { 433 $metadata = array(); 434 $orig_size = $this->size; 435 $orig_image = $this->image->getImage(); 433 $metadata = array(); 436 434 437 435 foreach ( $sizes as $size => $size_data ) { 438 if ( ! $this->image ) { 439 $this->image = $orig_image->getImage(); 440 } 436 $meta = $this->make_subsize( $size_data ); 441 437 442 if ( ! is set( $size_data['width'] ) && ! isset( $size_data['height']) ) {443 continue;438 if ( ! is_wp_error( $meta ) ) { 439 $metadata[ $size ] = $meta; 444 440 } 441 } 445 442 446 if ( ! isset( $size_data['width'] ) ) { 447 $size_data['width'] = null; 448 } 449 if ( ! isset( $size_data['height'] ) ) { 450 $size_data['height'] = null; 451 } 443 return $metadata; 444 } 452 445 453 if ( ! isset( $size_data['crop'] ) ) { 454 $size_data['crop'] = false; 455 } 446 /** 447 * Create an image sub-size and return the image meta data value for it. 448 * 449 * @since 5.0.0 450 * 451 * @param array $size_data Array of height, width and whether to crop. 452 * @return WP_Error|array WP_Error on error, or the image data array for inclusion in the `sizes` array in the image meta. 453 */ 454 public function make_subsize( $size_data ) { 455 if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { 456 return new WP_Error( 'image_subsize_create_error', __( 'Cannot resize the image. Both width and height are not set.' ) ); 457 } 456 458 457 $resize_result = $this->resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); 458 $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) ); 459 $orig_size = $this->size; 460 $orig_image = $this->image->getImage(); 461 $resized = false; 459 462 460 if ( ! is_wp_error( $resize_result ) && ! $duplicate ) { 461 $resized = $this->_save( $this->image ); 463 if ( ! isset( $size_data['width'] ) ) { 464 $size_data['width'] = null; 465 } 462 466 463 $this->image->clear();464 $this->image->destroy();465 $this->image = null;467 if ( ! isset( $size_data['height'] ) ) { 468 $size_data['height'] = null; 469 } 466 470 467 if ( ! is_wp_error( $resized ) && $resized ) { 468 unset( $resized['path'] ); 469 $metadata[ $size ] = $resized; 470 } 471 if ( ! isset( $size_data['crop'] ) ) { 472 $size_data['crop'] = false; 473 } 474 475 $resize_result = $this->resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); 476 $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) ); 477 478 if ( is_wp_error( $resize_result ) ) { 479 return $resize_result; 480 } 481 482 if ( ! $duplicate ) { 483 $resized = $this->_save( $this->image ); 484 485 $this->image->clear(); 486 $this->image->destroy(); 487 $this->image = null; 488 489 if ( is_wp_error( $resized ) ) { 490 return $resized; 471 491 } 472 492 473 $this->size = $orig_size; 493 if ( $resized ) { 494 unset( $resized['path'] ); 495 } 474 496 } 475 497 476 $this->image = $orig_image; 498 $this->size = $orig_size; 499 $this->image = $orig_image->getImage(); 477 500 478 return $metadata; 501 if ( ! $resized ) { 502 return new WP_Error( 'image_subsize_create_error', __( 'Failed to create image sub-size.' ) ); 503 } 504 505 return $resized; 479 506 } 480 507 481 508 /**