From 57cfc272f7530726f024d4aa8f91539764f78589 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Fri, 11 Mar 2022 12:20:37 +0200 Subject: [PATCH 01/18] Rename the webp_uploads_supported_image_mime_transforms filter to be webp_uploads_upload_image_mime_transforms. --- modules/images/webp-uploads/load.php | 13 +++---------- .../images/webp-uploads/webp-uploads-test.php | 8 ++++---- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 939501d3fc..6ee87e8f05 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -223,7 +223,6 @@ function webp_uploads_get_supported_image_mime_transforms() { 'image/webp' => array( 'image/jpeg' ), ); - $valid_transforms = array(); /** * Filter to allow the definition of a custom mime types, in which a defined mime type * can be transformed and provide a wide range of mime types. @@ -232,15 +231,9 @@ function webp_uploads_get_supported_image_mime_transforms() { * * @param array $image_mime_transforms A map with the valid mime transforms. */ - $transforms = (array) apply_filters( 'webp_uploads_supported_image_mime_transforms', $image_mime_transforms ); - // Remove any invalid transform, by making sure all the transform values are arrays. - foreach ( $transforms as $mime => $list_transforms ) { - if ( ! is_array( $list_transforms ) ) { - continue; - } - $valid_transforms[ $mime ] = $list_transforms; - } - return $valid_transforms; + $transforms = (array) apply_filters( 'webp_uploads_upload_image_mime_transforms', $image_mime_transforms ); + + return array_filter( $transforms, 'is_array' ); } /** diff --git a/tests/modules/images/webp-uploads/webp-uploads-test.php b/tests/modules/images/webp-uploads/webp-uploads-test.php index 4aa3ea0f7e..5765c98273 100644 --- a/tests/modules/images/webp-uploads/webp-uploads-test.php +++ b/tests/modules/images/webp-uploads/webp-uploads-test.php @@ -66,7 +66,7 @@ public function provider_image_with_default_behaviors_during_upload() { * @test */ public function it_should_not_create_the_sources_property_if_no_transform_is_provided() { - add_filter( 'webp_uploads_supported_image_mime_transforms', '__return_empty_array' ); + add_filter( 'webp_uploads_upload_image_mime_transforms', '__return_empty_array' ); $attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' @@ -88,7 +88,7 @@ public function it_should_not_create_the_sources_property_if_no_transform_is_pro */ public function it_should_create_the_sources_property_when_no_transform_is_available() { add_filter( - 'webp_uploads_supported_image_mime_transforms', + 'webp_uploads_upload_image_mime_transforms', function () { return array( 'image/jpeg' => array() ); } @@ -124,7 +124,7 @@ function () { */ public function it_should_not_create_the_sources_property_if_the_mime_is_not_specified_on_the_transforms_images() { add_filter( - 'webp_uploads_supported_image_mime_transforms', + 'webp_uploads_upload_image_mime_transforms', function () { return array( 'image/jpeg' => array() ); } @@ -589,7 +589,7 @@ public function it_should_replace_all_the_images_including_the_full_size_image() * @test */ public function it_should_prevent_replacing_an_image_with_no_available_sources() { - add_filter( 'webp_uploads_supported_image_mime_transforms', '__return_empty_array' ); + add_filter( 'webp_uploads_upload_image_mime_transforms', '__return_empty_array' ); $attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/car.jpeg' ); From c1550b23400d3171da32b182504324bf47aac9ba Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Fri, 11 Mar 2022 16:09:14 +0200 Subject: [PATCH 02/18] Update the webp_uploads_create_sources_property function to return early if only the original mime type is needed. --- modules/images/webp-uploads/load.php | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 6ee87e8f05..767e49c139 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -30,9 +30,18 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) { // This should take place only on the JPEG image. $valid_mime_transforms = webp_uploads_get_supported_image_mime_transforms(); + // Not a supported mime type to create the sources property. $mime_type = get_post_mime_type( $attachment_id ); - if ( ! isset( $valid_mime_transforms[ $mime_type ] ) ) { + if ( ! isset( $valid_mime_transforms[ $mime_type ] ) || ! is_array( $valid_mime_transforms[ $mime_type ] ) ) { + return $metadata; + } + + // Don't do anything if only the original mime type is needed. + if ( + 1 === count( $valid_mime_transforms[ $mime_type ] ) && + current( $valid_mime_transforms[ $mime_type ] ) === $mime_type + ) { return $metadata; } @@ -219,8 +228,8 @@ function webp_uploads_generate_image_size( $attachment_id, $size, $mime ) { */ function webp_uploads_get_supported_image_mime_transforms() { $image_mime_transforms = array( - 'image/jpeg' => array( 'image/webp' ), - 'image/webp' => array( 'image/jpeg' ), + 'image/jpeg' => array( 'image/jpeg', 'image/webp' ), + 'image/webp' => array( 'image/webp', 'image/jpeg' ), ); /** From 04e67a6ed1ed52966155e5f28ab04bda216f1f0d Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Fri, 11 Mar 2022 16:26:02 +0200 Subject: [PATCH 03/18] Add a new hook for the image_editor_output_format filter to select the correct mime type for new uploads. --- modules/images/webp-uploads/load.php | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 767e49c139..b11c80c2bc 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -166,6 +166,56 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) add_filter( 'wp_generate_attachment_metadata', 'webp_uploads_create_sources_property', 10, 2 ); +/** + * Filter the image editor default output format mapping to select the most appropriate + * output format depending on desired output formats and supported mime types by the image + * editor. + * + * @since n.e.x.t + * + * @param string $output_format The image editor default output format mapping. + * @param string $filename Path to the image. + * @param string $mime_type The source image mime type. + * @return string The new output format mapping. + */ +function webp_uploads_filter_image_editor_output_format( $output_format, $filename, $mime_type ) { + // Skip conversion when creating the `-scaled` image (for large image uploads). + if ( preg_match( '/-scaled\..{3}.?$/', $filename ) ) { + return $output_format; + } + + // Use the original mime type if this type is allowed. + $valid_mime_transforms = webp_uploads_get_supported_image_mime_transforms(); + if ( + ! isset( $valid_mime_transforms[ $mime_type ] ) || + ! is_array( $valid_mime_transforms[ $mime_type ] ) || + in_array( $mime_type, $valid_mime_transforms[ $mime_type ] ) + ) { + return $output_format; + } + + $new_mime_type = null; + + // Find the first supported mime type by the image editor to use it as the default one. + foreach ( $valid_mime_transforms[ $mime_type ] as $target_mime ) { + if ( wp_image_editor_supports( array( 'mime_type' => $target_mime ) ) ) { + $new_mime_type = $target_mime; + break; + } + } + + // Leave the original mime type if there is no other mime type supported by the image editor. + if ( empty( $new_mime_type ) ) { + return $output_format; + } + + $output_format[ $mime_type ] = $new_mime_type; + + return $output_format; +} + +add_filter( 'image_editor_output_format', 'webp_uploads_filter_image_editor_output_format', 10, 3 ); + /** * Creates a new image based of the specified attachment with a defined mime type * this image would be stored in the same place as the provided size name inside the From daf862020406a05d93eb773222c5aa4f9f509ffc Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Fri, 11 Mar 2022 16:31:08 +0200 Subject: [PATCH 04/18] Fix the phpcs issue. --- modules/images/webp-uploads/load.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index b11c80c2bc..1af51a7759 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -189,7 +189,7 @@ function webp_uploads_filter_image_editor_output_format( $output_format, $filena if ( ! isset( $valid_mime_transforms[ $mime_type ] ) || ! is_array( $valid_mime_transforms[ $mime_type ] ) || - in_array( $mime_type, $valid_mime_transforms[ $mime_type ] ) + in_array( $mime_type, $valid_mime_transforms[ $mime_type ], true ) ) { return $output_format; } From 579f7a1c9b1199bee849e3b2f72f3920463da8fc Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Fri, 11 Mar 2022 17:12:48 +0200 Subject: [PATCH 05/18] Update phpdoc for the webp_uploads_upload_image_mime_transforms filter. --- modules/images/webp-uploads/load.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 1af51a7759..a46577caaf 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -285,6 +285,10 @@ function webp_uploads_get_supported_image_mime_transforms() { /** * Filter to allow the definition of a custom mime types, in which a defined mime type * can be transformed and provide a wide range of mime types. + * + * The order of supported mime types matters. If the original mime type of the uploaded image + * is not needed, then the first mime type in the list supported by the image editor will be + * selected for the default subsizes. * * @since 1.0.0 * From 87cc7f2dcc88d6f446a3a86a49ba22d65e85ce17 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Fri, 11 Mar 2022 17:16:47 +0200 Subject: [PATCH 06/18] Fix formatting issue. --- modules/images/webp-uploads/load.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index a46577caaf..9851835107 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -285,7 +285,7 @@ function webp_uploads_get_supported_image_mime_transforms() { /** * Filter to allow the definition of a custom mime types, in which a defined mime type * can be transformed and provide a wide range of mime types. - * + * * The order of supported mime types matters. If the original mime type of the uploaded image * is not needed, then the first mime type in the list supported by the image editor will be * selected for the default subsizes. From 0b3b687448a8c4e26c6ac9152b186e83dc5fc96a Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Sat, 12 Mar 2022 10:26:47 +0200 Subject: [PATCH 07/18] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Crisoforo Gaspar Hernández --- modules/images/webp-uploads/load.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 9851835107..6dd04c4750 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -205,7 +205,7 @@ function webp_uploads_filter_image_editor_output_format( $output_format, $filena } // Leave the original mime type if there is no other mime type supported by the image editor. - if ( empty( $new_mime_type ) ) { + if ( null === $new_mime_type ) { return $output_format; } From dd30d0f69611a3fdbad447b4fb3779f947569e5c Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Sat, 12 Mar 2022 10:36:35 +0200 Subject: [PATCH 08/18] Update the webp_uploads_get_supported_image_mime_transforms function to return an empty array if a wrong value is returned from the filter. --- modules/images/webp-uploads/load.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 6dd04c4750..eb06facf95 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -33,7 +33,7 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) // Not a supported mime type to create the sources property. $mime_type = get_post_mime_type( $attachment_id ); - if ( ! isset( $valid_mime_transforms[ $mime_type ] ) || ! is_array( $valid_mime_transforms[ $mime_type ] ) ) { + if ( ! isset( $valid_mime_transforms[ $mime_type ] ) ) { return $metadata; } @@ -188,7 +188,6 @@ function webp_uploads_filter_image_editor_output_format( $output_format, $filena $valid_mime_transforms = webp_uploads_get_supported_image_mime_transforms(); if ( ! isset( $valid_mime_transforms[ $mime_type ] ) || - ! is_array( $valid_mime_transforms[ $mime_type ] ) || in_array( $mime_type, $valid_mime_transforms[ $mime_type ], true ) ) { return $output_format; @@ -296,6 +295,11 @@ function webp_uploads_get_supported_image_mime_transforms() { */ $transforms = (array) apply_filters( 'webp_uploads_upload_image_mime_transforms', $image_mime_transforms ); + // Return an empty array if non-array result is returned from the filter. + if ( ! is_array( $transforms ) ) { + return array(); + } + return array_filter( $transforms, 'is_array' ); } From a8911bcbf48b026532b1e3f9cbd193398f1c6417 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Sat, 12 Mar 2022 10:41:17 +0200 Subject: [PATCH 09/18] Remove "-scaled" condition. --- modules/images/webp-uploads/load.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index eb06facf95..d2624d371e 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -179,11 +179,6 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) * @return string The new output format mapping. */ function webp_uploads_filter_image_editor_output_format( $output_format, $filename, $mime_type ) { - // Skip conversion when creating the `-scaled` image (for large image uploads). - if ( preg_match( '/-scaled\..{3}.?$/', $filename ) ) { - return $output_format; - } - // Use the original mime type if this type is allowed. $valid_mime_transforms = webp_uploads_get_supported_image_mime_transforms(); if ( From f11853793b112cfaccaf69de5af2f3c432478cd6 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Tue, 15 Mar 2022 15:29:49 +0200 Subject: [PATCH 10/18] Address code review feedback. --- modules/images/webp-uploads/load.php | 41 ++++++++-------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 44e6e839bd..a54558e29f 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -11,8 +11,8 @@ /** * Hook called by `wp_generate_attachment_metadata` to create the `sources` property for every image * size, the sources' property would create a new image size with all the mime types specified in - * `webp_uploads_get_supported_image_mime_transforms`. If the original image is one of the mimes from - * `webp_uploads_get_supported_image_mime_transforms` the image is just added to the `sources` property and not + * `webp_uploads_get_upload_image_mime_transforms`. If the original image is one of the mimes from + * `webp_uploads_get_upload_image_mime_transforms` the image is just added to the `sources` property and not * created again. If the uploaded attachment is not a supported mime by this function, the hook does not alter the * metadata of the attachment. In addition to every single size the `sources` property is added at the * top level of the image metadata to store the references for all the mime types for the `full` size image of the @@ -21,7 +21,7 @@ * @since 1.0.0 * * @see wp_generate_attachment_metadata() - * @see webp_uploads_get_supported_image_mime_transforms() + * @see webp_uploads_get_upload_image_mime_transforms() * * @param array $metadata An array with the metadata from this attachment. * @param int $attachment_id The ID of the attachment where the hook was dispatched. @@ -29,7 +29,7 @@ */ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) { // This should take place only on the JPEG image. - $valid_mime_transforms = webp_uploads_get_supported_image_mime_transforms(); + $valid_mime_transforms = webp_uploads_get_upload_image_mime_transforms(); // Not a supported mime type to create the sources property. $mime_type = get_post_mime_type( $attachment_id ); @@ -37,14 +37,6 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) return $metadata; } - // Don't do anything if only the original mime type is needed. - if ( - 1 === count( $valid_mime_transforms[ $mime_type ] ) && - current( $valid_mime_transforms[ $mime_type ] ) === $mime_type - ) { - return $metadata; - } - $file = get_attached_file( $attachment_id, true ); // File does not exist. if ( ! file_exists( $file ) ) { @@ -180,7 +172,7 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) */ function webp_uploads_filter_image_editor_output_format( $output_format, $filename, $mime_type ) { // Use the original mime type if this type is allowed. - $valid_mime_transforms = webp_uploads_get_supported_image_mime_transforms(); + $valid_mime_transforms = webp_uploads_get_upload_image_mime_transforms(); if ( ! isset( $valid_mime_transforms[ $mime_type ] ) || in_array( $mime_type, $valid_mime_transforms[ $mime_type ], true ) @@ -188,23 +180,14 @@ function webp_uploads_filter_image_editor_output_format( $output_format, $filena return $output_format; } - $new_mime_type = null; - // Find the first supported mime type by the image editor to use it as the default one. foreach ( $valid_mime_transforms[ $mime_type ] as $target_mime ) { if ( wp_image_editor_supports( array( 'mime_type' => $target_mime ) ) ) { - $new_mime_type = $target_mime; + $output_format[ $mime_type ] = $target_mime; break; } } - // Leave the original mime type if there is no other mime type supported by the image editor. - if ( null === $new_mime_type ) { - return $output_format; - } - - $output_format[ $mime_type ] = $new_mime_type; - return $output_format; } @@ -270,8 +253,8 @@ function webp_uploads_generate_image_size( $attachment_id, $size, $mime ) { * * @return array> An array of valid mime types, where the key is the mime type and the value is the extension type. */ -function webp_uploads_get_supported_image_mime_transforms() { - $image_mime_transforms = array( +function webp_uploads_get_upload_image_mime_transforms() { + $default_transforms = array( 'image/jpeg' => array( 'image/jpeg', 'image/webp' ), 'image/webp' => array( 'image/webp', 'image/jpeg' ), ); @@ -286,13 +269,13 @@ function webp_uploads_get_supported_image_mime_transforms() { * * @since 1.0.0 * - * @param array $image_mime_transforms A map with the valid mime transforms. + * @param array $default_transforms A map with the valid mime transforms. */ - $transforms = (array) apply_filters( 'webp_uploads_upload_image_mime_transforms', $image_mime_transforms ); + $transforms = (array) apply_filters( 'webp_uploads_upload_image_mime_transforms', $default_transforms ); - // Return an empty array if non-array result is returned from the filter. + // Return the default mime transforms if a non-array result is returned from the filter. if ( ! is_array( $transforms ) ) { - return array(); + return $default_transforms; } return array_filter( $transforms, 'is_array' ); From 401ecd6da8c34fbb02bacbc34c3f63dc7fe1fb9e Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 16 Mar 2022 15:30:56 +0200 Subject: [PATCH 11/18] Update formatting. --- modules/images/webp-uploads/load.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index a54558e29f..2f8981e60f 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -155,7 +155,6 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) return $metadata; } - add_filter( 'wp_generate_attachment_metadata', 'webp_uploads_create_sources_property', 10, 2 ); /** @@ -190,7 +189,6 @@ function webp_uploads_filter_image_editor_output_format( $output_format, $filena return $output_format; } - add_filter( 'image_editor_output_format', 'webp_uploads_filter_image_editor_output_format', 10, 3 ); /** @@ -454,7 +452,6 @@ function webp_uploads_remove_sources_files( $attachment_id ) { wp_delete_file_from_directory( $full_size_file, $intermediate_dir ); } } - add_action( 'delete_attachment', 'webp_uploads_remove_sources_files', 10, 1 ); /** @@ -501,7 +498,6 @@ function webp_uploads_wp_get_missing_image_subsizes( $missing_sizes, $image_meta return array(); } - add_filter( 'wp_get_missing_image_subsizes', 'webp_uploads_wp_get_missing_image_subsizes', 10, 3 ); /** @@ -562,6 +558,7 @@ function webp_uploads_update_image_references( $content ) { return $content; } +add_filter( 'the_content', 'webp_uploads_update_image_references', 10 ); /** * Finds all the urls with *.jpg and *.jpeg extension and updates with *.webp version for the provided image @@ -639,5 +636,3 @@ function webp_uploads_img_tag_update_mime_type( $image, $context, $attachment_id return $image; } - -add_filter( 'the_content', 'webp_uploads_update_image_references', 10 ); From 66fea390bc6ae9d10ecf9d08f157c2e110cf66c5 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 16 Mar 2022 18:27:00 +0200 Subject: [PATCH 12/18] Refactor webp-uploads tests by moving the same checks into separate constraints. --- composer.json | 5 + .../images/webp-uploads/webp-uploads-test.php | 84 +++-------- tests/utils/Constraint/ImageHasSizeSource.php | 67 +++++++++ tests/utils/Constraint/ImageHasSource.php | 130 ++++++++++++++++++ tests/utils/TestCase/ImagesTestCase.php | 79 +++++++++++ 5 files changed, 303 insertions(+), 62 deletions(-) create mode 100644 tests/utils/Constraint/ImageHasSizeSource.php create mode 100644 tests/utils/Constraint/ImageHasSource.php create mode 100644 tests/utils/TestCase/ImagesTestCase.php diff --git a/composer.json b/composer.json index 04a30aae22..8748adc857 100644 --- a/composer.json +++ b/composer.json @@ -34,5 +34,10 @@ "dealerdirect/phpcodesniffer-composer-installer": true, "composer/installers": true } + }, + "autoload-dev": { + "psr-4": { + "PerformanceLab\\Tests\\": "tests/utils" + } } } diff --git a/tests/modules/images/webp-uploads/webp-uploads-test.php b/tests/modules/images/webp-uploads/webp-uploads-test.php index 3fe1bee9df..ca71d43698 100644 --- a/tests/modules/images/webp-uploads/webp-uploads-test.php +++ b/tests/modules/images/webp-uploads/webp-uploads-test.php @@ -6,7 +6,9 @@ * @group webp-uploads */ -class WebP_Uploads_Tests extends WP_UnitTestCase { +use PerformanceLab\Tests\TestCase\ImagesTestCase; + +class WebP_Uploads_Tests extends ImagesTestCase { /** * Create the original mime type as well with all the available sources for the specified mime * @@ -17,32 +19,16 @@ class WebP_Uploads_Tests extends WP_UnitTestCase { public function it_should_create_the_original_mime_type_as_well_with_all_the_available_sources_for_the_specified_mime( $file_location, $expected_mime, $targeted_mime ) { $attachment_id = $this->factory->attachment->create_upload_object( $file_location ); - $metadata = wp_get_attachment_metadata( $attachment_id ); - - $this->assertIsArray( $metadata ); - $this->assertArrayHasKey( 'sources', $metadata ); - $this->assertIsArray( $metadata['sources'] ); - $this->assertArrayHasKey( $targeted_mime, $metadata['sources'] ); - $this->assertIsArray( $metadata['sources'][ $targeted_mime ] ); - $this->assertArrayHasKey( $expected_mime, $metadata['sources'] ); - $this->assertIsArray( $metadata['sources'][ $expected_mime ] ); - $this->assertArrayHasKey( 'file', $metadata['sources'][ $targeted_mime ] ); - $this->assertArrayHasKey( 'filesize', $metadata['sources'][ $targeted_mime ] ); - $this->assertArrayHasKey( 'file', $metadata['sources'][ $expected_mime ] ); - $this->assertArrayHasKey( 'filesize', $metadata['sources'][ $expected_mime ] ); + $this->assertImageHasSource( $targeted_mime, $attachment_id ); + $this->assertImageHasSource( $expected_mime, $attachment_id ); + $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertArrayHasKey( 'file', $metadata ); $this->assertStringEndsWith( $metadata['sources'][ $expected_mime ]['file'], $metadata['file'] ); - foreach ( $metadata['sizes'] as $size_name => $properties ) { - $this->assertArrayHasKey( 'sources', $properties ); - $this->assertIsArray( $properties['sources'] ); - $this->assertArrayHasKey( $expected_mime, $properties['sources'] ); - $this->assertArrayHasKey( 'filesize', $properties['sources'][ $expected_mime ] ); - $this->assertArrayHasKey( 'file', $properties['sources'][ $expected_mime ] ); - $this->assertArrayHasKey( $targeted_mime, $properties['sources'] ); - $this->assertArrayHasKey( 'filesize', $properties['sources'][ $targeted_mime ] ); - $this->assertArrayHasKey( 'file', $properties['sources'][ $targeted_mime ] ); + foreach ( array_keys( $metadata['sizes'] ) as $size_name ) { + $this->assertImageHasSizeSource( $targeted_mime, $size_name, $attachment_id ); + $this->assertImageHasSizeSource( $expected_mime, $size_name, $attachment_id ); } } @@ -98,22 +84,13 @@ function () { TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); - $metadata = wp_get_attachment_metadata( $attachment_id ); - - $this->assertIsArray( $metadata ); - $this->assertArrayHasKey( 'sources', $metadata ); - $this->assertIsArray( $metadata['sources'] ); - $this->assertArrayHasKey( 'image/jpeg', $metadata['sources'] ); - $this->assertIsArray( $metadata['sources']['image/jpeg'] ); - $this->assertArrayNotHasKey( 'image/webp', $metadata['sources'] ); + $this->assertImageHasSource( 'image/jpeg', $attachment_id ); + $this->assertImageNotHasSource( 'image/webp', $attachment_id ); + $metadata = wp_get_attachment_metadata( $attachment_id ); foreach ( $metadata['sizes'] as $size_name => $properties ) { - $this->assertArrayHasKey( 'sources', $properties ); - $this->assertIsArray( $properties['sources'] ); - $this->assertArrayHasKey( 'image/jpeg', $properties['sources'] ); - $this->assertArrayHasKey( 'filesize', $properties['sources']['image/jpeg'] ); - $this->assertArrayHasKey( 'file', $properties['sources']['image/jpeg'] ); - $this->assertArrayNotHasKey( 'image/webp', $properties['sources'] ); + $this->assertImageHasSizeSource( 'image/jpeg', $size_name, $attachment_id ); + $this->assertImageNotHasSizeSource( 'image/webp', $size_name, $attachment_id ); } } @@ -280,31 +257,18 @@ public function it_should_create_a_webp_version_with_all_the_required_properties $file = get_attached_file( $attachment_id, true ); $dirname = pathinfo( $file, PATHINFO_DIRNAME ); - $this->assertArrayHasKey( 'image/jpeg', $metadata['sources'] ); - $this->assertIsArray( $metadata['sources']['image/jpeg'] ); - $this->assertArrayHasKey( 'file', $metadata['sources']['image/jpeg'] ); - $this->assertArrayHasKey( 'filesize', $metadata['sources']['image/jpeg'] ); + $this->assertImageHasSource( 'image/jpeg', $attachment_id ); $this->assertStringEndsWith( $metadata['sources']['image/jpeg']['file'], $file ); $this->assertFileExists( path_join( $dirname, $metadata['sources']['image/jpeg']['file'] ) ); $this->assertSame( $metadata['sources']['image/jpeg']['filesize'], filesize( path_join( $dirname, $metadata['sources']['image/jpeg']['file'] ) ) ); - $this->assertArrayHasKey( 'image/webp', $metadata['sources'] ); - $this->assertIsArray( $metadata['sources']['image/webp'] ); - $this->assertArrayHasKey( 'file', $metadata['sources']['image/webp'] ); - $this->assertArrayHasKey( 'filesize', $metadata['sources']['image/webp'] ); + $this->assertImageHasSource( 'image/webp', $attachment_id ); $this->assertStringEndsWith( '.webp', $metadata['sources']['image/webp']['file'] ); $this->assertFileExists( path_join( $dirname, $metadata['sources']['image/webp']['file'] ) ); $this->assertSame( $metadata['sources']['image/webp']['filesize'], filesize( path_join( $dirname, $metadata['sources']['image/webp']['file'] ) ) ); - $this->assertArrayHasKey( 'sources', $metadata['sizes']['thumbnail'] ); - $this->assertArrayHasKey( 'image/jpeg', $metadata['sizes']['thumbnail']['sources'] ); - $this->assertArrayHasKey( 'filesize', $metadata['sizes']['thumbnail']['sources']['image/jpeg'] ); - $this->assertArrayHasKey( 'file', $metadata['sizes']['thumbnail']['sources']['image/jpeg'] ); - $this->assertArrayHasKey( 'image/webp', $metadata['sizes']['thumbnail']['sources'] ); - $this->assertArrayHasKey( 'filesize', $metadata['sizes']['thumbnail']['sources']['image/webp'] ); - $this->assertArrayHasKey( 'file', $metadata['sizes']['thumbnail']['sources']['image/webp'] ); - $this->assertStringEndsNotWith( '.jpeg', $metadata['sizes']['thumbnail']['sources']['image/webp']['file'] ); - $this->assertStringEndsWith( '.webp', $metadata['sizes']['thumbnail']['sources']['image/webp']['file'] ); + $this->assertImageHasSizeSource( 'image/jpeg', 'thumbnail', $attachment_id ); + $this->assertImageHasSizeSource( 'image/webp', 'thumbnail', $attachment_id ); } /** @@ -319,13 +283,10 @@ public function it_should_create_the_full_size_images_when_no_size_is_available( $attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); - $this->assertEmpty( $metadata['sizes'] ); - $this->assertArrayHasKey( 'sources', $metadata ); - $this->assertArrayHasKey( 'image/jpeg', $metadata['sources'] ); - $this->assertIsArray( $metadata['sources']['image/jpeg'] ); - $this->assertIsArray( $metadata['sources']['image/webp'] ); + $this->assertImageHasSource( 'image/jpeg', $attachment_id ); + $this->assertImageHasSource( 'image/webp', $attachment_id ); } /** @@ -347,7 +308,7 @@ function () { ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertStringEndsWith( '-scaled.jpg', get_attached_file( $attachment_id ) ); - $this->assertArrayHasKey( 'image/webp', $metadata['sizes']['medium']['sources'] ); + $this->assertImageHasSizeSource( 'image/webp', 'medium', $attachment_id ); $this->assertStringEndsNotWith( '-scaled.webp', $metadata['sizes']['medium']['sources']['image/webp']['file'] ); $this->assertStringEndsWith( '-300x200.webp', $metadata['sizes']['medium']['sources']['image/webp']['file'] ); } @@ -374,8 +335,7 @@ public function it_should_remove_the_generated_webp_images_when_the_attachment_i $this->assertFileExists( path_join( $dirname, $metadata['sources']['image/webp']['file'] ) ); foreach ( $sizes as $size_name ) { - $this->assertArrayHasKey( 'image/webp', $metadata['sizes'][ $size_name ]['sources'] ); - $this->assertArrayHasKey( 'file', $metadata['sizes'][ $size_name ]['sources']['image/webp'] ); + $this->assertImageHasSizeSource( 'image/webp', $size_name, $attachment_id ); $this->assertFileExists( path_join( $dirname, $metadata['sizes'][ $size_name ]['sources']['image/webp']['file'] ) ); } diff --git a/tests/utils/Constraint/ImageHasSizeSource.php b/tests/utils/Constraint/ImageHasSizeSource.php new file mode 100644 index 0000000000..5009d296e1 --- /dev/null +++ b/tests/utils/Constraint/ImageHasSizeSource.php @@ -0,0 +1,67 @@ +size = $size; + } + + /** + * Returns a string representation of the constraint. + * + * @return string String representation of the constraint. + */ + public function toString(): string { + return sprintf( + '%s the source with the "%s" mime type for the "%s" size', + $this->is_not ? 'doesn\'t have' : 'has', + $this->mime_type, + $this->size + ); + } + + /** + * Evaluates the constraint for the provided attachment ID. + * + * @param int $attachment_id Attachment ID. + * @return bool TRUE if the attachment has a source with the requested mime type for the subsize, otherwise FALSE. + */ + protected function matches( $attachment_id ): bool { + $metadata = wp_get_attachment_metadata( $attachment_id ); + + // Fail if there is no metadata for the provided attachment ID. + if ( ! is_array( $metadata ) ) { + return false; + } + + // Fail if metadata doesn't contain the sources property. + if ( + ! isset( $metadata['sizes'][ $this->size ]['sources'] ) || + ! is_array( $metadata['sizes'][ $this->size ]['sources'] ) + ) { + return false; + } + + return $this->verify_sources( $metadata['sizes'][ $this->size ]['sources'] ); + } + +} diff --git a/tests/utils/Constraint/ImageHasSource.php b/tests/utils/Constraint/ImageHasSource.php new file mode 100644 index 0000000000..d3d5600a07 --- /dev/null +++ b/tests/utils/Constraint/ImageHasSource.php @@ -0,0 +1,130 @@ +is_not = false; + $this->mime_type = $mime_type; + } + + /** + * Tells to check for absence of the mime type. + */ + public function isNot() { + $this->is_not = true; + } + + /** + * Returns a string representation of the constraint. + * + * @return string String representation of the constraint. + */ + public function toString(): string { + return sprintf( + '%s the source with the "%s" mime type', + $this->is_not ? 'doesn\'t have' : 'has', + $this->mime_type + ); + } + + /** + * Evaluates the constraint for the provided attachment ID. + * + * @param int $attachment_id Attachment ID. + * @return bool TRUE if the attachment has a source for the requested mime type, otherwise FALSE. + */ + protected function matches( $attachment_id ): bool { + $metadata = wp_get_attachment_metadata( $attachment_id ); + + // Fail if there is no metadata for the provided attachment ID. + if ( ! is_array( $metadata ) ) { + return false; + } + + // Fail if metadata doesn't contain the sources property. + if ( + ! isset( $metadata['sources'] ) || + ! is_array( $metadata['sources'] ) + ) { + return false; + } + + return $this->verify_sources( $metadata['sources'] ); + } + + /** + * Verifies the sources to have the requested mime type. + * + * @param array $sources The sources array. + * @return bool TRUE if the sources array contains the correct mime type source, otherwise FALSE. + */ + protected function verify_sources( $sources ) { + // Fail if the mime type is supposed not to exist, but it is set. + if ( $this->is_not ) { + return ! isset( $sources[ $this->mime_type ] ); + } + + // Fail if metadata doesn't have the requested mime type in the sources property. + if ( + ! isset( $sources[ $this->mime_type ] ) || + ! is_array( $sources[ $this->mime_type ] ) + ) { + return false; + } + + // Fail if the file property is empty or not a string. + if ( + empty( $sources[ $this->mime_type ]['file'] ) || + ! is_string( $sources[ $this->mime_type ]['file'] ) + ) { + return false; + } + + // Fail if the filesize property is not set or it is not a number. + if ( + ! isset( $sources[ $this->mime_type ]['filesize'] ) || + ! is_numeric( $sources[ $this->mime_type ]['filesize'] ) + ) { + return false; + } + + return true; + } + + /** + * Returns the description of the failure. + * + * @param int $attachment_id Attachment ID. + * @return string The description of the failure. + */ + protected function failureDescription( $attachment_id ): string { + return sprintf( 'an image %s', $this->toString() ); + } + +} diff --git a/tests/utils/TestCase/ImagesTestCase.php b/tests/utils/TestCase/ImagesTestCase.php new file mode 100644 index 0000000000..bde7944b58 --- /dev/null +++ b/tests/utils/TestCase/ImagesTestCase.php @@ -0,0 +1,79 @@ +isNot(); + self::assertThat( $attachment_id, $constraint, $message ); + } + + /** + * Asserts that an image has a source with the specific mime type for a subsize. + * + * @since n.e.x.t + * + * @param string $mime_type The mime type of the source. + * @param string $size The subsize name. + * @param int $attachment_id The attachment ID. + * @param string $message An optional message to show on failure. + */ + public static function assertImageHasSizeSource( $mime_type, $size, $attachment_id, $message = '' ) { + $constraint = new ImageHasSizeSource( $mime_type, $size ); + self::assertThat( $attachment_id, $constraint, $message ); + } + + /** + * Asserts that an image doesn't have a source with the specific mime type for a subsize. + * + * @since n.e.x.t + * + * @param string $mime_type The mime type of the source. + * @param string $size The subsize name. + * @param int $attachment_id The attachment ID. + * @param string $message An optional message to show on failure. + */ + public static function assertImageNotHasSizeSource( $mime_type, $size, $attachment_id, $message = '' ) { + $constraint = new ImageHasSizeSource( $mime_type, $size ); + $constraint->isNot(); + self::assertThat( $attachment_id, $constraint, $message ); + } + +} From 1ef8544085c1ea2d9b5dd15d4bf85b5dde55bf16 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 16 Mar 2022 18:44:38 +0200 Subject: [PATCH 13/18] Refactor wepb-uploads tests. --- tests/modules/images/webp-uploads/webp-uploads-test.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/modules/images/webp-uploads/webp-uploads-test.php b/tests/modules/images/webp-uploads/webp-uploads-test.php index ca71d43698..886e9de325 100644 --- a/tests/modules/images/webp-uploads/webp-uploads-test.php +++ b/tests/modules/images/webp-uploads/webp-uploads-test.php @@ -62,7 +62,7 @@ public function it_should_not_create_the_sources_property_if_no_transform_is_pro $this->assertIsArray( $metadata ); $this->assertArrayNotHasKey( 'sources', $metadata ); - foreach ( $metadata['sizes'] as $size_name => $properties ) { + foreach ( $metadata['sizes'] as $properties ) { $this->assertArrayNotHasKey( 'sources', $properties ); } } @@ -88,7 +88,7 @@ function () { $this->assertImageNotHasSource( 'image/webp', $attachment_id ); $metadata = wp_get_attachment_metadata( $attachment_id ); - foreach ( $metadata['sizes'] as $size_name => $properties ) { + foreach ( array_keys( $metadata['sizes'] ) as $size_name ) { $this->assertImageHasSizeSource( 'image/jpeg', $size_name, $attachment_id ); $this->assertImageNotHasSizeSource( 'image/webp', $size_name, $attachment_id ); } @@ -115,7 +115,7 @@ function () { $this->assertIsArray( $metadata ); $this->assertArrayNotHasKey( 'sources', $metadata ); - foreach ( $metadata['sizes'] as $size_name => $properties ) { + foreach ( $metadata['sizes'] as $properties ) { $this->assertArrayNotHasKey( 'sources', $properties ); } } From fe32ee3d6bb1648203c2cd3db2a8feba36d3b564 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 16 Mar 2022 19:08:08 +0200 Subject: [PATCH 14/18] Add tests for the new functionality and fix found issues. --- modules/images/webp-uploads/load.php | 20 ++++++++++---- .../images/webp-uploads/webp-uploads-test.php | 26 +++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 2f8981e60f..21d0bbed1f 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -48,7 +48,10 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) $metadata['sources'] = array(); } - if ( empty( $metadata['sources'][ $mime_type ] ) ) { + if ( + empty( $metadata['sources'][ $mime_type ] ) && + in_array( $mime_type, $valid_mime_transforms[ $mime_type ], true ) + ) { $metadata['sources'][ $mime_type ] = array( 'file' => wp_basename( $file ), 'filesize' => filesize( $file ), @@ -65,6 +68,7 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) $original_directory = pathinfo( $file, PATHINFO_DIRNAME ); $filename = pathinfo( $file, PATHINFO_FILENAME ); $allowed_mimes = array_flip( wp_get_mime_types() ); + // Create the sources for the full sized image. foreach ( $valid_mime_transforms[ $mime_type ] as $targeted_mime ) { // If this property exists no need to create the image again. @@ -132,9 +136,7 @@ function webp_uploads_create_sources_property( array $metadata, $attachment_id ) wp_update_attachment_metadata( $attachment_id, $metadata ); } - $formats = isset( $valid_mime_transforms[ $current_mime ] ) ? $valid_mime_transforms[ $current_mime ] : array(); - - foreach ( $formats as $mime ) { + foreach ( $valid_mime_transforms[ $mime_type ] as $mime ) { // If this property exists no need to create the image again. if ( ! empty( $properties['sources'][ $mime ] ) ) { continue; @@ -276,7 +278,15 @@ function webp_uploads_get_upload_image_mime_transforms() { return $default_transforms; } - return array_filter( $transforms, 'is_array' ); + // Ensure that all mime types have correct transforms. If a mime type has invalid transforms array, + // then fallback to the original mime type to make sure that the correct subsizes are created. + foreach ( $transforms as $mime_type => $transform_types ) { + if ( ! is_array( $transform_types ) || empty( $transform_types ) ) { + $transforms[ $mime_type ] = array( $mime_type ); + } + } + + return $transforms; } /** diff --git a/tests/modules/images/webp-uploads/webp-uploads-test.php b/tests/modules/images/webp-uploads/webp-uploads-test.php index 886e9de325..d3d2c98d3a 100644 --- a/tests/modules/images/webp-uploads/webp-uploads-test.php +++ b/tests/modules/images/webp-uploads/webp-uploads-test.php @@ -711,4 +711,30 @@ function () { ); } } + + /** + * Tests that we can force transformation from jpeg to webp by using the webp_uploads_upload_image_mime_transforms filter. + * + * @test + */ + public function it_should_transofrm_jpeg_to_webp_subsizes_using_transform_filter() { + remove_all_filters( 'webp_uploads_upload_image_mime_transforms' ); + + add_filter( 'webp_uploads_upload_image_mime_transforms', function( $transforms ) { + // Unset "image/jpeg" mime type for jpeg images. + unset( $transforms['image/jpeg'][ array_search( 'image/jpeg', $transforms['image/jpeg'] ) ] ); + return $transforms; + } ); + + $attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/car.jpeg' ); + + $this->assertImageHasSource( 'image/webp', $attachment_id ); + $this->assertImageNotHasSource( 'image/jpeg', $attachment_id ); + + $metadata = wp_get_attachment_metadata( $attachment_id ); + foreach ( array_keys( $metadata['sizes'] ) as $size_name ) { + $this->assertImageHasSizeSource( 'image/webp', $size_name, $attachment_id ); + $this->assertImageNotHasSizeSource( 'image/jpeg', $size_name, $attachment_id ); + } + } } From 77737da83a79251f059435c4d4dcd0c1ae7db1ed Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 16 Mar 2022 19:17:17 +0200 Subject: [PATCH 15/18] Fix formatting issues. --- phpcs.xml.dist | 16 ++++++++++++++++ .../images/webp-uploads/webp-uploads-test.php | 13 ++++++++----- tests/utils/TestCase/ImagesTestCase.php | 16 ++++++++-------- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 29e34a94fa..f542112bef 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -46,4 +46,20 @@ tests/* + + + + tests/* + + + tests/* + + + + + tests/utils/* + + + tests/utils/* + diff --git a/tests/modules/images/webp-uploads/webp-uploads-test.php b/tests/modules/images/webp-uploads/webp-uploads-test.php index 7fcf9de4f7..31641e88af 100644 --- a/tests/modules/images/webp-uploads/webp-uploads-test.php +++ b/tests/modules/images/webp-uploads/webp-uploads-test.php @@ -764,11 +764,14 @@ function () { public function it_should_transofrm_jpeg_to_webp_subsizes_using_transform_filter() { remove_all_filters( 'webp_uploads_upload_image_mime_transforms' ); - add_filter( 'webp_uploads_upload_image_mime_transforms', function( $transforms ) { - // Unset "image/jpeg" mime type for jpeg images. - unset( $transforms['image/jpeg'][ array_search( 'image/jpeg', $transforms['image/jpeg'] ) ] ); - return $transforms; - } ); + add_filter( + 'webp_uploads_upload_image_mime_transforms', + function( $transforms ) { + // Unset "image/jpeg" mime type for jpeg images. + unset( $transforms['image/jpeg'][ array_search( 'image/jpeg', $transforms['image/jpeg'], true ) ] ); + return $transforms; + } + ); $attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/car.jpeg' ); diff --git a/tests/utils/TestCase/ImagesTestCase.php b/tests/utils/TestCase/ImagesTestCase.php index bde7944b58..47757eef47 100644 --- a/tests/utils/TestCase/ImagesTestCase.php +++ b/tests/utils/TestCase/ImagesTestCase.php @@ -9,10 +9,10 @@ /** * A test case for image attachments. * - * @method void assertImageHasSource( $mime_type, $attachment_id, $message ) Asserts that the image has the appropriate source. - * @method void assertImageHasSizeSource( $mime_type, $size, $attachment_id, $message ) Asserts that the image has the appropriate source for the subsize. - * @method void assertImageNotHasSource( $mime_type, $attachment_id, $message ) Asserts that the image doesn't have the appropriate source. - * @method void assertImageNotHasSizeSource( $mime_type, $size, $attachment_id, $message ) Asserts that the image doesn't have the appropriate source for the subsize. + * @method void assertImageHasSource( $mime_type, $attachment_id, $message ) Asserts that the image has the appropriate source. + * @method void assertImageHasSizeSource( $mime_type, $size, $attachment_id, $message ) Asserts that the image has the appropriate source for the subsize. + * @method void assertImageNotHasSource( $mime_type, $attachment_id, $message ) Asserts that the image doesn't have the appropriate source. + * @method void assertImageNotHasSizeSource( $mime_type, $size, $attachment_id, $message ) Asserts that the image doesn't have the appropriate source for the subsize. */ abstract class ImagesTestCase extends WP_UnitTestCase { @@ -22,7 +22,7 @@ abstract class ImagesTestCase extends WP_UnitTestCase { * @since n.e.x.t * * @param string $mime_type The mime type of the source. - * @param int $attachment_id The attachment ID. + * @param int $attachment_id The attachment ID. * @param string $message An optional message to show on failure. */ public static function assertImageHasSource( $mime_type, $attachment_id, $message = '' ) { @@ -36,7 +36,7 @@ public static function assertImageHasSource( $mime_type, $attachment_id, $messag * @since n.e.x.t * * @param string $mime_type The mime type of the source. - * @param int $attachment_id The attachment ID. + * @param int $attachment_id The attachment ID. * @param string $message An optional message to show on failure. */ public static function assertImageNotHasSource( $mime_type, $attachment_id, $message = '' ) { @@ -52,7 +52,7 @@ public static function assertImageNotHasSource( $mime_type, $attachment_id, $mes * * @param string $mime_type The mime type of the source. * @param string $size The subsize name. - * @param int $attachment_id The attachment ID. + * @param int $attachment_id The attachment ID. * @param string $message An optional message to show on failure. */ public static function assertImageHasSizeSource( $mime_type, $size, $attachment_id, $message = '' ) { @@ -67,7 +67,7 @@ public static function assertImageHasSizeSource( $mime_type, $size, $attachment_ * * @param string $mime_type The mime type of the source. * @param string $size The subsize name. - * @param int $attachment_id The attachment ID. + * @param int $attachment_id The attachment ID. * @param string $message An optional message to show on failure. */ public static function assertImageNotHasSizeSource( $mime_type, $size, $attachment_id, $message = '' ) { From b3419633bbc572b24848bf81e6fd4443d617e522 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 16 Mar 2022 19:48:26 +0200 Subject: [PATCH 16/18] Update tests/modules/images/webp-uploads/webp-uploads-test.php MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Crisoforo Gaspar Hernández --- tests/modules/images/webp-uploads/webp-uploads-test.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/modules/images/webp-uploads/webp-uploads-test.php b/tests/modules/images/webp-uploads/webp-uploads-test.php index 31641e88af..cc6bf48357 100644 --- a/tests/modules/images/webp-uploads/webp-uploads-test.php +++ b/tests/modules/images/webp-uploads/webp-uploads-test.php @@ -761,7 +761,7 @@ function () { * * @test */ - public function it_should_transofrm_jpeg_to_webp_subsizes_using_transform_filter() { + public function it_should_transform_jpeg_to_webp_subsizes_using_transform_filter() { remove_all_filters( 'webp_uploads_upload_image_mime_transforms' ); add_filter( From 630929e614d09b2f7695554bd528f992361d3f7f Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Thu, 17 Mar 2022 11:34:04 +0200 Subject: [PATCH 17/18] Update custom constraints to have the attachment ID parameter at the beginning. --- .../images/webp-uploads/webp-uploads-test.php | 40 +++++++++---------- tests/utils/TestCase/ImagesTestCase.php | 28 ++++++------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/tests/modules/images/webp-uploads/webp-uploads-test.php b/tests/modules/images/webp-uploads/webp-uploads-test.php index cc6bf48357..4d41cca73a 100644 --- a/tests/modules/images/webp-uploads/webp-uploads-test.php +++ b/tests/modules/images/webp-uploads/webp-uploads-test.php @@ -19,16 +19,16 @@ class WebP_Uploads_Tests extends ImagesTestCase { public function it_should_create_the_original_mime_type_as_well_with_all_the_available_sources_for_the_specified_mime( $file_location, $expected_mime, $targeted_mime ) { $attachment_id = $this->factory->attachment->create_upload_object( $file_location ); - $this->assertImageHasSource( $targeted_mime, $attachment_id ); - $this->assertImageHasSource( $expected_mime, $attachment_id ); + $this->assertImageHasSource( $attachment_id, $targeted_mime ); + $this->assertImageHasSource( $attachment_id, $expected_mime ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertArrayHasKey( 'file', $metadata ); $this->assertStringEndsWith( $metadata['sources'][ $expected_mime ]['file'], $metadata['file'] ); foreach ( array_keys( $metadata['sizes'] ) as $size_name ) { - $this->assertImageHasSizeSource( $targeted_mime, $size_name, $attachment_id ); - $this->assertImageHasSizeSource( $expected_mime, $size_name, $attachment_id ); + $this->assertImageHasSizeSource( $attachment_id, $size_name, $targeted_mime ); + $this->assertImageHasSizeSource( $attachment_id, $size_name, $expected_mime ); } } @@ -84,13 +84,13 @@ function () { TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' ); - $this->assertImageHasSource( 'image/jpeg', $attachment_id ); - $this->assertImageNotHasSource( 'image/webp', $attachment_id ); + $this->assertImageHasSource( $attachment_id, 'image/jpeg' ); + $this->assertImageNotHasSource( $attachment_id, 'image/webp' ); $metadata = wp_get_attachment_metadata( $attachment_id ); foreach ( array_keys( $metadata['sizes'] ) as $size_name ) { - $this->assertImageHasSizeSource( 'image/jpeg', $size_name, $attachment_id ); - $this->assertImageNotHasSizeSource( 'image/webp', $size_name, $attachment_id ); + $this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/jpeg' ); + $this->assertImageNotHasSizeSource( $attachment_id, $size_name, 'image/webp' ); } } @@ -257,18 +257,18 @@ public function it_should_create_a_webp_version_with_all_the_required_properties $file = get_attached_file( $attachment_id, true ); $dirname = pathinfo( $file, PATHINFO_DIRNAME ); - $this->assertImageHasSource( 'image/jpeg', $attachment_id ); + $this->assertImageHasSource( $attachment_id, 'image/jpeg' ); $this->assertStringEndsWith( $metadata['sources']['image/jpeg']['file'], $file ); $this->assertFileExists( path_join( $dirname, $metadata['sources']['image/jpeg']['file'] ) ); $this->assertSame( $metadata['sources']['image/jpeg']['filesize'], filesize( path_join( $dirname, $metadata['sources']['image/jpeg']['file'] ) ) ); - $this->assertImageHasSource( 'image/webp', $attachment_id ); + $this->assertImageHasSource( $attachment_id, 'image/webp' ); $this->assertStringEndsWith( '.webp', $metadata['sources']['image/webp']['file'] ); $this->assertFileExists( path_join( $dirname, $metadata['sources']['image/webp']['file'] ) ); $this->assertSame( $metadata['sources']['image/webp']['filesize'], filesize( path_join( $dirname, $metadata['sources']['image/webp']['file'] ) ) ); - $this->assertImageHasSizeSource( 'image/jpeg', 'thumbnail', $attachment_id ); - $this->assertImageHasSizeSource( 'image/webp', 'thumbnail', $attachment_id ); + $this->assertImageHasSizeSource( $attachment_id, 'thumbnail', 'image/jpeg' ); + $this->assertImageHasSizeSource( $attachment_id, 'thumbnail', 'image/webp' ); } /** @@ -285,8 +285,8 @@ public function it_should_create_the_full_size_images_when_no_size_is_available( $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertEmpty( $metadata['sizes'] ); - $this->assertImageHasSource( 'image/jpeg', $attachment_id ); - $this->assertImageHasSource( 'image/webp', $attachment_id ); + $this->assertImageHasSource( $attachment_id, 'image/jpeg' ); + $this->assertImageHasSource( $attachment_id, 'image/webp' ); } /** @@ -308,7 +308,7 @@ function () { ); $metadata = wp_get_attachment_metadata( $attachment_id ); $this->assertStringEndsWith( '-scaled.jpg', get_attached_file( $attachment_id ) ); - $this->assertImageHasSizeSource( 'image/webp', 'medium', $attachment_id ); + $this->assertImageHasSizeSource( $attachment_id, 'medium', 'image/webp' ); $this->assertStringEndsNotWith( '-scaled.webp', $metadata['sizes']['medium']['sources']['image/webp']['file'] ); $this->assertStringEndsWith( '-300x200.webp', $metadata['sizes']['medium']['sources']['image/webp']['file'] ); } @@ -335,7 +335,7 @@ public function it_should_remove_the_generated_webp_images_when_the_attachment_i $this->assertFileExists( path_join( $dirname, $metadata['sources']['image/webp']['file'] ) ); foreach ( $sizes as $size_name ) { - $this->assertImageHasSizeSource( 'image/webp', $size_name, $attachment_id ); + $this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/webp' ); $this->assertFileExists( path_join( $dirname, $metadata['sizes'][ $size_name ]['sources']['image/webp']['file'] ) ); } @@ -775,13 +775,13 @@ function( $transforms ) { $attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/car.jpeg' ); - $this->assertImageHasSource( 'image/webp', $attachment_id ); - $this->assertImageNotHasSource( 'image/jpeg', $attachment_id ); + $this->assertImageHasSource( $attachment_id, 'image/webp' ); + $this->assertImageNotHasSource( $attachment_id, 'image/jpeg' ); $metadata = wp_get_attachment_metadata( $attachment_id ); foreach ( array_keys( $metadata['sizes'] ) as $size_name ) { - $this->assertImageHasSizeSource( 'image/webp', $size_name, $attachment_id ); - $this->assertImageNotHasSizeSource( 'image/jpeg', $size_name, $attachment_id ); + $this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/webp' ); + $this->assertImageNotHasSizeSource( $attachment_id, $size_name, 'image/jpeg' ); } } } diff --git a/tests/utils/TestCase/ImagesTestCase.php b/tests/utils/TestCase/ImagesTestCase.php index 47757eef47..22376def0a 100644 --- a/tests/utils/TestCase/ImagesTestCase.php +++ b/tests/utils/TestCase/ImagesTestCase.php @@ -9,10 +9,10 @@ /** * A test case for image attachments. * - * @method void assertImageHasSource( $mime_type, $attachment_id, $message ) Asserts that the image has the appropriate source. - * @method void assertImageHasSizeSource( $mime_type, $size, $attachment_id, $message ) Asserts that the image has the appropriate source for the subsize. - * @method void assertImageNotHasSource( $mime_type, $attachment_id, $message ) Asserts that the image doesn't have the appropriate source. - * @method void assertImageNotHasSizeSource( $mime_type, $size, $attachment_id, $message ) Asserts that the image doesn't have the appropriate source for the subsize. + * @method void assertImageHasSource( $attachment_id, $mime_type, $message ) Asserts that the image has the appropriate source. + * @method void assertImageHasSizeSource( $attachment_id, $size, $mime_type, $message ) Asserts that the image has the appropriate source for the subsize. + * @method void assertImageNotHasSource( $attachment_id, $mime_type, $message ) Asserts that the image doesn't have the appropriate source. + * @method void assertImageNotHasSizeSource( $attachment_id, $size, $mime_type, $message ) Asserts that the image doesn't have the appropriate source for the subsize. */ abstract class ImagesTestCase extends WP_UnitTestCase { @@ -21,11 +21,11 @@ abstract class ImagesTestCase extends WP_UnitTestCase { * * @since n.e.x.t * - * @param string $mime_type The mime type of the source. * @param int $attachment_id The attachment ID. + * @param string $mime_type The mime type of the source. * @param string $message An optional message to show on failure. */ - public static function assertImageHasSource( $mime_type, $attachment_id, $message = '' ) { + public static function assertImageHasSource( $attachment_id, $mime_type, $message = '' ) { $constraint = new ImageHasSource( $mime_type ); self::assertThat( $attachment_id, $constraint, $message ); } @@ -35,11 +35,11 @@ public static function assertImageHasSource( $mime_type, $attachment_id, $messag * * @since n.e.x.t * - * @param string $mime_type The mime type of the source. * @param int $attachment_id The attachment ID. + * @param string $mime_type The mime type of the source. * @param string $message An optional message to show on failure. */ - public static function assertImageNotHasSource( $mime_type, $attachment_id, $message = '' ) { + public static function assertImageNotHasSource( $attachment_id, $mime_type, $message = '' ) { $constraint = new ImageHasSource( $mime_type ); $constraint->isNot(); self::assertThat( $attachment_id, $constraint, $message ); @@ -50,12 +50,12 @@ public static function assertImageNotHasSource( $mime_type, $attachment_id, $mes * * @since n.e.x.t * - * @param string $mime_type The mime type of the source. - * @param string $size The subsize name. * @param int $attachment_id The attachment ID. + * @param string $size The subsize name. + * @param string $mime_type The mime type of the source. * @param string $message An optional message to show on failure. */ - public static function assertImageHasSizeSource( $mime_type, $size, $attachment_id, $message = '' ) { + public static function assertImageHasSizeSource( $attachment_id, $size, $mime_type, $message = '' ) { $constraint = new ImageHasSizeSource( $mime_type, $size ); self::assertThat( $attachment_id, $constraint, $message ); } @@ -65,12 +65,12 @@ public static function assertImageHasSizeSource( $mime_type, $size, $attachment_ * * @since n.e.x.t * - * @param string $mime_type The mime type of the source. - * @param string $size The subsize name. * @param int $attachment_id The attachment ID. + * @param string $size The subsize name. + * @param string $mime_type The mime type of the source. * @param string $message An optional message to show on failure. */ - public static function assertImageNotHasSizeSource( $mime_type, $size, $attachment_id, $message = '' ) { + public static function assertImageNotHasSizeSource( $attachment_id, $size, $mime_type, $message = '' ) { $constraint = new ImageHasSizeSource( $mime_type, $size ); $constraint->isNot(); self::assertThat( $attachment_id, $constraint, $message ); From 1babcc91febdd0da517e506e82154268f057e942 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Thu, 17 Mar 2022 11:52:54 +0200 Subject: [PATCH 18/18] Add the file extension check to image source constraints. --- .../modules/images/webp-uploads/webp-uploads-test.php | 1 - tests/utils/Constraint/ImageHasSource.php | 10 ++++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/tests/modules/images/webp-uploads/webp-uploads-test.php b/tests/modules/images/webp-uploads/webp-uploads-test.php index 4d41cca73a..93084b0593 100644 --- a/tests/modules/images/webp-uploads/webp-uploads-test.php +++ b/tests/modules/images/webp-uploads/webp-uploads-test.php @@ -263,7 +263,6 @@ public function it_should_create_a_webp_version_with_all_the_required_properties $this->assertSame( $metadata['sources']['image/jpeg']['filesize'], filesize( path_join( $dirname, $metadata['sources']['image/jpeg']['file'] ) ) ); $this->assertImageHasSource( $attachment_id, 'image/webp' ); - $this->assertStringEndsWith( '.webp', $metadata['sources']['image/webp']['file'] ); $this->assertFileExists( path_join( $dirname, $metadata['sources']['image/webp']['file'] ) ); $this->assertSame( $metadata['sources']['image/webp']['filesize'], filesize( path_join( $dirname, $metadata['sources']['image/webp']['file'] ) ) ); diff --git a/tests/utils/Constraint/ImageHasSource.php b/tests/utils/Constraint/ImageHasSource.php index d3d5600a07..2c55f01e28 100644 --- a/tests/utils/Constraint/ImageHasSource.php +++ b/tests/utils/Constraint/ImageHasSource.php @@ -106,6 +106,16 @@ protected function verify_sources( $sources ) { return false; } + // Fail if the file has wrong extension. + $allowed_mimes = array_flip( wp_get_mime_types() ); + if ( isset( $allowed_mimes[ $this->mime_type ] ) ) { + $extensions = explode( '|', $allowed_mimes[ $this->mime_type ] ); + $extension = pathinfo( $sources[ $this->mime_type ]['file'], PATHINFO_EXTENSION ); + if ( ! in_array( strtolower( $extension ), $extensions, true ) ) { + return false; + } + } + // Fail if the filesize property is not set or it is not a number. if ( ! isset( $sources[ $this->mime_type ]['filesize'] ) ||