Changeset 54085
- Timestamp:
- 09/06/2022 09:11:41 PM (2 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/js/_enqueues/vendor/plupload/handlers.js
r53751 r54085 487 487 times = tryAgainCount[ file.id ]; 488 488 489 if ( times && times > 8) {489 if ( times && times > 4 ) { 490 490 /* 491 491 * The file may have been uploaded and attachment post created, -
trunk/src/js/_enqueues/vendor/plupload/wp-plupload.js
r53751 r54085 139 139 times = tryAgainCount[ file.id ]; 140 140 141 if ( times && times > 8) {141 if ( times && times > 4 ) { 142 142 /* 143 143 * The file may have been uploaded and attachment post created, -
trunk/src/wp-admin/includes/image.php
r53848 r54085 72 72 73 73 /** 74 * Compare sthe existing image sub-sizes (as saved in the attachment meta)75 * to the currently registered image sub-sizes, and return sthe difference.74 * Compare the existing image sub-sizes (as saved in the attachment meta) 75 * to the currently registered image sub-sizes, and return the difference. 76 76 * 77 77 * Registered sub-sizes that are larger than the image are skipped. 78 78 * 79 79 * @since 5.3.0 80 * @since 6.1.0 The $mime_type parameter was added. 81 * 82 * @param int $attachment_id The image attachment post ID. 83 * @param string $mime_type Optional. The mime type to check for missing sizes. Default is the primary image mime. 80 * 81 * @param int $attachment_id The image attachment post ID. 84 82 * @return array[] Associative array of arrays of image sub-size information for 85 83 * missing image sizes, keyed by image size name. 86 84 */ 87 function wp_get_missing_image_subsizes( $attachment_id , $mime_type = '') {85 function wp_get_missing_image_subsizes( $attachment_id ) { 88 86 if ( ! wp_attachment_is_image( $attachment_id ) ) { 89 87 return array(); 90 }91 92 $primary_mime_type = get_post_mime_type( get_post( $attachment_id ) );93 if ( ! $mime_type ) {94 $mime_type = $primary_mime_type;95 88 } 96 89 … … 137 130 * as the image may have been used in an older post. 138 131 */ 139 $missing_sizes = array(); 140 foreach ( $possible_sizes as $size_name => $size_data ) { 141 if ( ! isset( $image_meta['sizes'][ $size_name ] ) ) { 142 $missing_sizes[ $size_name ] = $size_data; 143 continue; 144 } 145 146 if ( ( isset( $size_data['mime-type'] ) && $size_data['mime-type'] === $mime_type ) || isset( $size_data['sources'][ $mime_type ] ) ) { 147 continue; 148 } 149 150 $missing_sizes[ $size_name ] = $size_data; 151 } 152 153 // Filter secondary mime types to those sizes that are enabled. 154 if ( $primary_mime_type !== $mime_type ) { 155 $missing_sizes = _wp_filter_image_sizes_additional_mime_type_support( $missing_sizes, $attachment_id ); 156 } 132 $missing_sizes = array_diff_key( $possible_sizes, $image_meta['sizes'] ); 157 133 158 134 /** … … 160 136 * 161 137 * @since 5.3.0 162 * @since 6.1.0 The $mime_type filter parameter was added.163 138 * 164 139 * @param array[] $missing_sizes Associative array of arrays of image sub-size information for … … 166 141 * @param array $image_meta The image meta data. 167 142 * @param int $attachment_id The image attachment post ID. 168 * @param string $mime_type The image mime type to get missing sizes for. 169 */ 170 return apply_filters( 'wp_get_missing_image_subsizes', $missing_sizes, $image_meta, $attachment_id, $mime_type ); 143 */ 144 return apply_filters( 'wp_get_missing_image_subsizes', $missing_sizes, $image_meta, $attachment_id ); 171 145 } 172 146 … … 176 150 * 177 151 * @since 5.3.0 178 * @since 6.1.0 Now supports additional mime types, creating the additional sub-sizes and 'full' sized images.179 152 * 180 153 * @param int $attachment_id The image attachment post ID. … … 195 168 } 196 169 } else { 197 // Get the primary and additional mime types to generate. 198 list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $image_file, $attachment_id ); 199 200 // Generate missing 'full' image files for additional mime types. 201 if ( ! empty( $additional_mime_types ) ) { 202 if ( isset( $image_meta['sources'] ) ) { 203 $missing_mime_types = array_diff( $additional_mime_types, array_keys( $image_meta['sources'] ) ); 204 } else { 205 $missing_mime_types = $additional_mime_types; 206 } 207 if ( ! empty( $missing_mime_types ) ) { 208 $image_meta = _wp_make_additional_mime_types( $missing_mime_types, $image_file, $image_meta, $attachment_id ); 209 } 210 } 211 212 // Generate missing image sub-sizes for each mime type. 213 $all_mime_types = array_merge( array( $primary_mime_type ), $additional_mime_types ); 214 foreach ( $all_mime_types as $mime_type ) { 215 $missing_sizes = wp_get_missing_image_subsizes( $attachment_id, $mime_type ); 216 217 if ( empty( $missing_sizes ) ) { 218 continue; 219 } 220 221 // This also updates the image meta. 222 $image_meta = _wp_make_subsizes( $missing_sizes, $image_file, $image_meta, $attachment_id, $mime_type ); 223 } 170 $missing_sizes = wp_get_missing_image_subsizes( $attachment_id ); 171 172 if ( empty( $missing_sizes ) ) { 173 return $image_meta; 174 } 175 176 // This also updates the image meta. 177 $image_meta = _wp_make_subsizes( $missing_sizes, $image_file, $image_meta, $attachment_id ); 224 178 } 225 179 … … 269 223 270 224 /** 271 * Creates image mime variations andsub-sizes, adds the new data to the image meta `sizes` array, and updates the image metadata.225 * Creates image sub-sizes, adds the new data to the image meta `sizes` array, and updates the image metadata. 272 226 * 273 227 * Intended for use after an image is uploaded. Saves/updates the image metadata after each … … 275 229 * 276 230 * @since 5.3.0 277 * @since 6.1.0 Generates sub-sizes in alternate mime types based on the `wp_image_mime_transforms` filter.278 231 * 279 232 * @param string $file Full path to the image file. … … 296 249 'filesize' => wp_filesize( $file ), 297 250 'sizes' => array(), 298 'sources' => array(),299 251 ); 300 252 … … 306 258 } 307 259 308 // Get the primary and additional mime types to generate.309 list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $file, $attachment_id );310 311 list( $editor, $resized, $rotated ) = _wp_maybe_scale_and_rotate_image( $file, $attachment_id, $imagesize, $exif_meta, $primary_mime_type );312 if ( is_wp_error( $editor ) ) {313 return $image_meta;314 }315 $suffix = _wp_get_image_suffix( $resized, $rotated );316 317 // Save image only if either it was modified or if the primary mime type is different from the original.318 if ( ! empty( $suffix ) || $primary_mime_type !== $imagesize['mime'] ) {319 $saved = $editor->save( $editor->generate_filename( $suffix ) );320 321 if ( ! is_wp_error( $saved ) ) {322 $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id );323 324 // If the image was rotated update the stored EXIF data.325 if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) {326 $image_meta['image_meta']['orientation'] = 1;327 }328 } else {329 // TODO: Log errors.330 }331 }332 333 // Set 'sources' for the primary mime type.334 $image_meta['sources'][ $primary_mime_type ] = _wp_get_sources_from_meta( $image_meta );335 336 /*337 * Initial save of the new metadata.338 * At this point the file was uploaded and moved to the uploads directory339 * but the image sub-sizes haven't been created yet and the `sizes` array is empty.340 */341 wp_update_attachment_metadata( $attachment_id, $image_meta );342 343 if ( ! empty( $additional_mime_types ) ) {344 // Use the original file's exif_meta orientation and size information for secondary mime generation to ensure345 // sub-sized images are correctly scaled and rotated.346 347 // Save data.348 $saved_meta = array();349 $saved_meta['orientation'] = $image_meta['image_meta']['orientation'];350 $saved_meta['width'] = $image_meta['width'];351 $saved_meta['height'] = $image_meta['height'];352 353 // Temporarily set the image meta to the original file's meta.354 $image_meta['image_meta']['orientation'] = $exif_meta['orientation'];355 $image_meta['width'] = $imagesize[0];356 $image_meta['height'] = $imagesize[1];357 358 $image_meta = _wp_make_additional_mime_types( $additional_mime_types, $file, $image_meta, $attachment_id );359 360 // Restore the saved meta data.361 $image_meta['image_meta']['orientation'] = $saved_meta['orientation'];362 $image_meta['width'] = $saved_meta['width'];363 $image_meta['height'] = $saved_meta['height'];364 365 }366 367 $new_sizes = wp_get_registered_image_subsizes();368 369 /**370 * Filters the image sizes automatically generated when uploading an image.371 *372 * @since 2.9.0373 * @since 4.4.0 Added the `$image_meta` argument.374 * @since 5.3.0 Added the `$attachment_id` argument.375 *376 * @param array $new_sizes Associative array of image sizes to be created.377 * @param array $image_meta The image meta data: width, height, file, sizes, etc.378 * @param int $attachment_id The attachment post ID for the image.379 */380 $new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id );381 382 $image_meta = _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $primary_mime_type );383 384 // Filter secondary mime types to those sizes that are enabled.385 $new_sizes = _wp_filter_image_sizes_additional_mime_type_support( $new_sizes, $attachment_id );386 387 foreach ( $additional_mime_types as $additional_mime_type ) {388 $image_meta = _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id, $additional_mime_type );389 }390 391 return $image_meta;392 }393 394 /**395 * Returns a WP_Image_Editor instance where the image file has been scaled and rotated as necessary.396 *397 * @since 6.1.0398 * @access private399 *400 * @param string $file Full path to the image file.401 * @param int $attachment_id Attachment ID.402 * @param array $imagesize {403 * Indexed array of the image width and height in pixels.404 *405 * @type int $0 The image width.406 * @type int $1 The image height.407 * }408 * @param array|null $exif_meta EXIF metadata if extracted from the image file.409 * @param string $mime_type Output mime type.410 * @return array Array with three entries: The WP_Image_Editor instance, whether the image was resized, and whether the411 * image was rotated (booleans). Each entry can alternatively be a WP_Error in case something went wrong.412 */413 function _wp_maybe_scale_and_rotate_image( $file, $attachment_id, $imagesize, $exif_meta, $mime_type ) {414 $resized = false;415 $rotated = false;416 417 $editor = wp_get_image_editor( $file, array( 'mime_type' => $mime_type ) );418 if ( is_wp_error( $editor ) ) {419 // This image cannot be edited.420 return array( $editor, $resized, $rotated );421 }422 423 if ( ! empty( $mime_type ) ) {424 $editor->set_output_mime_type( $mime_type );425 }426 427 260 // Do not scale (large) PNG images. May result in sub-sizes that have greater file size than the original. See #48736. 428 if ( 'image/png' !== $mime_type ) { 261 if ( 'image/png' !== $imagesize['mime'] ) { 262 429 263 /** 430 264 * Filters the "BIG image" threshold value. … … 452 286 // If the original image's dimensions are over the threshold, 453 287 // scale the image and use it as the "full" size. 454 if ( $threshold && ( $imagesize[0] > $threshold || $imagesize[1] > $threshold ) ) { 288 if ( $threshold && ( $image_meta['width'] > $threshold || $image_meta['height'] > $threshold ) ) { 289 $editor = wp_get_image_editor( $file ); 290 291 if ( is_wp_error( $editor ) ) { 292 // This image cannot be edited. 293 return $image_meta; 294 } 295 455 296 // Resize the image. 456 297 $resized = $editor->resize( $threshold, $threshold ); 298 $rotated = null; 457 299 458 300 // If there is EXIF data, rotate according to EXIF Orientation. 459 301 if ( ! is_wp_error( $resized ) && is_array( $exif_meta ) ) { 460 $rotated = $editor->maybe_exif_rotate(); 302 $resized = $editor->maybe_exif_rotate(); 303 $rotated = $resized; 304 } 305 306 if ( ! is_wp_error( $resized ) ) { 307 // Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg". 308 // This doesn't affect the sub-sizes names as they are generated from the original image (for best quality). 309 $saved = $editor->save( $editor->generate_filename( 'scaled' ) ); 310 311 if ( ! is_wp_error( $saved ) ) { 312 $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id ); 313 314 // If the image was rotated update the stored EXIF data. 315 if ( true === $rotated && ! empty( $image_meta['image_meta']['orientation'] ) ) { 316 $image_meta['image_meta']['orientation'] = 1; 317 } 318 } else { 319 // TODO: Log errors. 320 } 321 } else { 322 // TODO: Log errors. 461 323 } 462 324 } elseif ( ! empty( $exif_meta['orientation'] ) && 1 !== (int) $exif_meta['orientation'] ) { 463 325 // Rotate the whole original image if there is EXIF data and "orientation" is not 1. 326 327 $editor = wp_get_image_editor( $file ); 328 329 if ( is_wp_error( $editor ) ) { 330 // This image cannot be edited. 331 return $image_meta; 332 } 333 334 // Rotate the image. 464 335 $rotated = $editor->maybe_exif_rotate(); 465 } 466 } 467 468 return array( $editor, $resized, $rotated ); 469 } 470 471 /** 472 * Gets the suffix to use for image files based on resizing and rotating. 473 * 474 * @since 6.1.0 475 * @access private 476 * 477 * @param bool|WP_Error Whether the image was resized, or an error if resizing failed. 478 * @param bool|WP_Error Whether the image was rotated, or an error if rotating failed. 479 * @return string The suffix to use for the file name, or empty string if none. 480 */ 481 function _wp_get_image_suffix( $resized, $rotated ) { 482 if ( $resized && ! is_wp_error( $resized ) ) { 483 // Append "-scaled" to the image file name. It will look like "my_image-scaled.jpg". 484 // This doesn't affect the sub-sizes names as they are generated from the original image (for best quality). 485 return 'scaled'; 486 } 487 488 if ( true === $rotated ) { 489 // Append `-rotated` to the image file name. 490 return 'rotated'; 491 } 492 493 if ( is_wp_error( $resized ) || is_wp_error( $rotated ) ) { 494 // TODO: Log errors. 495 } 496 return ''; 497 } 498 499 /** 500 * Gets a sources array element from a meta. 501 * 502 * @since 6.1.0 503 * @access private 504 * 505 * @param array $meta The meta to get the source from. 506 * @return array The source array element. 507 */ 508 function _wp_get_sources_from_meta( $meta ) { 509 return array( 510 'file' => isset( $meta['file'] ) ? wp_basename( $meta['file'] ) : '', 511 'filesize' => isset( $meta['filesize'] ) ? $meta['filesize'] : wp_filesize( $meta['path'] ), 512 ); 336 337 if ( true === $rotated ) { 338 // Append `-rotated` to the image file name. 339 $saved = $editor->save( $editor->generate_filename( 'rotated' ) ); 340 341 if ( ! is_wp_error( $saved ) ) { 342 $image_meta = _wp_image_meta_replace_original( $saved, $file, $image_meta, $attachment_id ); 343 344 // Update the stored EXIF data. 345 if ( ! empty( $image_meta['image_meta']['orientation'] ) ) { 346 $image_meta['image_meta']['orientation'] = 1; 347 } 348 } else { 349 // TODO: Log errors. 350 } 351 } 352 } 353 } 354 355 /* 356 * Initial save of the new metadata. 357 * At this point the file was uploaded and moved to the uploads directory 358 * but the image sub-sizes haven't been created yet and the `sizes` array is empty. 359 */ 360 wp_update_attachment_metadata( $attachment_id, $image_meta ); 361 362 $new_sizes = wp_get_registered_image_subsizes(); 363 364 /** 365 * Filters the image sizes automatically generated when uploading an image. 366 * 367 * @since 2.9.0 368 * @since 4.4.0 Added the `$image_meta` argument. 369 * @since 5.3.0 Added the `$attachment_id` argument. 370 * 371 * @param array $new_sizes Associative array of image sizes to be created. 372 * @param array $image_meta The image meta data: width, height, file, sizes, etc. 373 * @param int $attachment_id The attachment post ID for the image. 374 */ 375 $new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id ); 376 377 return _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ); 513 378 } 514 379 … … 520 385 * 521 386 * @since 5.3.0 522 * @since 6.1.0 The $mime_type parameter was added.523 387 * @access private 524 388 * 525 * @param array $new_sizes Array defining what sizes to create. 526 * @param string $file Full path to the image file. 527 * @param array $image_meta The attachment meta data array. 528 * @param int $attachment_id Attachment ID to process. 529 * @param string $mime_type Optional. The mime type to check for missing sizes. Default is the image mime of $file. 389 * @param array $new_sizes Array defining what sizes to create. 390 * @param string $file Full path to the image file. 391 * @param array $image_meta The attachment meta data array. 392 * @param int $attachment_id Attachment ID to process. 530 393 * @return array The attachment meta data with updated `sizes` array. Includes an array of errors encountered while resizing. 531 394 */ 532 function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id , $mime_type = '') {395 function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ) { 533 396 if ( empty( $image_meta ) || ! is_array( $image_meta ) ) { 534 397 // Not an image attachment. 535 398 return array(); 536 }537 538 if ( ! $mime_type ) {539 $mime_type = wp_get_image_mime( $file );540 399 } 541 400 … … 549 408 */ 550 409 if ( array_key_exists( $size_name, $new_sizes ) ) { 551 // Unset the size if it is either the required mime type already exists either as main mime type or 552 // within sources. 553 if ( $size_meta['mime-type'] === $mime_type || isset( $size_meta['sources'][ $mime_type ] ) ) { 554 unset( $new_sizes[ $size_name ] ); 555 } 410 unset( $new_sizes[ $size_name ] ); 556 411 } 557 412 } … … 579 434 $new_sizes = array_filter( array_merge( $priority, $new_sizes ) ); 580 435 581 $editor = wp_get_image_editor( $file , array( 'mime_type' => $mime_type ));436 $editor = wp_get_image_editor( $file ); 582 437 583 438 if ( is_wp_error( $editor ) ) { … … 585 440 return $image_meta; 586 441 } 587 588 $editor->set_output_mime_type( $mime_type );589 442 590 443 // If stored EXIF data exists, rotate the source image before creating sub-sizes. … … 605 458 } else { 606 459 // Save the size meta value. 607 if ( ! isset( $image_meta['sizes'][ $new_size_name ] ) ) { 608 $image_meta['sizes'][ $new_size_name ] = $new_size_meta; 609 } else { 610 // Remove any newly generated images that are larger than the primary mime type. 611 $new_size = isset( $new_size_meta['filesize'] ) ? $new_size_meta['filesize'] : 0; 612 $primary_size = isset( $image_meta['sizes'][ $new_size_name ]['filesize'] ) ? $image_meta['sizes'][ $new_size_name ]['filesize'] : 0; 613 614 if ( $new_size && $primary_size && $new_size >= $primary_size ) { 615 wp_delete_file( dirname( $file ) . '/' . $new_size_meta['file'] ); 616 continue; 617 } 618 } 619 if ( ! isset( $image_meta['sizes'][ $new_size_name ]['sources'] ) ) { 620 $image_meta['sizes'][ $new_size_name ]['sources'] = array(); 621 } 622 $image_meta['sizes'][ $new_size_name ]['sources'][ $mime_type ] = _wp_get_sources_from_meta( $new_size_meta ); 460 $image_meta['sizes'][ $new_size_name ] = $new_size_meta; 623 461 wp_update_attachment_metadata( $attachment_id, $image_meta ); 624 462 } … … 629 467 630 468 if ( ! empty( $created_sizes ) ) { 631 foreach ( $created_sizes as $created_size_name => $created_size_meta ) { 632 633 // Primary mime type is set in 'sizes' array. 634 if ( ! isset( $image_meta['sizes'][ $created_size_name ] ) ) { 635 $image_meta['sizes'][ $created_size_name ] = $created_size_meta; 636 } else { 637 // Remove any newly generated images that are larger than the primary mime type. 638 $new_size = isset( $created_size_meta['filesize'] ) ? $created_size_meta['filesize'] : 0; 639 $primary_size = isset( $image_meta['sizes'][ $created_size_name ]['filesize'] ) ? $image_meta['sizes'][ $created_size_name ]['filesize'] : 0; 640 641 if ( $new_size && $primary_size && $new_size >= $primary_size ) { 642 wp_delete_file( dirname( $file ) . '/' . $created_size_meta['file'] ); 643 continue; 644 } 645 } 646 if ( ! isset( $image_meta['sizes'][ $created_size_name ]['sources'] ) ) { 647 $image_meta['sizes'][ $created_size_name ]['sources'] = array(); 648 } 649 $image_meta['sizes'][ $created_size_name ]['sources'][ $mime_type ] = _wp_get_sources_from_meta( $created_size_meta ); 650 } 651 wp_update_attachment_metadata( $attachment_id, $image_meta ); 652 } 653 } 654 655 return $image_meta; 656 } 657 658 /** 659 * Filters the list of image size objects that support secondary mime type output. 660 * 661 * @since 6.1.0 662 * 663 * @param array $sizes Associative array of image sizes. 664 * @param int $attachment_id Attachment ID. 665 * @return array $sizes Filtered $sizes with only those that support secondary mime type output. 666 */ 667 function _wp_filter_image_sizes_additional_mime_type_support( $sizes, $attachment_id ) { 668 669 // Include only the core sizes that do not rely on add_image_size(). Additional image sizes are opt-in. 670 $enabled_sizes = array( 671 'thumbnail' => true, 672 'medium' => true, 673 'medium_large' => true, 674 'large' => true, 675 'post-thumbnail' => true, 676 ); 677 678 /** 679 * Filter the sizes that support secondary mime type output. Developers can use this 680 * to control the output of additional mime type sub-sized images. 681 * 682 * @since 6.1.0 683 * 684 * @param array $enabled_sizes Map of size names and whether they support secondary mime type output. 685 * @param int $attachment_id Attachment ID. 686 */ 687 $enabled_sizes = apply_filters( 'wp_image_sizes_with_additional_mime_type_support', $enabled_sizes, $attachment_id ); 688 689 // Filter supported sizes to only include enabled sizes. 690 return array_intersect_key( $sizes, array_filter( $enabled_sizes ) ); 691 } 692 693 /** 694 * Low-level function to create full-size images in additional mime types. 695 * 696 * Updates the image meta after each mime type image is created. 697 * 698 * @since 6.1.0 699 * @access private 700 * 701 * @param array $new_mime_types Array defining what mime types to create. 702 * @param string $file Full path to the image file. 703 * @param array $image_meta The attachment meta data array. 704 * @param int $attachment_id Attachment ID to process. 705 * @return array The attachment meta data with updated `sizes` array. Includes an array of errors encountered while resizing. 706 */ 707 function _wp_make_additional_mime_types( $new_mime_types, $file, $image_meta, $attachment_id ) { 708 $imagesize = array( 709 $image_meta['width'], 710 $image_meta['height'], 711 ); 712 $exif_meta = isset( $image_meta['image_meta'] ) ? $image_meta['image_meta'] : null; 713 $original_file_size = isset( $image_meta['filesize'] ) ? $image_meta['filesize'] : wp_filesize( $file ); 714 715 foreach ( $new_mime_types as $mime_type ) { 716 list( $editor, $resized, $rotated ) = _wp_maybe_scale_and_rotate_image( $file, $attachment_id, $imagesize, $exif_meta, $mime_type ); 717 if ( is_wp_error( $editor ) ) { 718 // The image cannot be edited. 719 continue; 720 } 721 722 $suffix = _wp_get_image_suffix( $resized, $rotated ); 723 $extension = wp_get_default_extension_for_mime_type( $mime_type ); 724 725 $saved = $editor->save( $editor->generate_filename( $suffix, null, $extension ) ); 726 727 if ( is_wp_error( $saved ) ) { 728 // TODO: Log errors. 729 } else { 730 // If the saved image is larger than the original, discard it. 731 $filesize = isset( $saved['filesize'] ) ? $saved['filesize'] : wp_filesize( $saved['path'] ); 732 if ( $filesize && $original_file_size && $filesize > $original_file_size ) { 733 wp_delete_file( $saved['path'] ); 734 continue; 735 } 736 $image_meta['sources'][ $mime_type ] = _wp_get_sources_from_meta( $saved ); 469 $image_meta['sizes'] = array_merge( $image_meta['sizes'], $created_sizes ); 737 470 wp_update_attachment_metadata( $attachment_id, $image_meta ); 738 471 } … … 828 561 * Information about the newly-uploaded file. 829 562 * 830 * @type string $file Filename of the newly-uploaded file.831 * @type string $url URL of the uploaded file.832 * @type string $type File type.563 * @type string $file Filename of the newly-uploaded file. 564 * @type string $url URL of the uploaded file. 565 * @type string $type File type. 833 566 * } 834 567 */ … … 898 631 899 632 // Create sub-sizes saving the image meta after each. 900 $metadata = _wp_make_subsizes( $merged_sizes, $image_file, $metadata, $attachment_id , '');633 $metadata = _wp_make_subsizes( $merged_sizes, $image_file, $metadata, $attachment_id ); 901 634 } 902 635 } … … 1425 1158 return $dst_file; 1426 1159 } 1427 1428 /**1429 * Returns an array with the list of valid mime types that a specific mime type should be converted into.1430 * For example an `image/jpeg` should be converted into an `image/jpeg` and `image/webp`. The first type1431 * is considered the primary output type for this image.1432 *1433 * Called for each uploaded image to determine the list of mime types that should be converted into. Then,1434 * called again for each image size as they are generated to check if the image should be converted into the mime type1435 * for that size.1436 *1437 * @since 6.1.01438 *1439 * @param int $attachment_id The attachment ID.1440 * @return array An array of valid mime types, where the key is the source file mime type and the list of mime types to1441 * generate.1442 */1443 function wp_upload_image_mime_transforms( $attachment_id ) {1444 $default_image_mime_transforms = array(1445 'image/jpeg' => array( 'image/jpeg', 'image/webp' ),1446 'image/webp' => array( 'image/webp', 'image/jpeg' ),1447 );1448 $image_mime_transforms = $default_image_mime_transforms;1449 1450 /**1451 * Filters the output mime types for a given input mime type and image size.1452 *1453 * @since 6.1.01454 *1455 * @param array $image_mime_transforms A map with the valid mime transforms where the key is the source file mime type1456 * and the value is one or more mime file types to generate.1457 * @param int $attachment_id The ID of the attachment where the hook was dispatched.1458 */1459 $image_mime_transforms = apply_filters( 'wp_upload_image_mime_transforms', $image_mime_transforms, $attachment_id );1460 1461 if ( ! is_array( $image_mime_transforms ) ) {1462 return $default_image_mime_transforms;1463 }1464 1465 return array_map(1466 function( $transforms_list ) {1467 return (array) $transforms_list;1468 },1469 $image_mime_transforms1470 );1471 }1472 1473 /**1474 * Extracts the primary and additional mime output types for an image from the $image_mime_transforms.1475 *1476 * @since 6.1.01477 * @access private1478 *1479 * @param string $file Full path to the image file.1480 * @param int $attachment_id Attachment ID to process.1481 * @return array An array with two entries, the primary mime type and the list of additional mime types.1482 */1483 function _wp_get_primary_and_additional_mime_types( $file, $attachment_id ) {1484 $image_mime_transforms = wp_upload_image_mime_transforms( $attachment_id );1485 $original_mime_type = wp_get_image_mime( $file );1486 $output_mime_types = isset( $image_mime_transforms[ $original_mime_type ] ) ? $image_mime_transforms[ $original_mime_type ] : array( $original_mime_type );1487 1488 // Exclude any output mime types that the system doesn't support.1489 $output_mime_types = array_values(1490 array_filter(1491 $output_mime_types,1492 function( $mime_type ) {1493 return wp_image_editor_supports(1494 array(1495 'mime_type' => $mime_type,1496 )1497 );1498 }1499 )1500 );1501 1502 // Handle an empty value for $output_mime_types: only output the original type.1503 if ( empty( $output_mime_types ) ) {1504 return array( $original_mime_type, array() );1505 }1506 1507 // Use original mime type as primary mime type, or alternatively the first one.1508 $primary_mime_type_key = array_search( $original_mime_type, $output_mime_types, true );1509 if ( false === $primary_mime_type_key ) {1510 $primary_mime_type_key = 0;1511 }1512 // Split output mime types into primary mime type and additional mime types.1513 $additional_mime_types = $output_mime_types;1514 list( $primary_mime_type ) = array_splice( $additional_mime_types, $primary_mime_type_key, 1 );1515 1516 return array(1517 $primary_mime_type,1518 $additional_mime_types,1519 );1520 } -
trunk/src/wp-includes/class-wp-image-editor.php
r53751 r54085 334 334 protected function get_output_format( $filename = null, $mime_type = null ) { 335 335 $new_ext = null; 336 337 // If no mime type is passed but output mime type is set, use that.338 if ( ! $mime_type && ! empty( $this->output_mime_type ) ) {339 $mime_type = $this->output_mime_type;340 }341 336 342 337 // By default, assume specified type takes priority. … … 431 426 432 427 /** 433 * Builds an output filename based on current file, and adding proper suffix. 434 * 435 * @since 3.5.0 436 * @since 6.1.0 Skips adding a suffix when set to an empty string. When the 437 * file extension being generated doesn't match the image file extension, 438 * add the extension to the suffix 439 * 440 * @param string $suffix Optional. Suffix to add to the filename. The default null 441 * will result in a 'widthxheight' suffix. Passing 442 * an empty string will result in no suffix. 443 * @param string $dest_path Optional. The path to save the file to. The default null 444 * will use the image file path. 445 * @param string $extension Optional. The file extension to use. The default null 446 * will use the image file extension. 447 * @return string filename The generated file name. 428 * Builds an output filename based on current file, and adding proper suffix 429 * 430 * @since 3.5.0 431 * 432 * @param string $suffix 433 * @param string $dest_path 434 * @param string $extension 435 * @return string filename 448 436 */ 449 437 public function generate_filename( $suffix = null, $dest_path = null, $extension = null ) { 450 438 // $suffix will be appended to the destination filename, just before the extension. 451 if ( null ===$suffix ) {439 if ( ! $suffix ) { 452 440 $suffix = $this->get_suffix(); 453 441 } … … 470 458 } 471 459 472 if ( empty( $suffix ) ) { 473 $suffix = ''; 474 } else { 475 $suffix = "-{$suffix}"; 476 } 477 478 // When the file extension being generated doesn't match the image file extension, 479 // add the extension to the suffix to ensure a unique file name. Prevents 480 // name conflicts when a single image type can have multiple extensions, 481 // eg. .jpg, .jpeg and .jpe are all valid JPEG extensions. 482 if ( ! empty( $extension ) && $extension !== $ext ) { 483 $suffix .= "-{$ext}"; 484 } 485 486 return trailingslashit( $dir ) . "{$name}{$suffix}.{$new_ext}"; 460 return trailingslashit( $dir ) . "{$name}-{$suffix}.{$new_ext}"; 487 461 } 488 462 … … 664 638 return wp_get_default_extension_for_mime_type( $mime_type ); 665 639 } 666 667 /**668 * Set the editor output mime type, useful when outputting alternate mime types.669 *670 * Track that the mime type is set with the mime type set flag.671 *672 * @since 6.1.0673 *674 * @param string $output_mime_type The mime type to set.675 */676 public function set_output_mime_type( $output_mime_type ) {677 $this->output_mime_type = $output_mime_type;678 }679 680 /**681 * Reset the mime type to the original file mime type.682 *683 * Reset the mime type set flag.684 *685 * @since 6.1.0686 */687 public function reset_output_mime_type() {688 $this->output_mime_type = $this->mime_type;689 }690 640 } 641 -
trunk/src/wp-includes/media.php
r53827 r54085 1853 1853 } 1854 1854 1855 // Use alternate mime types when specified and available.1856 if ( $attachment_id > 0 && _wp_in_front_end_context() ) {1857 $filtered_image = wp_image_use_alternate_mime_types( $filtered_image, $context, $attachment_id );1858 }1859 1860 1855 /** 1861 1856 * Filters an img tag within the content for a given context. … … 1902 1897 1903 1898 return $content; 1904 }1905 1906 /**1907 * Use alternate mime type images in the front end content output when available.1908 *1909 * @since 6.1.01910 *1911 * @param string $image The HTML `img` tag where the attribute should be added.1912 * @param string $context Additional context to pass to the filters.1913 * @param int $attachment_id The attachment ID.1914 * @return string Converted `img` tag with `loading` attribute added.1915 */1916 function wp_image_use_alternate_mime_types( $image, $context, $attachment_id ) {1917 $metadata = wp_get_attachment_metadata( $attachment_id );1918 if ( empty( $metadata['file'] ) ) {1919 return $image;1920 }1921 1922 // Only alter images with a `sources` attribute1923 if ( empty( $metadata['sources'] ) ) {1924 return $image;1925 };1926 1927 $target_mimes = array( 'image/webp', 'image/jpeg' );1928 1929 /**1930 * Filter the content image mime type output selection and order.1931 *1932 * When outputting images in the content, the first mime type available will be used.1933 *1934 * @since 6.1.01935 *1936 * @param array $target_mimes The image output mime type and order. Default is array( 'image/webp', 'image/jpeg' ).1937 * @param int $attachment_id The attachment ID.1938 * @param string $context Additional context to pass to the filters.1939 * @return array The filtered output mime type and order. Return an empty array to skip mime type substitution.1940 */1941 $target_mimes = apply_filters( 'wp_content_image_mimes', $target_mimes, $attachment_id, $context );1942 1943 if ( false === $target_mimes ) {1944 return $image;1945 }1946 1947 // Find the appropriate size for the provided URL in the first available mime type.1948 foreach ( $target_mimes as $target_mime ) {1949 // Handle full size image replacement.1950 if ( ! empty( $metadata['sources'][ $target_mime ]['file'] ) ) {1951 $src_filename = wp_basename( $metadata['file'] );1952 1953 // This is the same MIME type as the original, so the entire $target_mime can be skipped.1954 // Since it is already the preferred MIME type, the entire loop can be cancelled.1955 if ( $metadata['sources'][ $target_mime ]['file'] === $src_filename ) {1956 break;1957 }1958 1959 $image = str_replace( $src_filename, $metadata['sources'][ $target_mime ]['file'], $image );1960 1961 // The full size was replaced, so unset this entirely here so that in the next iteration it is no longer1962 // considered, simply for a small performance optimization.1963 unset( $metadata['sources'] );1964 }1965 1966 // Go through each image size and replace with the first available mime type version.1967 foreach ( $metadata['sizes'] as $name => $size_data ) {1968 // Check if size has an original file.1969 if ( empty( $size_data['file'] ) ) {1970 continue;1971 }1972 1973 // Check if size has a source in the desired mime type.1974 if ( empty( $size_data['sources'][ $target_mime ]['file'] ) ) {1975 continue;1976 }1977 1978 $src_filename = wp_basename( $size_data['file'] );1979 1980 // This is the same MIME type as the original, so the entire $target_mime can be skipped.1981 // Since it is already the preferred MIME type, the entire loop can be cancelled.1982 if ( $size_data['sources'][ $target_mime ]['file'] === $src_filename ) {1983 break 2;1984 }1985 1986 // Found a match, replace with the new filename.1987 $image = str_replace( $src_filename, $size_data['sources'][ $target_mime ]['file'], $image );1988 1989 // This size was replaced, so unset this entirely here so that in the next iteration it is no longer1990 // considered, simply for a small performance optimization.1991 unset( $metadata['sizes'][ $name ] );1992 }1993 }1994 return $image;1995 }1996 1997 /**1998 * Check if execution is currently in the front end content context, outside of <head>.1999 *2000 * @since 6.1.02001 * @access private2002 *2003 * @return bool True if in the front end content context, false otherwise.2004 */2005 function _wp_in_front_end_context() {2006 global $wp_query;2007 2008 // Check if this request is generally outside (or before) any frontend context.2009 if ( ! isset( $wp_query ) || defined( 'XMLRPC_REQUEST' ) || defined( 'REST_REQUEST' ) || is_feed() ) {2010 return false;2011 }2012 2013 // Check if we're anywhere before the 'wp_head' action has completed.2014 return did_action( 'template_redirect' ) && ! doing_action( 'wp_head' );2015 1899 } 2016 1900 -
trunk/src/wp-includes/post.php
r53944 r54085 6487 6487 6488 6488 foreach ( $meta['sizes'] as $size => $sizeinfo ) { 6489 6490 // Check for alternate size mime types in the sizeinfo['sources'] array to delete. 6491 if ( isset( $sizeinfo['sources'] ) && is_array( $sizeinfo['sources'] ) ) { 6492 foreach ( $sizeinfo['sources'] as $mime => $properties ) { 6493 $intermediate_file = str_replace( wp_basename( $file ), $properties['file'], $file ); 6494 if ( ! empty( $intermediate_file ) ) { 6495 $intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file ); 6496 if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) { 6497 $deleted = false; 6498 } 6499 } 6500 } 6501 } else { 6502 // Otherwise, delete files from the sizeinfo data. 6503 $intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file ); 6504 6505 if ( ! empty( $intermediate_file ) ) { 6506 $intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file ); 6507 6508 if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) { 6509 $deleted = false; 6510 } 6489 $intermediate_file = str_replace( wp_basename( $file ), $sizeinfo['file'], $file ); 6490 6491 if ( ! empty( $intermediate_file ) ) { 6492 $intermediate_file = path_join( $uploadpath['basedir'], $intermediate_file ); 6493 6494 if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) { 6495 $deleted = false; 6511 6496 } 6512 6497 } … … 6530 6515 } 6531 6516 6532 // Delete the full size images from 'sources' if available, or the root file.6533 if ( isset( $meta['sources'] ) && is_array( $meta['sources'] ) ) {6534 $sources = $meta['sources'];6535 $intermediate_dir = path_join( $uploadpath['basedir'], dirname( $file ) );6536 foreach ( $sources as $mime => $properties ) {6537 if ( ! is_array( $properties ) || empty( $properties['file'] ) ) {6538 continue;6539 }6540 $intermediate_file = str_replace( wp_basename( $file ), $properties['file'], $file );6541 if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {6542 $deleted = false;6543 }6544 }6545 } else {6546 if ( ! wp_delete_file_from_directory( $file, $uploadpath['basedir'] ) ) {6547 $deleted = false;6548 }6549 }6550 6551 6517 if ( is_array( $backup_sizes ) ) { 6552 6553 6518 $del_dir = path_join( $uploadpath['basedir'], dirname( $meta['file'] ) ); 6554 // Delete the root (edited) file which was not deleted above. 6555 if ( ! wp_delete_file_from_directory( $file, $uploadpath['basedir'] ) ) { 6556 $deleted = false; 6557 } 6519 6558 6520 foreach ( $backup_sizes as $size ) { 6559 // Delete files from 'sources' data if available, otherwise from 'sizes' data. 6560 if ( isset( $meta['sources'] ) && is_array( $meta['sources'] ) ) { 6561 // Delete any backup images stored in the 'sources' array. 6562 if ( isset( $size['sources'] ) && is_array( $size['sources'] ) ) { 6563 foreach ( $size['sources'] as $mime => $properties ) { 6564 $del_file = path_join( dirname( $meta['file'] ), $properties['file'] ); 6565 if ( ! empty( $del_file ) ) { 6566 $del_file = path_join( $uploadpath['basedir'], $del_file ); 6567 if ( ! wp_delete_file_from_directory( $del_file, $del_dir ) ) { 6568 $deleted = false; 6569 } 6570 } 6571 } 6572 } 6573 } else { 6574 $del_file = path_join( dirname( $meta['file'] ), $size['file'] ); 6575 6576 if ( ! empty( $del_file ) ) { 6577 $del_file = path_join( $uploadpath['basedir'], $del_file ); 6578 if ( ! wp_delete_file_from_directory( $del_file, $del_dir ) ) { 6579 $deleted = false; 6580 } 6521 $del_file = path_join( dirname( $meta['file'] ), $size['file'] ); 6522 6523 if ( ! empty( $del_file ) ) { 6524 $del_file = path_join( $uploadpath['basedir'], $del_file ); 6525 6526 if ( ! wp_delete_file_from_directory( $del_file, $del_dir ) ) { 6527 $deleted = false; 6581 6528 } 6582 6529 } 6583 6530 } 6531 } 6532 6533 if ( ! wp_delete_file_from_directory( $file, $uploadpath['basedir'] ) ) { 6534 $deleted = false; 6584 6535 } 6585 6536 -
trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php
r53786 r54085 784 784 785 785 $size_data['source_url'] = $image_src[0]; 786 787 if ( empty( $size_data['sources'] ) || ! is_array( $size_data['sources'] ) ) {788 continue;789 }790 791 $image_url_basename = wp_basename( $image_src[0] );792 foreach ( $size_data['sources'] as $mime => &$mime_details ) {793 $mime_details['source_url'] = str_replace( $image_url_basename, $mime_details['file'], $image_src[0] );794 }795 786 } 796 787 … … 805 796 'source_url' => $full_src[0], 806 797 ); 807 808 if ( ! empty( $data['media_details']['sources'] ) ) {809 $full_url_basename = wp_basename( $full_src[0] );810 foreach ( $data['media_details']['sources'] as $mime => &$mime_details ) {811 $mime_details['source_url'] = str_replace( $full_url_basename, $mime_details['file'], $full_src[0] );812 }813 $data['media_details']['sizes']['full']['sources'] = $data['media_details']['sources'];814 unset( $data['media_details']['sources'] );815 }816 798 } 817 799 } else { -
trunk/tests/phpunit/tests/image/editor.php
r53751 r54085 132 132 133 133 // Removing PNG to WEBP conversion on save. Quality setting should reset to the default. 134 $editor->reset_output_mime_type();135 134 remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_formats' ) ); 136 135 $editor->save(); … … 156 155 157 156 // After removing the conversion the quality setting should reset to the filtered value for the original image type, JPEG. 158 $editor->reset_output_mime_type();159 157 remove_filter( 'image_editor_output_format', array( $this, 'image_editor_output_formats' ) ); 160 158 $editor->save(); … … 229 227 230 228 // Test with a suffix only. 231 $this->assertSame( 'canola-100x50 -jpg.png', wp_basename( $editor->generate_filename( null, null, 'png' ) ) );229 $this->assertSame( 'canola-100x50.png', wp_basename( $editor->generate_filename( null, null, 'png' ) ) ); 232 230 233 231 // Combo! 234 $this->assertSame( trailingslashit( realpath( get_temp_dir() ) ) . 'canola-new -jpg.png', $editor->generate_filename( 'new', realpath( get_temp_dir() ), 'png' ) );232 $this->assertSame( trailingslashit( realpath( get_temp_dir() ) ) . 'canola-new.png', $editor->generate_filename( 'new', realpath( get_temp_dir() ), 'png' ) ); 235 233 236 234 // Test with a stream destination. … … 365 363 } 366 364 367 /**368 * Test creating the original image mime type when the image is uploaded.369 *370 * @ticket 55443371 *372 * @dataProvider provider_image_with_default_behaviors_during_upload373 */374 public function it_should_create_the_original_image_mime_type_when_the_image_is_uploaded( $file_location, $expected_mime, $targeted_mime ) {375 $attachment_id = $this->factory->attachment->create_upload_object( $file_location );376 377 $metadata = wp_get_attachment_metadata( $attachment_id );378 379 $this->assertIsArray( $metadata );380 foreach ( $metadata['sizes'] as $size_name => $properties ) {381 $this->assertArrayHasKey( 'sources', $properties );382 $this->assertIsArray( $properties['sources'] );383 $this->assertArrayHasKey( $expected_mime, $properties['sources'] );384 $this->assertArrayHasKey( 'filesize', $properties['sources'][ $expected_mime ] );385 $this->assertArrayHasKey( 'file', $properties['sources'][ $expected_mime ] );386 $this->assertArrayHasKey( $targeted_mime, $properties['sources'] );387 $this->assertArrayHasKey( 'filesize', $properties['sources'][ $targeted_mime ] );388 $this->assertArrayHasKey( 'file', $properties['sources'][ $targeted_mime ] );389 }390 }391 392 /**393 * Data provider for it_should_create_the_original_image_mime_type_when_the_image_is_uploaded.394 */395 public function provider_image_with_default_behaviors_during_upload() {396 yield 'JPEG image' => array(397 DIR_TESTDATA . '/images/test-image.jpg',398 'image/jpeg',399 'image/webp',400 );401 402 yield 'WebP image' => array(403 DIR_TESTDATA . '/images/webp-lossy.webp',404 'image/webp',405 'image/jpeg',406 );407 }408 409 /**410 * Test Do not create the sources property if no transform is provided.411 *412 * @ticket 55443413 */414 public function it_should_not_create_the_sources_property_if_no_transform_is_provided() {415 add_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );416 417 $attachment_id = $this->factory->attachment->create_upload_object(418 DIR_TESTDATA . '/images/test-image.jpg'419 );420 421 $metadata = wp_get_attachment_metadata( $attachment_id );422 423 $this->assertIsArray( $metadata );424 foreach ( $metadata['sizes'] as $size_name => $properties ) {425 $this->assertArrayNotHasKey( 'sources', $properties );426 }427 }428 429 /**430 * Test creating the sources property when no transform is available.431 *432 * @ticket 55443433 */434 public function it_should_create_the_sources_property_when_no_transform_is_available() {435 add_filter(436 'wp_upload_image_mime_transforms',437 function () {438 return array( 'image/jpeg' => array() );439 }440 );441 442 $attachment_id = $this->factory->attachment->create_upload_object(443 DIR_TESTDATA . '/images/test-image.jpg'444 );445 446 $metadata = wp_get_attachment_metadata( $attachment_id );447 448 $this->assertIsArray( $metadata );449 foreach ( $metadata['sizes'] as $size_name => $properties ) {450 $this->assertArrayHasKey( 'sources', $properties );451 $this->assertIsArray( $properties['sources'] );452 $this->assertArrayHasKey( 'image/jpeg', $properties['sources'] );453 $this->assertArrayHasKey( 'filesize', $properties['sources']['image/jpeg'] );454 $this->assertArrayHasKey( 'file', $properties['sources']['image/jpeg'] );455 $this->assertArrayNotHasKey( 'image/webp', $properties['sources'] );456 }457 }458 459 /**460 * Test not creating the sources property if the mime is not specified on the transforms images.461 *462 * @ticket 55443463 */464 public function it_should_not_create_the_sources_property_if_the_mime_is_not_specified_on_the_transforms_images() {465 add_filter(466 'wp_upload_image_mime_transforms',467 function () {468 return array( 'image/jpeg' => array() );469 }470 );471 472 $attachment_id = $this->factory->attachment->create_upload_object(473 DIR_TESTDATA . '/images/webp-lossy.webp'474 );475 476 $metadata = wp_get_attachment_metadata( $attachment_id );477 478 $this->assertIsArray( $metadata );479 foreach ( $metadata['sizes'] as $size_name => $properties ) {480 $this->assertArrayNotHasKey( 'sources', $properties );481 }482 }483 484 485 /**486 * Test creating a WebP version with all the required properties.487 *488 * @ticket 55443489 */490 public function it_should_create_a_webp_version_with_all_the_required_properties() {491 $attachment_id = $this->factory->attachment->create_upload_object(492 DIR_TESTDATA . '/images/test-image.jpg'493 );494 495 $metadata = wp_get_attachment_metadata( $attachment_id );496 $this->assertArrayHasKey( 'sources', $metadata['sizes']['thumbnail'] );497 $this->assertArrayHasKey( 'image/jpeg', $metadata['sizes']['thumbnail']['sources'] );498 $this->assertArrayHasKey( 'filesize', $metadata['sizes']['thumbnail']['sources']['image/jpeg'] );499 $this->assertArrayHasKey( 'file', $metadata['sizes']['thumbnail']['sources']['image/jpeg'] );500 $this->assertArrayHasKey( 'image/webp', $metadata['sizes']['thumbnail']['sources'] );501 $this->assertArrayHasKey( 'filesize', $metadata['sizes']['thumbnail']['sources']['image/webp'] );502 $this->assertArrayHasKey( 'file', $metadata['sizes']['thumbnail']['sources']['image/webp'] );503 $this->assertStringEndsNotWith( '.jpeg', $metadata['sizes']['thumbnail']['sources']['image/webp']['file'] );504 $this->assertStringEndsWith( '.webp', $metadata['sizes']['thumbnail']['sources']['image/webp']['file'] );505 }506 507 /**508 * Test removing `scaled` suffix from the generated filename.509 *510 * @ticket 55443511 */512 public function it_should_remove_scaled_suffix_from_the_generated_filename() {513 // The leafs image is 1080 pixels wide with this filter we ensure a -scaled version is created.514 add_filter(515 'big_image_size_threshold',516 function () {517 return 850;518 }519 );520 521 $attachment_id = $this->factory->attachment->create_upload_object(522 DIR_TESTDATA . '/images/test-image.jpg'523 );524 $metadata = wp_get_attachment_metadata( $attachment_id );525 $this->assertStringEndsWith( '-scaled.jpg', get_attached_file( $attachment_id ) );526 $this->assertArrayHasKey( 'image/webp', $metadata['sizes']['medium']['sources'] );527 $this->assertStringEndsNotWith( '-scaled.webp', $metadata['sizes']['medium']['sources']['image/webp']['file'] );528 $this->assertStringEndsWith( '-300x200.webp', $metadata['sizes']['medium']['sources']['image/webp']['file'] );529 }530 531 /**532 * Test removing the generated webp images when the attachment is deleted.533 *534 * @ticket 55443535 */536 public function it_should_remove_the_generated_webp_images_when_the_attachment_is_deleted() {537 // Make sure no editor is available.538 $attachment_id = $this->factory->attachment->create_upload_object(539 DIR_TESTDATA . '/images/test-image.jpg'540 );541 542 $file = get_attached_file( $attachment_id, true );543 $dirname = pathinfo( $file, PATHINFO_DIRNAME );544 545 $this->assertIsString( $file );546 $this->assertFileExists( $file );547 548 $metadata = wp_get_attachment_metadata( $attachment_id );549 $sizes = array( 'thumbnail', 'medium' );550 551 foreach ( $sizes as $size_name ) {552 $this->assertArrayHasKey( 'image/webp', $metadata['sizes'][ $size_name ]['sources'] );553 $this->assertArrayHasKey( 'file', $metadata['sizes'][ $size_name ]['sources']['image/webp'] );554 $this->assertFileExists(555 path_join( $dirname, $metadata['sizes'][ $size_name ]['sources']['image/webp']['file'] )556 );557 }558 559 wp_delete_attachment( $attachment_id );560 561 foreach ( $sizes as $size_name ) {562 $this->assertFileDoesNotExist(563 path_join( $dirname, $metadata['sizes'][ $size_name ]['sources']['image/webp']['file'] )564 );565 }566 }567 568 /**569 * Test removing the attached WebP version if the attachment is force deleted but empty trash day is not defined.570 *571 * @ticket 55443572 */573 public function it_should_remove_the_attached_webp_version_if_the_attachment_is_force_deleted_but_empty_trash_day_is_not_defined() {574 // Make sure no editor is available.575 $attachment_id = $this->factory->attachment->create_upload_object(576 DIR_TESTDATA . '/images/test-image.jpg'577 );578 579 $file = get_attached_file( $attachment_id, true );580 $dirname = pathinfo( $file, PATHINFO_DIRNAME );581 582 $this->assertIsString( $file );583 $this->assertFileExists( $file );584 585 $metadata = wp_get_attachment_metadata( $attachment_id );586 587 $this->assertFileExists(588 path_join( $dirname, $metadata['sizes']['thumbnail']['sources']['image/webp']['file'] )589 );590 591 wp_delete_attachment( $attachment_id, true );592 593 $this->assertFileDoesNotExist(594 path_join( $dirname, $metadata['sizes']['thumbnail']['sources']['image/webp']['file'] )595 );596 }597 598 /**599 * Test removing the WebP version of the image if the image is force deleted and empty trash days is set to zero.600 *601 * @ticket 55443602 */603 public function it_should_remove_the_webp_version_of_the_image_if_the_image_is_force_deleted_and_empty_trash_days_is_set_to_zero() {604 // Make sure no editor is available.605 $attachment_id = $this->factory->attachment->create_upload_object(606 DIR_TESTDATA . '/images/test-image.jpg'607 );608 609 $file = get_attached_file( $attachment_id, true );610 $dirname = pathinfo( $file, PATHINFO_DIRNAME );611 612 $this->assertIsString( $file );613 $this->assertFileExists( $file );614 615 $metadata = wp_get_attachment_metadata( $attachment_id );616 617 $this->assertFileExists(618 path_join( $dirname, $metadata['sizes']['thumbnail']['sources']['image/webp']['file'] )619 );620 621 define( 'EMPTY_TRASH_DAYS', 0 );622 623 wp_delete_attachment( $attachment_id, true );624 625 $this->assertFileDoesNotExist(626 path_join( $dirname, $metadata['sizes']['thumbnail']['sources']['image/webp']['file'] )627 );628 }629 630 /**631 * Test avoiding the change of URLs of images that are not part of the media library.632 *633 * @ticket 55443634 */635 public function it_should_avoid_the_change_of_urls_of_images_that_are_not_part_of_the_media_library() {636 $paragraph = '<p>Donec accumsan, sapien et <img src="https://ia600200.us.archive.org/16/items/SPD-SLRSY-1867/hubblesite_2001_06.jpg">, id commodo nisi sapien et est. Mauris nisl odio, iaculis vitae pellentesque nec.</p>';637 638 $this->assertSame( $paragraph, webp_uploads_update_image_references( $paragraph ) );639 }640 641 /**642 * Test avoiding replacing not existing attachment IDs.643 *644 * @ticket 55443645 */646 public function it_should_avoid_replacing_not_existing_attachment_i_ds() {647 $paragraph = '<p>Donec accumsan, sapien et <img class="wp-image-0" src="https://ia600200.us.archive.org/16/items/SPD-SLRSY-1867/hubblesite_2001_06.jpg">, id commodo nisi sapien et est. Mauris nisl odio, iaculis vitae pellentesque nec.</p>';648 649 $this->assertSame( $paragraph, webp_uploads_update_image_references( $paragraph ) );650 }651 652 /**653 * Test preventing replacing a WebP image.654 *655 * @ticket 55443656 */657 public function it_should_test_preventing_replacing_a_webp_image() {658 $attachment_id = $this->factory->attachment->create_upload_object(659 DIR_TESTDATA . '/images/webp-lossy.webp'660 );661 662 $tag = wp_get_attachment_image( $attachment_id, 'medium', false, array( 'class' => "wp-image-{$attachment_id}" ) );663 664 $this->assertSame( $tag, webp_uploads_img_tag_update_mime_type( $tag, 'the_content', $attachment_id ) );665 }666 667 /**668 * Test preventing replacing a jpg image if the image does not have the target class name.669 *670 * @ticket 55443671 */672 public function it_should_test_preventing_replacing_a_jpg_image_if_the_image_does_not_have_the_target_class_name() {673 $attachment_id = $this->factory->attachment->create_upload_object(674 DIR_TESTDATA . '/images/test-image.jpg'675 );676 677 $tag = wp_get_attachment_image( $attachment_id, 'medium' );678 679 $this->assertSame( $tag, webp_uploads_update_image_references( $tag ) );680 }681 682 /**683 * Test replacing the references to a JPG image to a WebP version.684 *685 * @dataProvider provider_replace_images_with_different_extensions686 *687 * @ticket 55443688 */689 public function it_should_replace_the_references_to_a_jpg_image_to_a_webp_version( $image_path ) {690 $attachment_id = $this->factory->attachment->create_upload_object( $image_path );691 692 $tag = wp_get_attachment_image( $attachment_id, 'medium', false, array( 'class' => "wp-image-{$attachment_id}" ) );693 $expected_tag = $tag;694 $metadata = wp_get_attachment_metadata( $attachment_id );695 foreach ( $metadata['sizes'] as $size => $properties ) {696 $expected_tag = str_replace( $properties['sources']['image/jpeg']['file'], $properties['sources']['image/webp']['file'], $expected_tag );697 }698 699 $this->assertNotEmpty( $expected_tag );700 $this->assertNotSame( $tag, $expected_tag );701 $this->assertSame( $expected_tag, webp_uploads_img_tag_update_mime_type( $tag, 'the_content', $attachment_id ) );702 }703 704 public function provider_replace_images_with_different_extensions() {705 yield 'An image with a .jpg extension' => array( DIR_TESTDATA . '/images/test-image.jpg' );706 yield 'An image with a .jpeg extension' => array( DIR_TESTDATA . '/images/test-image.jpeg' );707 }708 709 /**710 * Test the full image size from the original mime type.711 *712 * @ticket 55443713 */714 public function it_should_contain_the_full_image_size_from_the_original_mime() {715 $attachment_id = $this->factory->attachment->create_upload_object(716 DIR_TESTDATA . '/images/test-image.jpg'717 );718 719 $tag = wp_get_attachment_image( $attachment_id, 'full', false, array( 'class' => "wp-image-{$attachment_id}" ) );720 721 $expected = array(722 'ext' => 'jpg',723 'type' => 'image/jpeg',724 );725 $this->assertSame( $expected, wp_check_filetype( get_attached_file( $attachment_id ) ) );726 $this->assertContains( wp_basename( get_attached_file( $attachment_id ) ), webp_uploads_img_tag_update_mime_type( $tag, 'the_content', $attachment_id ) );727 }728 729 /**730 * Test preventing replacing an image with no available sources.731 *732 * @ticket 55443733 */734 public function it_should_prevent_replacing_an_image_with_no_available_sources() {735 add_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );736 737 $attachment_id = $this->factory->attachment->create_upload_object( DIR_TESTDATA . '/images/test-image.jpg' );738 739 $tag = wp_get_attachment_image( $attachment_id, 'full', false, array( 'class' => "wp-image-{$attachment_id}" ) );740 $this->assertSame( $tag, webp_uploads_img_tag_update_mime_type( $tag, 'the_content', $attachment_id ) );741 }742 743 /**744 * Test preventing update not supported images with no available sources.745 *746 * @dataProvider provider_it_should_prevent_update_not_supported_images_with_no_available_sources747 *748 * @ticket 55443749 */750 public function it_should_prevent_update_not_supported_images_with_no_available_sources( $image_path ) {751 $attachment_id = $this->factory->attachment->create_upload_object( $image_path );752 753 $this->assertIsNumeric( $attachment_id );754 $tag = wp_get_attachment_image( $attachment_id, 'full', false, array( 'class' => "wp-image-{$attachment_id}" ) );755 756 $this->assertSame( $tag, webp_uploads_img_tag_update_mime_type( $tag, 'the_content', $attachment_id ) );757 }758 759 /**760 * Data provider for it_should_prevent_update_not_supported_images_with_no_available_sources.761 */762 public function provider_it_should_prevent_update_not_supported_images_with_no_available_sources() {763 yield 'PNG image' => array( DIR_TESTDATA . '/images/test-image.png' );764 yield 'GIFT image' => array( DIR_TESTDATA . '/images/test-image.gif' );765 }766 767 365 } -
trunk/tests/phpunit/tests/image/functions.php
r53751 r54085 640 640 } 641 641 642 // Use legacy JPEG output.643 add_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );644 645 642 $orig_file = DIR_TESTDATA . '/images/wordpress-gsoc-flyer.pdf'; 646 643 $test_file = get_temp_dir() . 'wordpress-gsoc-flyer.pdf'; … … 681 678 'mime-type' => 'image/jpeg', 682 679 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-232x300.jpg' ), 683 'sources' => array(684 'image/jpeg' => array(685 'file' => 'wordpress-gsoc-flyer-pdf-232x300.jpg',686 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-232x300.jpg' ),687 ),688 ),689 680 ), 690 681 'large' => array( … … 694 685 'mime-type' => 'image/jpeg', 695 686 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-791x1024.jpg' ), 696 'sources' => array(697 'image/jpeg' => array(698 'file' => 'wordpress-gsoc-flyer-pdf-791x1024.jpg',699 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-791x1024.jpg' ),700 ),701 ),702 687 ), 703 688 'thumbnail' => array( … … 707 692 'mime-type' => 'image/jpeg', 708 693 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-116x150.jpg' ), 709 'sources' => array(710 'image/jpeg' => array(711 'file' => 'wordpress-gsoc-flyer-pdf-116x150.jpg',712 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-116x150.jpg' ),713 ),714 ),715 694 ), 716 695 ), … … 724 703 unlink( $temp_dir . $size['file'] ); 725 704 } 726 remove_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );727 705 } 728 706 … … 738 716 739 717 update_option( 'medium_crop', 1 ); 740 741 // Use legacy JPEG output.742 add_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );743 718 744 719 $orig_file = DIR_TESTDATA . '/images/wordpress-gsoc-flyer.pdf'; … … 780 755 'mime-type' => 'image/jpeg', 781 756 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-300x300.jpg' ), 782 'sources' => array(783 'image/jpeg' => array(784 'file' => 'wordpress-gsoc-flyer-pdf-300x300.jpg',785 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-300x300.jpg' ),786 ),787 ),788 757 ), 789 758 'large' => array( … … 793 762 'mime-type' => 'image/jpeg', 794 763 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-791x1024.jpg' ), 795 'sources' => array(796 'image/jpeg' => array(797 'file' => 'wordpress-gsoc-flyer-pdf-791x1024.jpg',798 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-791x1024.jpg' ),799 ),800 ),801 802 764 ), 803 765 'thumbnail' => array( … … 807 769 'mime-type' => 'image/jpeg', 808 770 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-116x150.jpg' ), 809 'sources' => array(810 'image/jpeg' => array(811 'file' => 'wordpress-gsoc-flyer-pdf-116x150.jpg',812 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-116x150.jpg' ),813 ),814 ),815 771 ), 816 772 ), … … 824 780 unlink( $temp_dir . $size['file'] ); 825 781 } 826 remove_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );827 828 782 } 829 783 … … 835 789 $this->markTestSkipped( 'Rendering PDFs is not supported on this system.' ); 836 790 } 837 838 // Use legacy JPEG output.839 add_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );840 791 841 792 $orig_file = DIR_TESTDATA . '/images/wordpress-gsoc-flyer.pdf'; … … 871 822 'mime-type' => 'image/jpeg', 872 823 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-77x100.jpg' ), 873 'sources' => array(874 'image/jpeg' => array(875 'file' => 'wordpress-gsoc-flyer-pdf-77x100.jpg',876 'filesize' => wp_filesize( $temp_dir . 'wordpress-gsoc-flyer-pdf-77x100.jpg' ),877 ),878 ),879 824 ); 880 825 … … 892 837 unlink( $temp_dir . $size['file'] ); 893 838 } 894 remove_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );895 839 } 896 840 … … 1083 1027 ); 1084 1028 } 1085 1086 /**1087 * @ticket 554431088 */1089 public function test_wp_upload_image_mime_transforms_generates_webp_and_jpeg_for_both_by_default() {1090 $result = wp_upload_image_mime_transforms( 42 );1091 $this->assertArrayHasKey( 'image/jpeg', $result );1092 $this->assertArrayHasKey( 'image/webp', $result );1093 $this->assertSameSets( array( 'image/jpeg', 'image/webp' ), $result['image/jpeg'] );1094 $this->assertSameSets( array( 'image/jpeg', 'image/webp' ), $result['image/webp'] );1095 }1096 1097 /**1098 * @ticket 554431099 */1100 public function test_wp_upload_image_mime_transforms_filter_always_use_webp_instead_of_jpeg() {1101 add_filter(1102 'wp_upload_image_mime_transforms',1103 function( $transforms ) {1104 // Ensure JPG only results in WebP files.1105 $transforms['image/jpeg'] = array( 'image/webp' );1106 // Unset WebP since it does not need any transformation in that case.1107 unset( $transforms['image/webp'] );1108 return $transforms;1109 }1110 );1111 1112 $result = wp_upload_image_mime_transforms( 42 );1113 $this->assertArrayHasKey( 'image/jpeg', $result );1114 $this->assertArrayNotHasKey( 'image/webp', $result );1115 $this->assertSameSets( array( 'image/webp' ), $result['image/jpeg'] );1116 }1117 1118 /**1119 * @ticket 554431120 */1121 public function test_wp_upload_image_mime_transforms_filter_receives_parameters() {1122 $attachment_id = null;1123 add_filter(1124 'wp_upload_image_mime_transforms',1125 function( $transforms, $param1 ) use ( &$attachment_id ) {1126 $attachment_id = $param1;1127 return $transforms;1128 },1129 10,1130 21131 );1132 1133 wp_upload_image_mime_transforms( 23 );1134 $this->assertSame( 23, $attachment_id );1135 }1136 1137 /**1138 * @ticket 554431139 */1140 public function test_wp_upload_image_mime_transforms_filter_with_empty_array() {1141 add_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );1142 $result = wp_upload_image_mime_transforms( 42 );1143 $this->assertSame( array(), $result );1144 }1145 1146 /**1147 * @ticket 554431148 */1149 public function test_wp_upload_image_mime_transforms_filter_with_invalid_usage() {1150 $default = wp_upload_image_mime_transforms( 42 );1151 1152 add_filter( 'wp_upload_image_mime_transforms', '__return_false' );1153 $result = wp_upload_image_mime_transforms( 42 );1154 $this->assertSame( $default, $result );1155 }1156 1157 /**1158 * @ticket 554431159 */1160 public function test__wp_get_primary_and_additional_mime_types_default() {1161 $jpeg_file = DIR_TESTDATA . '/images/test-image-large.jpg';1162 1163 list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $jpeg_file, 42 );1164 $this->assertSame( 'image/jpeg', $primary_mime_type );1165 1166 // WebP may not be supported by the server, in which case it will be stripped from the results.1167 if ( wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {1168 $this->assertSame( array( 'image/webp' ), $additional_mime_types );1169 } else {1170 $this->assertSame( array(), $additional_mime_types );1171 }1172 }1173 1174 /**1175 * @ticket 554431176 */1177 public function test__wp_get_primary_and_additional_mime_types_prefer_original_mime() {1178 $jpeg_file = DIR_TESTDATA . '/images/test-image-large.jpg';1179 1180 // Set 'image/jpeg' only as secondary output MIME type.1181 // Still, because it is the original, it should be chosen as primary over 'image/webp'.1182 add_filter(1183 'wp_upload_image_mime_transforms',1184 function( $transforms ) {1185 $transforms['image/jpeg'] = array( 'image/webp', 'image/jpeg' );1186 return $transforms;1187 }1188 );1189 1190 list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $jpeg_file, 42 );1191 $this->assertSame( 'image/jpeg', $primary_mime_type );1192 1193 // WebP may not be supported by the server, in which case it will be stripped from the results.1194 if ( wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {1195 $this->assertSame( array( 'image/webp' ), $additional_mime_types );1196 } else {1197 $this->assertSame( array(), $additional_mime_types );1198 }1199 }1200 1201 /**1202 * @ticket 554431203 */1204 public function test__wp_get_primary_and_additional_mime_types_use_original_mime_when_no_transformation_rules() {1205 $jpeg_file = DIR_TESTDATA . '/images/test-image-large.jpg';1206 1207 // Strip all transformation rules.1208 add_filter( 'wp_upload_image_mime_transforms', '__return_empty_array' );1209 1210 list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $jpeg_file, 42 );1211 $this->assertSame( 'image/jpeg', $primary_mime_type );1212 $this->assertSame( array(), $additional_mime_types );1213 }1214 1215 /**1216 * @ticket 554431217 */1218 public function test__wp_get_primary_and_additional_mime_types_different_output_mime() {1219 $jpeg_file = DIR_TESTDATA . '/images/test-image-large.jpg';1220 1221 // Set 'image/webp' as the only output MIME type.1222 // In that case, JPEG is not generated at all, so WebP becomes the primary MIME type.1223 add_filter(1224 'wp_upload_image_mime_transforms',1225 function( $transforms ) {1226 $transforms['image/jpeg'] = array( 'image/webp' );1227 return $transforms;1228 }1229 );1230 1231 list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $jpeg_file, 42 );1232 1233 // WebP may not be supported by the server, in which case it will fall back to the original MIME type.1234 if ( wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {1235 $this->assertSame( 'image/webp', $primary_mime_type );1236 } else {1237 $this->assertSame( 'image/jpeg', $primary_mime_type );1238 }1239 1240 $this->assertSame( array(), $additional_mime_types );1241 }1242 1243 /**1244 * @ticket 554431245 */1246 public function test__wp_get_primary_and_additional_mime_types_different_output_mimes() {1247 $jpeg_file = DIR_TESTDATA . '/images/test-image-large.jpg';1248 1249 // Set 'image/webp' and 'image/avif' as output MIME types.1250 // In that case, JPEG is not generated at all, with WebP being the primary MIME type and AVIF the secondary.1251 add_filter(1252 'wp_upload_image_mime_transforms',1253 function( $transforms ) {1254 $transforms['image/jpeg'] = array( 'image/webp', 'image/avif' );1255 return $transforms;1256 }1257 );1258 1259 list( $primary_mime_type, $additional_mime_types ) = _wp_get_primary_and_additional_mime_types( $jpeg_file, 42 );1260 1261 // WebP may not be supported by the server, in which case it will fall back to the original MIME type.1262 if ( wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {1263 $this->assertSame( 'image/webp', $primary_mime_type );1264 } else {1265 $this->assertSame( 'image/jpeg', $primary_mime_type );1266 }1267 1268 // AVIF may not be supported by the server, in which case it will be stripped from the results.1269 if ( wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) {1270 $this->assertSame( array( 'image/avif' ), $additional_mime_types );1271 } else {1272 $this->assertSame( array(), $additional_mime_types );1273 }1274 }1275 1276 /**1277 * @ticket 554431278 * @dataProvider data__wp_filter_image_sizes_additional_mime_type_support1279 */1280 public function test__wp_filter_image_sizes_additional_mime_type_support( $input_size_data, $filter_callback, $expected_size_names ) {1281 remove_all_filters( 'wp_image_sizes_with_additional_mime_type_support' );1282 if ( $filter_callback ) {1283 add_filter( 'wp_image_sizes_with_additional_mime_type_support', $filter_callback );1284 }1285 1286 $expected_size_data = array_intersect_key( $input_size_data, array_flip( $expected_size_names ) );1287 1288 $output_size_data = _wp_filter_image_sizes_additional_mime_type_support( $input_size_data, 42 );1289 $this->assertEqualSetsWithIndex( $expected_size_data, $output_size_data );1290 }1291 1292 public function data__wp_filter_image_sizes_additional_mime_type_support() {1293 $thumbnail_data = array(1294 'width' => 150,1295 'height' => 150,1296 'crop' => true,1297 );1298 $medium_data = array(1299 'width' => 300,1300 'height' => 300,1301 'crop' => false,1302 );1303 $medium_large_data = array(1304 'width' => 768,1305 'height' => 0,1306 'crop' => false,1307 );1308 $large_data = array(1309 'width' => 1024,1310 'height' => 1024,1311 'crop' => false,1312 );1313 $custom_data = array(1314 'width' => 512,1315 'height' => 512,1316 'crop' => true,1317 );1318 1319 return array(1320 array(1321 array(1322 'thumbnail' => $thumbnail_data,1323 'medium' => $medium_data,1324 'medium_large' => $medium_large_data,1325 'large' => $large_data,1326 ),1327 null,1328 array( 'thumbnail', 'medium', 'medium_large', 'large' ),1329 ),1330 array(1331 array(1332 'thumbnail' => $thumbnail_data,1333 'medium' => $medium_data,1334 'custom' => $custom_data,1335 ),1336 null,1337 array( 'thumbnail', 'medium' ),1338 ),1339 array(1340 array(1341 'thumbnail' => $thumbnail_data,1342 'medium' => $medium_data,1343 'medium_large' => $medium_large_data,1344 'large' => $large_data,1345 ),1346 function( $enabled_sizes ) {1347 unset( $enabled_sizes['medium_large'], $enabled_sizes['large'] );1348 return $enabled_sizes;1349 },1350 array( 'thumbnail', 'medium' ),1351 ),1352 array(1353 array(1354 'thumbnail' => $thumbnail_data,1355 'medium' => $medium_data,1356 'medium_large' => $medium_large_data,1357 'large' => $large_data,1358 ),1359 function( $enabled_sizes ) {1360 $enabled_sizes['medium_large'] = false;1361 $enabled_sizes['large'] = false;1362 return $enabled_sizes;1363 },1364 array( 'thumbnail', 'medium' ),1365 ),1366 array(1367 array(1368 'thumbnail' => $thumbnail_data,1369 'medium' => $medium_data,1370 'custom' => $custom_data,1371 ),1372 function( $enabled_sizes ) {1373 unset( $enabled_sizes['medium'] );1374 $enabled_sizes['custom'] = true;1375 return $enabled_sizes;1376 },1377 array( 'thumbnail', 'custom' ),1378 ),1379 );1380 }1381 1382 /**1383 * Test the `_wp_maybe_scale_and_rotate_image()` function.1384 *1385 * @dataProvider data_test__wp_maybe_scale_and_rotate_image1386 *1387 * @ticket 554431388 */1389 public function test__wp_maybe_scale_and_rotate_image( $file, $imagesize, $mime_type, $expected ) {1390 if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) {1391 $this->markTestSkipped( sprintf( 'This test requires %s support.', $mime_type ) );1392 }1393 1394 $attributes = array( 'post_mime_type' => $mime_type );1395 $attachment_id = $this->factory->attachment->create_object( $file, 0, $attributes );1396 $exif_meta = wp_read_image_metadata( $file );1397 1398 list( $editor, $resized, $rotated ) = _wp_maybe_scale_and_rotate_image( $file, $attachment_id, $imagesize, $exif_meta, $mime_type );1399 1400 $this->assertSame( $expected['rotated'], $rotated );1401 $this->assertSame( $expected['resized'], $resized );1402 $this->assertSame( $expected['size'], $editor->get_size() );1403 }1404 1405 /**1406 * Data provider for the `test__wp_maybe_scale_and_rotate_image()` test.1407 *1408 * @return array1409 */1410 public function data_test__wp_maybe_scale_and_rotate_image() {1411 return array(1412 1413 // Image that will be scaled.1414 array(1415 DIR_TESTDATA . '/images/test-image-large.jpg',1416 array( 3000, 2250 ),1417 'image/jpeg',1418 array(1419 'rotated' => false,1420 'resized' => true,1421 'size' => array(1422 'width' => 2560,1423 'height' => 1920,1424 ),1425 ),1426 ),1427 1428 // Image that will not be scaled.1429 array(1430 DIR_TESTDATA . '/images/canola.jpg',1431 array( 640, 480 ),1432 'image/jpeg',1433 array(1434 'rotated' => false,1435 'resized' => false,1436 'size' => array(1437 'width' => 640,1438 'height' => 480,1439 ),1440 ),1441 ),1442 1443 // Image that will be flipped.1444 array(1445 DIR_TESTDATA . '/images/test-image-upside-down.jpg',1446 array( 600, 450 ),1447 'image/jpeg',1448 array(1449 'rotated' => true,1450 'resized' => false,1451 'size' => array(1452 'width' => 600,1453 'height' => 450,1454 ),1455 ),1456 ),1457 1458 // Image that will be rotated.1459 array(1460 DIR_TESTDATA . '/images/test-image-rotated-90ccw.jpg',1461 array( 1200, 1800 ),1462 'image/jpeg',1463 array(1464 'rotated' => true,1465 'resized' => false,1466 'size' => array(1467 'width' => 1800,1468 'height' => 1200,1469 ),1470 ),1471 ),1472 1473 // Image that will not be rotated - WebP Exif is not supported in PHP.1474 array(1475 DIR_TESTDATA . '/images/test-image-rotated-90cw.webp',1476 array( 1024, 768 ),1477 'image/webp',1478 array(1479 'rotated' => false,1480 'resized' => false,1481 'size' => array(1482 'width' => 1024,1483 'height' => 768,1484 ),1485 ),1486 ),1487 1488 );1489 }1490 1491 /**1492 * Test the `_wp_get_image_suffix()` function.1493 * @dataProvider data_test__wp_get_image_suffix1494 *1495 * @ticket 554431496 */1497 public function test__wp_get_image_suffix( $resized, $rotated, $expected ) {1498 $this->assertSame( $expected, _wp_get_image_suffix( $resized, $rotated ) );1499 }1500 1501 /**1502 * Data provider for the `test__wp_get_image_suffix()` test.1503 */1504 public function data_test__wp_get_image_suffix() {1505 return array(1506 array( false, false, '' ),1507 array( true, false, 'scaled' ),1508 array( false, true, 'rotated' ),1509 array( true, true, 'scaled' ),1510 );1511 }1512 1029 } -
trunk/tests/phpunit/tests/media.php
r53920 r54085 2256 2256 add_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' ); 2257 2257 add_filter( 'wp_img_tag_add_loading_attr', '__return_false' ); 2258 add_filter( 'wp_content_image_mimes', '__return_empty_array' );2259 2258 2260 2259 $this->assertSame( $content_filtered, wp_filter_content_tags( $content_unfiltered ) ); … … 2262 2261 remove_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' ); 2263 2262 remove_filter( 'wp_img_tag_add_loading_attr', '__return_false' ); 2264 remove_filter( 'wp_content_image_mimes', '__return_empty_array' );2265 2266 2263 } 2267 2264 … … 2297 2294 $img = wp_img_tag_add_decoding_attr( $img, 'the_content' ); 2298 2295 $img = preg_replace( '|<img ([^>]+) />|', '<img $1 ' . 'srcset="image2x.jpg 2x" />', $img ); 2299 add_filter( 'wp_content_image_mimes', '__return_empty_array' );2300 2296 2301 2297 // The content filter should return the image unchanged. 2302 2298 $this->assertSame( $img, wp_filter_content_tags( $img ) ); 2303 2304 remove_filter( 'wp_content_image_mimes', '__return_empty_array' );2305 2299 } 2306 2300 … … 2372 2366 add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); 2373 2367 add_filter( 'wp_img_tag_add_decoding_attr', '__return_false' ); 2374 add_filter( 'wp_content_image_mimes', '__return_empty_array' );2375 2368 2376 2369 add_filter( … … 2435 2428 */ 2436 2429 public function test_wp_filter_content_tags_schemes() { 2437 add_filter( 'wp_content_image_mimes', '__return_empty_array' );2438 2430 $image_meta = wp_get_attachment_metadata( self::$large_id ); 2439 2431 $size_array = $this->get_image_size_array_from_meta( $image_meta, 'medium' ); … … 2481 2473 2482 2474 $this->assertSame( $expected, $actual ); 2483 remove_filter( 'wp_content_image_mimes', '__return_empty_array' );2484 2475 } 2485 2476 … … 2975 2966 add_filter( 'wp_img_tag_add_loading_attr', '__return_false' ); 2976 2967 add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); 2977 add_filter( 'wp_content_image_mimes', '__return_empty_array' );2978 2968 2979 2969 $this->assertSame( $content_filtered, wp_filter_content_tags( $content_unfiltered ) ); … … 2981 2971 remove_filter( 'wp_img_tag_add_loading_attr', '__return_false' ); 2982 2972 remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); 2983 remove_filter( 'wp_content_image_mimes', '__return_empty_array' );2984 2973 } 2985 2974 … … 3057 3046 add_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' ); 3058 3047 add_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); 3059 add_filter( 'wp_content_image_mimes', '__return_empty_array' );3060 3048 3061 3049 $this->assertSame( $content_filtered, wp_filter_content_tags( $content_unfiltered ) ); … … 3063 3051 remove_filter( 'wp_img_tag_add_width_and_height_attr', '__return_false' ); 3064 3052 remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); 3065 remove_filter( 'wp_content_image_mimes', '__return_empty_array' );3066 3053 } 3067 3054 … … 3092 3079 add_filter( 'wp_lazy_loading_enabled', '__return_true' ); 3093 3080 3094 add_filter( 'wp_content_image_mimes', '__return_empty_array' );3095 3096 3081 $this->assertSame( $content_filtered, wp_filter_content_tags( $content_unfiltered ) ); 3097 3082 remove_filter( 'wp_lazy_loading_enabled', '__return_true' ); 3098 3083 remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); 3099 remove_filter( 'wp_content_image_mimes', '__return_empty_array' );3100 3101 3084 } 3102 3085 … … 3123 3106 add_filter( 'wp_lazy_loading_enabled', '__return_false' ); 3124 3107 3125 add_filter( 'wp_content_image_mimes', '__return_empty_array' );3126 3127 3108 $this->assertSame( $content, wp_filter_content_tags( $content ) ); 3128 3109 remove_filter( 'wp_lazy_loading_enabled', '__return_false' ); 3129 3110 remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); 3130 remove_filter( 'wp_content_image_mimes', '__return_empty_array' );3131 3111 } 3132 3112 … … 3554 3534 function test_wp_filter_content_tags_with_wp_get_loading_attr_default() { 3555 3535 global $wp_query, $wp_the_query; 3556 add_filter( 'wp_content_image_mimes', '__return_empty_array' );3557 3536 3558 3537 $img1 = get_image_tag( self::$large_id, '', '', '', 'large' ); … … 3590 3569 remove_filter( 'wp_img_tag_add_srcset_and_sizes_attr', '__return_false' ); 3591 3570 } 3592 remove_filter( 'wp_content_image_mimes', '__return_empty_array' );3593 3571 3594 3572 // After filtering, the first image should not be lazy-loaded while the other ones should be. … … 3640 3618 remove_filter( 'wp_omit_loading_attr_threshold', '__return_null', 100 ); 3641 3619 } 3642 3643 /**3644 * @ticket 554433645 */3646 public function test_wp_image_use_alternate_mime_types_replaces_jpg_with_webp_where_available() {3647 if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {3648 $this->markTestSkipped( 'This test requires WebP support.' );3649 }3650 3651 // The attachment $large_id is a JPEG image, so it gets WebP files generated by default.3652 $tag = wp_get_attachment_image( self::$large_id, 'full' );3653 $expected_tag = $tag;3654 3655 $metadata = wp_get_attachment_metadata( self::$large_id );3656 foreach ( $metadata['sizes'] as $size => $properties ) {3657 // Some sizes may not have WebP if the WebP file is larger than the JPEG for the size.3658 if ( ! isset( $properties['sources']['image/webp'] ) ) {3659 continue;3660 }3661 $expected_tag = str_replace( $properties['sources']['image/jpeg']['file'], $properties['sources']['image/webp']['file'], $expected_tag );3662 }3663 // Same applies to the full size.3664 if ( isset( $metadata['sources']['image/webp'] ) ) {3665 $expected_tag = str_replace( $metadata['sources']['image/jpeg']['file'], $metadata['sources']['image/webp']['file'], $expected_tag );3666 }3667 3668 $this->assertNotSame( $tag, $expected_tag );3669 $this->assertSame( $expected_tag, wp_image_use_alternate_mime_types( $tag, 'the_content', self::$large_id ) );3670 }3671 3672 /**3673 * @ticket 554433674 */3675 public function test_wp_image_use_alternate_mime_types_does_not_replace_jpg_when_webp_is_not_available() {3676 if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {3677 $this->markTestSkipped( 'This test requires WebP support.' );3678 }3679 3680 // The attachment $large_id is a JPEG image, so it gets WebP files generated by default.3681 $tag = wp_get_attachment_image( self::$large_id, 'full' );3682 3683 // Update attachment metadata as if the image had no WebP available for any sub-sizes and the full size.3684 $metadata = wp_get_attachment_metadata( self::$large_id );3685 foreach ( $metadata['sizes'] as $size => $properties ) {3686 unset( $metadata['sizes'][ $size ]['sources']['image/webp'] );3687 }3688 unset( $metadata['sources']['image/webp'] );3689 wp_update_attachment_metadata( self::$large_id, $metadata );3690 3691 $this->assertSame( $tag, wp_image_use_alternate_mime_types( $tag, 'the_content', self::$large_id ) );3692 }3693 3694 /**3695 * @ticket 554433696 */3697 public function test_wp_image_use_alternate_mime_types_still_replaces_jpg_subsizes_when_webp_is_not_available_for_full_size() {3698 if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {3699 $this->markTestSkipped( 'This test requires WebP support.' );3700 }3701 3702 // The attachment $large_id is a JPEG image, so it gets WebP files generated by default.3703 $tag = wp_get_attachment_image( self::$large_id, 'full' );3704 $expected_tag = $tag;3705 3706 // Update attachment metadata as if the image had no WebP available for the full size.3707 $metadata = wp_get_attachment_metadata( self::$large_id );3708 unset( $metadata['sources']['image/webp'] );3709 wp_update_attachment_metadata( self::$large_id, $metadata );3710 3711 foreach ( $metadata['sizes'] as $size => $properties ) {3712 // Some sizes may not have WebP if the WebP file is larger than the JPEG for the size.3713 if ( ! isset( $properties['sources']['image/webp'] ) ) {3714 continue;3715 }3716 $expected_tag = str_replace( $properties['sources']['image/jpeg']['file'], $properties['sources']['image/webp']['file'], $expected_tag );3717 }3718 3719 $this->assertNotSame( $tag, $expected_tag );3720 $this->assertSame( $expected_tag, wp_image_use_alternate_mime_types( $tag, 'the_content', self::$large_id ) );3721 }3722 3723 /**3724 * @ticket 554433725 */3726 public function test_wp_image_use_alternate_mime_types_respects_wp_content_image_mimes_filter() {3727 if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {3728 $this->markTestSkipped( 'This test requires WebP support.' );3729 }3730 3731 // The attachment $large_id is a JPEG image, so it gets WebP files generated by default.3732 $tag = wp_get_attachment_image( self::$large_id, 'full' );3733 3734 // Invalid filter value results in no changes to content.3735 add_filter( 'wp_content_image_mimes', '__return_false' );3736 $this->assertSame( $tag, wp_image_use_alternate_mime_types( $tag, 'the_content', self::$large_id ) );3737 3738 // Empty array results in no changes to content.3739 add_filter( 'wp_content_image_mimes', '__return_empty_array' );3740 $this->assertSame( $tag, wp_image_use_alternate_mime_types( $tag, 'the_content', self::$large_id ) );3741 3742 // Preferring JPEG over WebP results in no changes to content.3743 add_filter(3744 'wp_content_image_mimes',3745 function() {3746 return array( 'image/jpeg', 'image/webp' );3747 }3748 );3749 $this->assertSame( $tag, wp_image_use_alternate_mime_types( $tag, 'the_content', self::$large_id ) );3750 }3751 3752 /**3753 * @ticket 554433754 */3755 public function test__wp_in_front_end_context_without_wp_query() {3756 unset( $GLOBALS['wp_query'] );3757 3758 $this->assertFalse( _wp_in_front_end_context() );3759 }3760 3761 /**3762 * @ticket 554433763 */3764 public function test__wp_in_front_end_context_with_feed() {3765 remove_all_actions( 'template_redirect' );3766 do_action( 'template_redirect' );3767 $GLOBALS['wp_query']->is_feed = true;3768 3769 $this->assertFalse( _wp_in_front_end_context() );3770 }3771 3772 /**3773 * @ticket 554433774 */3775 public function test__wp_in_front_end_context_before_and_after_template_redirect() {3776 $result = _wp_in_front_end_context();3777 3778 remove_all_actions( 'template_redirect' );3779 do_action( 'template_redirect' );3780 3781 $this->assertFalse( $result );3782 $this->assertTrue( _wp_in_front_end_context() );3783 }3784 3785 /**3786 * @ticket 554433787 */3788 public function test__wp_in_front_end_context_within_wp_head() {3789 remove_all_actions( 'template_redirect' );3790 do_action( 'template_redirect' );3791 3792 // Call function within a 'wp_head' callback.3793 remove_all_actions( 'wp_head' );3794 $result = null;3795 add_action(3796 'wp_head',3797 function() use ( &$result ) {3798 $result = _wp_in_front_end_context();3799 }3800 );3801 do_action( 'wp_head' );3802 3803 $this->assertFalse( $result );3804 }3805 3620 } 3806 3621 -
trunk/tests/phpunit/tests/rest-api/rest-attachments-controller.php
r54041 r54085 2263 2263 ); 2264 2264 } 2265 2266 /**2267 * @ticket 554432268 */2269 public function test_image_sources_to_rest_response() {2270 2271 $attachment_id = self::factory()->attachment->create_upload_object( $this->test_file );2272 $metadata = wp_get_attachment_metadata( $attachment_id );2273 $request = new WP_REST_Request();2274 $request['id'] = $attachment_id;2275 $controller = new WP_REST_Attachments_Controller( 'attachment' );2276 $response = $controller->get_item( $request );2277 2278 $this->assertNotWPError( $response );2279 2280 $data = $response->get_data();2281 $mime_types = array(2282 'image/jpeg',2283 );2284 2285 if ( wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {2286 array_push( $mime_types, 'image/webp' );2287 }2288 2289 foreach ( $data['media_details']['sizes'] as $size_name => $properties ) {2290 if ( ! isset( $metadata['sizes'][ $size_name ]['sources'] ) ) {2291 continue;2292 }2293 2294 $this->assertArrayHasKey( 'sources', $properties );2295 $this->assertIsArray( $properties['sources'] );2296 2297 foreach ( $mime_types as $mime_type ) {2298 $this->assertArrayHasKey( $mime_type, $properties['sources'] );2299 $this->assertArrayHasKey( 'filesize', $properties['sources'][ $mime_type ] );2300 $this->assertArrayHasKey( 'file', $properties['sources'][ $mime_type ] );2301 $this->assertArrayHasKey( 'source_url', $properties['sources'][ $mime_type ] );2302 $this->assertNotFalse( filter_var( $properties['sources'][ $mime_type ]['source_url'], FILTER_VALIDATE_URL ) );2303 }2304 }2305 $this->assertArrayNotHasKey( 'sources', $data['media_details'] );2306 }2307 2265 }
Note: See TracChangeset
for help on using the changeset viewer.