From 2bbfc2edfa7a709c6cdeb6c51b35987a4b49ff18 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 6 Jul 2022 21:43:21 +0300 Subject: [PATCH 1/4] Add a hook for the wp_get_attachment_image_src filter. --- modules/images/webp-uploads/load.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index 1098a40908..c6400b62fe 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -573,3 +573,23 @@ function webp_uploads_update_featured_image( $html, $post_id, $attachment_id ) { return webp_uploads_img_tag_update_mime_type( $html, 'post_thumbnail_html', $attachment_id ); } add_filter( 'post_thumbnail_html', 'webp_uploads_update_featured_image', 10, 3 ); + +/** + * Updates the image src data to use the webp format if an image has webp version. + * + * @since n.e.x.t + * + * @param array|bool $image Image data. + * @param int $attachment_id Image attachment ID. + * @param string|array $size Requested image size. + * @return array|bool Updated image data if the image has webp version, otherwise the original value. + */ +function webp_uploads_update_attachment_image_src( $image, $attachment_id, $size ) { + // Do nothing if image data is falsy. + if ( empty( $image ) ) { + return $image; + } + + return $image; +} +add_filter( 'wp_get_attachment_image_src', 'webp_uploads_update_attachment_image_src', 10, 3 ); From 7a6bf596b416914404c372e0bf3ec234febfff6d Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 6 Jul 2022 22:02:47 +0300 Subject: [PATCH 2/4] Implement the replacement for the image URL. --- modules/images/webp-uploads/helper.php | 30 +++++++++++++++ modules/images/webp-uploads/load.php | 51 +++++++++++++++++--------- 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/modules/images/webp-uploads/helper.php b/modules/images/webp-uploads/helper.php index 2ca66c60a6..be75d50222 100644 --- a/modules/images/webp-uploads/helper.php +++ b/modules/images/webp-uploads/helper.php @@ -240,3 +240,33 @@ function webp_uploads_get_attachment_sources( $attachment_id, $size = 'thumbnail // Return an empty array if no sources found. return array(); } + +/** + * Returns mime types that should be used for an image in the specific context. + * + * @since n.e.x.t + * + * @param int $attachment_id The attachment ID. + * @param string $context The current context. + * @return array Mime types to use for the image. + */ +function webp_uploads_get_content_image_mimes( $attachment_id, $context ) { + $target_mimes = array( 'image/webp', 'image/jpeg' ); + + /** + * Filters mime types that should be used to update all images in the content. The order of + * mime types matters. The first mime type in the list will be used if it is supported by an image. + * + * @since 1.0.0 + * + * @param array $target_mimes The list of mime types that can be used to update images in the content. + * @param int $attachment_id The attachment ID. + * @param string $context The current context. + */ + $target_mimes = apply_filters( 'webp_uploads_content_image_mimes', $target_mimes, $attachment_id, $context ); + if ( ! is_array( $target_mimes ) ) { + $target_mimes = array(); + } + + return $target_mimes; +} diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index c6400b62fe..ccc85a638b 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -441,22 +441,8 @@ function webp_uploads_img_tag_update_mime_type( $image, $context, $attachment_id */ $prefer_smaller_image_file = apply_filters( 'webp_uploads_prefer_smaller_image_file', false ); - /** - * Filters mime types that should be used to update all images in the content. The order of - * mime types matters. The first mime type in the list will be used if it is supported by an image. - * - * @since 1.0.0 - * - * @param array $target_mimes The list of mime types that can be used to update images in the content. - * @param int $attachment_id The attachment ID. - * @param string $context The current context. - */ - $target_mimes = apply_filters( 'webp_uploads_content_image_mimes', array( 'image/webp', 'image/jpeg' ), $attachment_id, $context ); - - // Get the original mime type for comparison. - $original_mime = get_post_mime_type( $attachment_id ); - - $target_mime = null; + $target_mime = null; + $target_mimes = webp_uploads_get_content_image_mimes( $attachment_id, $context ); foreach ( $target_mimes as $mime ) { if ( isset( $metadata['sources'][ $mime ] ) ) { $target_mime = $mime; @@ -468,6 +454,9 @@ function webp_uploads_img_tag_update_mime_type( $image, $context, $attachment_id return $image; } + // Get the original mime type for comparison. + $original_mime = get_post_mime_type( $attachment_id ); + // Replace the full size image if present. if ( isset( $metadata['sources'][ $target_mime ]['file'] ) ) { // Initially set the target mime as the replacement source. @@ -585,11 +574,37 @@ function webp_uploads_update_featured_image( $html, $post_id, $attachment_id ) { * @return array|bool Updated image data if the image has webp version, otherwise the original value. */ function webp_uploads_update_attachment_image_src( $image, $attachment_id, $size ) { - // Do nothing if image data is falsy. - if ( empty( $image ) ) { + // Do nothing if image data is falsy or the size is not a string. + if ( empty( $image ) || ! is_string( $size ) ) { return $image; } + // Do nothing if there is no sources for the selected image size. + $sources = webp_uploads_get_attachment_sources( $attachment_id, $size ); + if ( empty( $sources ) ) { + return $image; + } + + $context = doing_filter( 'the_content' ) ? 'the_content' : null; + + // Try to find the correct mime type for the image. + $target_mime = null; + $target_mimes = webp_uploads_get_content_image_mimes( $attachment_id, $context ); + foreach ( $target_mimes as $mime ) { + if ( isset( $sources[ $mime ] ) ) { + $target_mime = $mime; + break; + } + } + + // Do nothing if there is no appropriate mime type for this image. + if ( null === $target_mime ) { + return $image; + } + + // Replace the image with the new mime type. + $image[0] = dirname( $image[0] ) . '/' . $sources[ $target_mime ]['file']; + return $image; } add_filter( 'wp_get_attachment_image_src', 'webp_uploads_update_attachment_image_src', 10, 3 ); From 87e1a737324349761180b506b20539499d291577 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 6 Jul 2022 22:36:52 +0300 Subject: [PATCH 3/4] Add phpunit tests. --- modules/images/webp-uploads/load.php | 9 ++++--- .../images/webp-uploads/load-tests.php | 26 +++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index ccc85a638b..1828893fd3 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -579,17 +579,20 @@ function webp_uploads_update_attachment_image_src( $image, $attachment_id, $size return $image; } + // Do nothing if not in the "the_content" context. + if ( ! doing_filter( 'the_content' ) ) { + return $image; + } + // Do nothing if there is no sources for the selected image size. $sources = webp_uploads_get_attachment_sources( $attachment_id, $size ); if ( empty( $sources ) ) { return $image; } - $context = doing_filter( 'the_content' ) ? 'the_content' : null; - // Try to find the correct mime type for the image. $target_mime = null; - $target_mimes = webp_uploads_get_content_image_mimes( $attachment_id, $context ); + $target_mimes = webp_uploads_get_content_image_mimes( $attachment_id, 'the_content' ); foreach ( $target_mimes as $mime ) { if ( isset( $sources[ $mime ] ) ) { $target_mime = $mime; diff --git a/tests/modules/images/webp-uploads/load-tests.php b/tests/modules/images/webp-uploads/load-tests.php index 4cf4f2fd8c..b39aad471e 100644 --- a/tests/modules/images/webp-uploads/load-tests.php +++ b/tests/modules/images/webp-uploads/load-tests.php @@ -631,4 +631,30 @@ function() { $tag = wp_get_attachment_image( $attachment_id, 'medium', false, array( 'class' => "wp-image-{$attachment_id}" ) ); $this->assertNotSame( $tag, webp_uploads_img_tag_update_mime_type( $tag, 'the_content', $attachment_id ) ); } + + /** + * Checks if the image URL is update when there is an appropriate mime type. + * + * @test + */ + public function it_should_update_image_src_if_there_is_appropriate_mime_type() { + $attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/paint.jpeg' ); + $original_url = wp_get_attachment_image_url( $attachment_id, 'medium' ); + $this->assertNotFalse( $original_url ); + + // This test should be executed within the the_content context to process correctly. + add_filter( + 'the_content', + function() use ( $attachment_id, $original_url ) { + $webp_url = wp_get_attachment_image_url( $attachment_id, 'medium' ); + $this->assertNotFalse( $webp_url ); + $this->assertNotSame( $webp_url, $original_url ); + + $expected = str_replace( '.jpeg', '.webp', $original_url ); + $this->assertSame( $expected, $webp_url ); + } + ); + + apply_filters( 'the_content', '' ); + } } From 36a1279a69fc8bf22eb1a86a815a4a0972473249 Mon Sep 17 00:00:00 2001 From: Eugene Manuilov Date: Wed, 13 Jul 2022 15:58:10 +0300 Subject: [PATCH 4/4] Remove wp_get_attachment_image_src related functionality. --- modules/images/webp-uploads/load.php | 49 ------------------- .../images/webp-uploads/load-tests.php | 26 ---------- 2 files changed, 75 deletions(-) diff --git a/modules/images/webp-uploads/load.php b/modules/images/webp-uploads/load.php index b709809087..996439b001 100644 --- a/modules/images/webp-uploads/load.php +++ b/modules/images/webp-uploads/load.php @@ -629,55 +629,6 @@ function webp_uploads_update_featured_image( $html, $post_id, $attachment_id ) { } add_filter( 'post_thumbnail_html', 'webp_uploads_update_featured_image', 10, 3 ); -/** - * Updates the image src data to use the webp format if an image has webp version. - * - * @since n.e.x.t - * - * @param array|bool $image Image data. - * @param int $attachment_id Image attachment ID. - * @param string|array $size Requested image size. - * @return array|bool Updated image data if the image has webp version, otherwise the original value. - */ -function webp_uploads_update_attachment_image_src( $image, $attachment_id, $size ) { - // Do nothing if image data is falsy or the size is not a string. - if ( empty( $image ) || ! is_string( $size ) ) { - return $image; - } - - // Do nothing if not in the "the_content" context. - if ( ! doing_filter( 'the_content' ) ) { - return $image; - } - - // Do nothing if there is no sources for the selected image size. - $sources = webp_uploads_get_attachment_sources( $attachment_id, $size ); - if ( empty( $sources ) ) { - return $image; - } - - // Try to find the correct mime type for the image. - $target_mime = null; - $target_mimes = webp_uploads_get_content_image_mimes( $attachment_id, 'the_content' ); - foreach ( $target_mimes as $mime ) { - if ( isset( $sources[ $mime ] ) ) { - $target_mime = $mime; - break; - } - } - - // Do nothing if there is no appropriate mime type for this image. - if ( null === $target_mime ) { - return $image; - } - - // Replace the image with the new mime type. - $image[0] = dirname( $image[0] ) . '/' . $sources[ $target_mime ]['file']; - - return $image; -} -add_filter( 'wp_get_attachment_image_src', 'webp_uploads_update_attachment_image_src', 10, 3 ); - /** * Returns an array of image size names that have secondary mime type output enabled. Core sizes and * core theme sizes are enabled by default. diff --git a/tests/modules/images/webp-uploads/load-tests.php b/tests/modules/images/webp-uploads/load-tests.php index 317dcd8fdc..8c843ae136 100644 --- a/tests/modules/images/webp-uploads/load-tests.php +++ b/tests/modules/images/webp-uploads/load-tests.php @@ -636,32 +636,6 @@ function() { $this->assertNotSame( $tag, webp_uploads_img_tag_update_mime_type( $tag, 'the_content', $attachment_id ) ); } - /** - * Checks if the image URL is update when there is an appropriate mime type. - * - * @test - */ - public function it_should_update_image_src_if_there_is_appropriate_mime_type() { - $attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/paint.jpeg' ); - $original_url = wp_get_attachment_image_url( $attachment_id, 'medium' ); - $this->assertNotFalse( $original_url ); - - // This test should be executed within the the_content context to process correctly. - add_filter( - 'the_content', - function() use ( $attachment_id, $original_url ) { - $webp_url = wp_get_attachment_image_url( $attachment_id, 'medium' ); - $this->assertNotFalse( $webp_url ); - $this->assertNotSame( $webp_url, $original_url ); - - $expected = str_replace( '.jpeg', '.webp', $original_url ); - $this->assertSame( $expected, $webp_url ); - } - ); - - apply_filters( 'the_content', '' ); - } - /** * Tests whether additional mime types generated only for allowed image sizes or not when the filter is used. *