From c284697d95e47e6788bf5e6f916eac71551693e3 Mon Sep 17 00:00:00 2001 From: Aditya Dhade Date: Sun, 7 Jun 2026 00:01:19 +0530 Subject: [PATCH 01/12] Use `wordpress` docker container for image related plugins --- package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 33d4a224b9..ec5d92ca58 100644 --- a/package.json +++ b/package.json @@ -69,29 +69,29 @@ "test-e2e:debug": "wp-scripts test-playwright --config tools/e2e/playwright.config.ts --ui", "test-e2e:auto-sizes": "wp-scripts test-playwright --config tools/e2e/playwright.config.ts --project=auto-sizes", "lint-php": "composer lint:all", - "test-php": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:plugins", + "test-php": "npm-run-all -s --continue-on-error test-php:performance-lab test-php:auto-sizes test-php:dominant-color-images test-php:embed-optimizer test-php:image-prioritizer test-php:optimization-detective test-php:speculation-rules test-php:view-transitions test-php:web-worker-offloading test-php:webp-uploads", "test-php-watch": "./bin/test-php-watch.sh", - "test-php-multisite": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:plugins", + "test-php-multisite": "npm-run-all -s --continue-on-error test-php-multisite:performance-lab test-php-multisite:auto-sizes test-php-multisite:dominant-color-images test-php-multisite:embed-optimizer test-php-multisite:image-prioritizer test-php-multisite:optimization-detective test-php-multisite:speculation-rules test-php-multisite:view-transitions test-php-multisite:web-worker-offloading test-php-multisite:webp-uploads", "test-php:performance-lab": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:performance-lab", "test-php:auto-sizes": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:auto-sizes", - "test-php:dominant-color-images": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:dominant-color-images", + "test-php:dominant-color-images": "wp-env --config=.wp-env.test.json run wordpress --env-cwd=/var/www/html/wp-content/plugins/performance composer test:dominant-color-images", "test-php:embed-optimizer": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:embed-optimizer", "test-php:image-prioritizer": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:image-prioritizer", "test-php:optimization-detective": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:optimization-detective", "test-php:speculation-rules": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:speculation-rules", "test-php:view-transitions": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:view-transitions", "test-php:web-worker-offloading": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:web-worker-offloading", - "test-php:webp-uploads": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test:webp-uploads", + "test-php:webp-uploads": "wp-env --config=.wp-env.test.json run wordpress --env-cwd=/var/www/html/wp-content/plugins/performance composer test:webp-uploads", "test-php-multisite:performance-lab": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:performance-lab", "test-php-multisite:auto-sizes": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:auto-sizes", - "test-php-multisite:dominant-color-images": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:dominant-color-images", + "test-php-multisite:dominant-color-images": "wp-env --config=.wp-env.test.json run wordpress --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:dominant-color-images", "test-php-multisite:embed-optimizer": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:embed-optimizer", "test-php-multisite:image-prioritizer": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:image-prioritizer", "test-php-multisite:optimization-detective": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:optimization-detective", "test-php-multisite:speculation-rules": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:speculation-rules", "test-php-multisite:view-transitions": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:view-transitions", "test-php-multisite:web-worker-offloading": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:web-worker-offloading", - "test-php-multisite:webp-uploads": "wp-env --config=.wp-env.test.json run cli --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:webp-uploads", + "test-php-multisite:webp-uploads": "wp-env --config=.wp-env.test.json run wordpress --env-cwd=/var/www/html/wp-content/plugins/performance composer test-multisite:webp-uploads", "update-test-case-snapshots": "bin/update-test-case-snapshots.sh", "wp-env": "wp-env", "wp-env-test": "wp-env --config=.wp-env.test.json", From 68a36a39b3503b5ad2bc0b4cdd8de382c7d96c88 Mon Sep 17 00:00:00 2001 From: Aditya Dhade Date: Sun, 7 Jun 2026 00:13:23 +0530 Subject: [PATCH 02/12] Fix previously skipped tests --- plugins/dominant-color-images/tests/data/class-testcase.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/dominant-color-images/tests/data/class-testcase.php b/plugins/dominant-color-images/tests/data/class-testcase.php index f6026dde7c..2925664276 100644 --- a/plugins/dominant-color-images/tests/data/class-testcase.php +++ b/plugins/dominant-color-images/tests/data/class-testcase.php @@ -122,12 +122,12 @@ public function provider_get_dominant_color(): array { ), 'balloons_webp' => array( 'image_path' => TESTS_PLUGIN_DIR . '/tests/data/images/balloons.webp', - 'expected_color' => array( 'c1bbb9', 'c0bbb9', 'c0bab8', 'c3bdbd', 'bfbab8' ), + 'expected_color' => array( 'c1bbb9', 'c0bbb9', 'c0bab8', 'c3bdbd', 'bfbab8', 'c2bdbc' ), 'expected_transparency' => false, ), 'half_opaque' => array( 'image_path' => TESTS_PLUGIN_DIR . '/tests/data/images/half-opaque.png', - 'expected_color' => array( '7e7e7e' ), + 'expected_color' => array( '7e7e7e', 'ffffff' ), 'expected_transparency' => true, ), ); @@ -214,7 +214,7 @@ public function test_get_dominant_color_invalid( string $image_path ): void { $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); $this->assertWPError( $dominant_color_data ); - $this->assertStringContainsString( 'image_no_editor', $dominant_color_data->get_error_code() ); + $this->assertStringContainsString( 'unsupported_attachment_type', $dominant_color_data->get_error_code() ); } /** From 991da0aaebee351095d229ff4e9f2b22c31d4da2 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Wed, 3 Jun 2026 14:37:05 -0600 Subject: [PATCH 03/12] allow falling back to original image if no subsizes available --- plugins/dominant-color-images/helper.php | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/plugins/dominant-color-images/helper.php b/plugins/dominant-color-images/helper.php index 4cd6254d95..3a14f67137 100644 --- a/plugins/dominant-color-images/helper.php +++ b/plugins/dominant-color-images/helper.php @@ -155,17 +155,15 @@ function dominant_color_get_attachment_file_path( int $attachment_id, string $si return false; } - if ( ! isset( $imagedata['sizes'][ $size ] ) ) { + $filepath = get_attached_file( $attachment_id ); + if ( false === $filepath ) { return false; } - $file = get_attached_file( $attachment_id ); - if ( false === $file ) { - return false; + if ( isset( $imagedata['sizes'][ $size ] ) ) { + $filepath = str_replace( wp_basename( $filepath ), $imagedata['sizes'][ $size ]['file'], $filepath ); } - $filepath = str_replace( wp_basename( $file ), $imagedata['sizes'][ $size ]['file'], $file ); - return $filepath; } From 1ad06cacd88ac918ee3fec58056edad6ef5befe3 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Wed, 3 Jun 2026 14:37:05 -0600 Subject: [PATCH 04/12] always override core image editor classes, such that same editor is used for initial image processing and dominant colours --- plugins/dominant-color-images/helper.php | 2 -- plugins/dominant-color-images/load.php | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/dominant-color-images/helper.php b/plugins/dominant-color-images/helper.php index 3a14f67137..91b05c9029 100644 --- a/plugins/dominant-color-images/helper.php +++ b/plugins/dominant-color-images/helper.php @@ -96,7 +96,6 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) { if ( false === $file ) { return new WP_Error( 'no_image_found', __( 'Unable to load image.', 'dominant-color-images' ) ); } - add_filter( 'wp_image_editors', 'dominant_color_set_image_editors' ); /** * Editor. @@ -113,7 +112,6 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) { ), ) ); - remove_filter( 'wp_image_editors', 'dominant_color_set_image_editors' ); if ( is_wp_error( $editor ) ) { return $editor; diff --git a/plugins/dominant-color-images/load.php b/plugins/dominant-color-images/load.php index 5640401957..35095bd85b 100644 --- a/plugins/dominant-color-images/load.php +++ b/plugins/dominant-color-images/load.php @@ -32,4 +32,6 @@ require_once __DIR__ . '/helper.php'; require_once __DIR__ . '/hooks.php'; + +add_filter( 'wp_image_editors', 'dominant_color_set_image_editors', 999, 1 ); // @codeCoverageIgnoreEnd From ecaa0f56bc21d0908a2401337780c94c0de4e546 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Sun, 7 Jun 2026 13:47:48 -0600 Subject: [PATCH 05/12] remove redundant fn call --- plugins/dominant-color-images/helper.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/dominant-color-images/helper.php b/plugins/dominant-color-images/helper.php index 91b05c9029..ad2503e27d 100644 --- a/plugins/dominant-color-images/helper.php +++ b/plugins/dominant-color-images/helper.php @@ -90,9 +90,6 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) { } $file = dominant_color_get_attachment_file_path( $attachment_id ); - if ( false === $file ) { - $file = get_attached_file( $attachment_id ); - } if ( false === $file ) { return new WP_Error( 'no_image_found', __( 'Unable to load image.', 'dominant-color-images' ) ); } From badb9e9482fcfebc6caa4dfca9a80cf635357329 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Sun, 7 Jun 2026 13:06:55 -0600 Subject: [PATCH 06/12] abstract the get metadata functions --- plugins/dominant-color-images/helper.php | 46 ++++++++++++++---------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/plugins/dominant-color-images/helper.php b/plugins/dominant-color-images/helper.php index ad2503e27d..57353ae785 100644 --- a/plugins/dominant-color-images/helper.php +++ b/plugins/dominant-color-images/helper.php @@ -135,6 +135,28 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) { return $dominant_color_data; } +/** + * Retrieves attachment metadata for an image attachment. + * + * @since 1.0.0 + * + * @param int $attachment_id Attachment ID. + * @return array|null Attachment metadata array or null if not an image or metadata unavailable. + */ +function dominant_color_get_attachment_metadata( int $attachment_id ) { + + if ( ! wp_attachment_is_image( $attachment_id ) ) { + return null; + } + + $image_meta = wp_get_attachment_metadata( $attachment_id ); + if ( ! is_array( $image_meta ) ) { + return null; + } + + return $image_meta; +} + /** * Gets file path of image based on size. * @@ -145,18 +167,16 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) { * @return false|string Path to an image or false if not found. */ function dominant_color_get_attachment_file_path( int $attachment_id, string $size = 'medium' ) { - $imagedata = wp_get_attachment_metadata( $attachment_id ); - if ( ! is_array( $imagedata ) ) { - return false; - } $filepath = get_attached_file( $attachment_id ); if ( false === $filepath ) { return false; } - if ( isset( $imagedata['sizes'][ $size ] ) ) { - $filepath = str_replace( wp_basename( $filepath ), $imagedata['sizes'][ $size ]['file'], $filepath ); + $image_meta = dominant_color_get_attachment_metadata( $attachment_id ); + + if ( isset( $image_meta['sizes'][ $size ] ) ) { + $filepath = str_replace( wp_basename( $filepath ), $image_meta['sizes'][ $size ]['file'], $filepath ); } return $filepath; @@ -171,13 +191,7 @@ function dominant_color_get_attachment_file_path( int $attachment_id, string $si * @return string|null Hex value of dominant color or null if not set. */ function dominant_color_get_dominant_color( int $attachment_id ): ?string { - if ( ! wp_attachment_is_image( $attachment_id ) ) { - return null; - } - $image_meta = wp_get_attachment_metadata( $attachment_id ); - if ( ! is_array( $image_meta ) ) { - return null; - } + $image_meta = dominant_color_get_attachment_metadata( $attachment_id ); if ( ! isset( $image_meta['dominant_color'] ) ) { return null; @@ -195,10 +209,7 @@ function dominant_color_get_dominant_color( int $attachment_id ): ?string { * @return bool|null Whether the image has transparency, or null if not set. */ function dominant_color_has_transparency( int $attachment_id ): ?bool { - $image_meta = wp_get_attachment_metadata( $attachment_id ); - if ( ! is_array( $image_meta ) ) { - return null; - } + $image_meta = dominant_color_get_attachment_metadata( $attachment_id ); if ( ! isset( $image_meta['has_transparency'] ) ) { return null; @@ -207,7 +218,6 @@ function dominant_color_has_transparency( int $attachment_id ): ?bool { return $image_meta['has_transparency']; } - /** * Gets hex color from RGB. * From 89a775c9c6c8e72bcf3475caee6a41817a909603 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Sun, 7 Jun 2026 17:02:12 -0600 Subject: [PATCH 07/12] Remove unnecessary wp_maybe_generate_attachment_metadata calls. They never do anything in any test --- plugins/dominant-color-images/tests/data/class-testcase.php | 4 ---- plugins/dominant-color-images/tests/test-dominant-color.php | 5 ----- 2 files changed, 9 deletions(-) diff --git a/plugins/dominant-color-images/tests/data/class-testcase.php b/plugins/dominant-color-images/tests/data/class-testcase.php index 2925664276..6cfab19f23 100644 --- a/plugins/dominant-color-images/tests/data/class-testcase.php +++ b/plugins/dominant-color-images/tests/data/class-testcase.php @@ -182,7 +182,6 @@ public function test_get_dominant_color_valid( string $image_path, array $expect } $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); @@ -209,7 +208,6 @@ public function test_get_dominant_color_invalid( string $image_path ): void { $this->markTestSkipped( "Mime type $mime_type is not supported." ); } $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); @@ -227,7 +225,6 @@ public function test_get_dominant_color_data_unsupported_mime_type(): void { $image_path = TESTS_PLUGIN_DIR . '/tests/data/images/red.jpg'; $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); @@ -245,7 +242,6 @@ public function test_get_dominant_color_data_unsupported_mime_type(): void { */ public function test_get_dominant_color_none_images( string $image_path ): void { $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); diff --git a/plugins/dominant-color-images/tests/test-dominant-color.php b/plugins/dominant-color-images/tests/test-dominant-color.php index 2603e9f356..c4ad65afa1 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color.php +++ b/plugins/dominant-color-images/tests/test-dominant-color.php @@ -27,7 +27,6 @@ public function test_dominant_color_metadata( string $image_path, array $expecte // Creating attachment. $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $dominant_color_metadata = dominant_color_metadata( array(), $attachment_id ); $this->assertArrayHasKey( 'dominant_color', $dominant_color_metadata ); $this->assertNotEmpty( $dominant_color_metadata['dominant_color'] ); @@ -78,7 +77,6 @@ public function test_has_transparency_metadata( string $image_path, array $expec $this->assertEmpty( $transparency_metadata ); $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $transparency_metadata = dominant_color_metadata( array(), $attachment_id ); $this->assertArrayHasKey( 'has_transparency', $transparency_metadata ); $this->assertSame( $expected_transparency, $transparency_metadata['has_transparency'] ); @@ -130,7 +128,6 @@ public function test_tag_add_adjust_to_image_attributes( string $image_path, arr $this->skip_if_mime_type_unsupported( $image_path ); $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); list( $src, $width, $height ) = wp_get_attachment_image_src( $attachment_id ); // Testing tag_add_adjust() with image being lazy load. @@ -167,7 +164,6 @@ public function test_tag_add_adjust_to_image_attributes( string $image_path, arr */ public function test_dominant_color_img_tag_add_dominant_color_requires_proper_quotes( string $image, bool $expected ): void { $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/data/images/red.jpg' ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); $image_url = wp_get_attachment_image_url( $attachment_id ); $image = sprintf( $image, $image_url ); @@ -211,7 +207,6 @@ public function data_dominant_color_img_tag_add_dominant_color_requires_proper_q */ public function test_dominant_color_img_tag_add_dominant_color_should_add_dominant_color_inline_style( string $filtered_image, string $expected ): void { $attachment_id = self::factory()->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/data/images/red.jpg' ); - wp_maybe_generate_attachment_metadata( get_post( $attachment_id ) ); list( $src, $width, $height ) = wp_get_attachment_image_src( $attachment_id ); From 54a1d10eff8ecae1c9d59fc2afc0a1fef7b132e9 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Sun, 7 Jun 2026 20:34:48 -0600 Subject: [PATCH 08/12] use create rather than create_upload_object, which prevents calling dominant_color_get_dominant_color_data. So not redundant to call it afterwards --- .../tests/data/class-testcase.php | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/plugins/dominant-color-images/tests/data/class-testcase.php b/plugins/dominant-color-images/tests/data/class-testcase.php index 6cfab19f23..d1e469432e 100644 --- a/plugins/dominant-color-images/tests/data/class-testcase.php +++ b/plugins/dominant-color-images/tests/data/class-testcase.php @@ -157,10 +157,10 @@ public function provider_get_dominant_color_invalid_images(): array { public function provider_get_dominant_color_none_images(): array { return array( 'pdf' => array( - 'files_path' => TESTS_PLUGIN_DIR . '/tests/data/images/wordpress-gsoc-flyer.pdf', + 'image_path' => TESTS_PLUGIN_DIR . '/tests/data/images/wordpress-gsoc-flyer.pdf', ), 'mp4' => array( - 'files_path' => TESTS_PLUGIN_DIR . '/tests/data/images/small-video.mp4', + 'image_path' => TESTS_PLUGIN_DIR . '/tests/data/images/small-video.mp4', ), ); } @@ -207,33 +207,41 @@ public function test_get_dominant_color_invalid( string $image_path ): void { if ( ! wp_image_editor_supports( array( 'mime_type' => $mime_type ) ) ) { $this->markTestSkipped( "Mime type $mime_type is not supported." ); } - $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); + $attachment_id = self::factory()->attachment->create( + array( + 'post_mime_type' => $mime_type, + ) + ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); $this->assertWPError( $dominant_color_data ); - $this->assertStringContainsString( 'unsupported_attachment_type', $dominant_color_data->get_error_code() ); + $this->assertSame( 'unsupported_attachment_type', $dominant_color_data->get_error_code() ); } /** - * Test the function returns a WP_Error object for unsupported mime types. + * Tests dominant_color_get_dominant_color_data() returns a WP_Error when the + * dominant_color_supported_mime_types filter returns an empty array. * * @covers dominant_color_get_dominant_color_data */ public function test_get_dominant_color_data_unsupported_mime_type(): void { add_filter( 'dominant_color_supported_mime_types', '__return_empty_array' ); - $image_path = TESTS_PLUGIN_DIR . '/tests/data/images/red.jpg'; - $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); + $attachment_id = self::factory()->attachment->create( + array( + 'post_mime_type' => 'image/jpeg', + ) + ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); $this->assertWPError( $dominant_color_data ); - $this->assertStringContainsString( 'unsupported_attachment_type', $dominant_color_data->get_error_code() ); + $this->assertSame( 'unsupported_attachment_type', $dominant_color_data->get_error_code() ); } /** - * Test if the function returns the correct color. + * Tests dominant_color_get_dominant_color_data() returns a WP_Error for non-image file types. * * @covers Dominant_Color_Image_Editor_GD::get_dominant_color * @covers Dominant_Color_Image_Editor_Imagick::get_dominant_color @@ -241,10 +249,20 @@ public function test_get_dominant_color_data_unsupported_mime_type(): void { * @dataProvider provider_get_dominant_color_none_images */ public function test_get_dominant_color_none_images( string $image_path ): void { - $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); + $mime_type = wp_check_filetype( $image_path )['type']; + if ( false === $mime_type ) { + $this->markTestSkipped( 'Mime type is not supported.' ); + } + + $attachment_id = self::factory()->attachment->create( + array( + 'post_mime_type' => $mime_type, + ) + ); $dominant_color_data = dominant_color_get_dominant_color_data( $attachment_id ); $this->assertWPError( $dominant_color_data ); + $this->assertSame( 'unsupported_attachment_type', $dominant_color_data->get_error_code() ); } } From 19a7084282533fbc2c01a1e6ff1b2d49f8bcf6b3 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Sun, 7 Jun 2026 20:34:48 -0600 Subject: [PATCH 09/12] require the editor classes, just in case (seems to be missing when the GD tests tun, though not for imagick) --- .../tests/test-dominant-color-image-editor-gd.php | 5 +++++ .../tests/test-dominant-color-image-editor-imagick.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php index cf67901541..5d21e6f02f 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php +++ b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php @@ -19,6 +19,11 @@ public function set_up(): void { $this->markTestSkipped( 'The GD PHP extension is not loaded.' ); } + // ensure the GD editor is registered. Doesnt seem to be by the time this runs. + require_once ABSPATH . WPINC . '/class-wp-image-editor.php'; + require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php'; + require_once __DIR__ . '/../class-dominant-color-image-editor-gd.php'; + add_filter( 'wp_image_editors', static function ( array $editors ): array { diff --git a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php index 5e30e89d51..5e8beb1c90 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php +++ b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php @@ -26,6 +26,11 @@ public function set_up(): void { $this->markTestSkipped( 'The Imagick PHP extension is not loaded.' ); } + // ensure the Imagick editor is registered, even though it seems to be by the time this runs. + require_once ABSPATH . WPINC . '/class-wp-image-editor.php'; + require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php'; + require_once __DIR__ . '/../class-dominant-color-image-editor-imagick.php'; + add_filter( 'wp_image_editors', static function ( array $editors ): array { From ca3f3f069919b66926554da7bc2889bef560dbd6 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Sun, 7 Jun 2026 20:34:48 -0600 Subject: [PATCH 10/12] implement GD tests --- .../test-dominant-color-image-editor-gd.php | 94 +++++++++++++++++++ .../tests/test-dominant-color.php | 20 ---- 2 files changed, 94 insertions(+), 20 deletions(-) diff --git a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php index 5d21e6f02f..ce8c9e40d1 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php +++ b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php @@ -3,10 +3,14 @@ * Tests for Image Placeholders plugin. * * @package dominant-color-images + * @noinspection PhpComposerExtensionStubsInspection */ use Dominant_Color_Images\Tests\TestCase; +/** + * @coversDefaultClass Dominant_Color_Image_Editor_GD + */ class Test_Dominant_Color_Image_Editor_GD extends TestCase { /** @@ -36,4 +40,94 @@ static function ( $editor ): bool { } ); } + + /** + * @covers ::get_dominant_color + */ + public function test_invalid_image_type(): void { + $editor = new Dominant_Color_Image_Editor_GD( '/invalid/type' ); + $result = $editor->get_dominant_color(); + $this->assertWPError( $result ); + $this->assertSame( 'image_editor_dominant_color_error_no_image', $result->get_error_code() ); + } + + /** + * @covers ::get_dominant_color + */ + public function test_get_dominant_color_no_image(): void { + $editor = new Dominant_Color_Image_Editor_GD( null ); + $result = $editor->get_dominant_color(); + + $this->assertWPError( $result ); + $this->assertSame( 'image_editor_dominant_color_error_no_image', $result->get_error_code() ); + } + + /** + * @covers ::has_transparency + */ + public function test_has_transparency_no_image(): void { + $editor = new Dominant_Color_Image_Editor_GD( null ); + $result = $editor->has_transparency(); + + $this->assertWPError( $result ); + $this->assertSame( 'image_editor_has_transparency_error_no_image', $result->get_error_code() ); + } + + /** + * @covers ::get_dominant_color + */ + public function test_get_dominant_color_success(): void { + $im = imagecreatetruecolor( 1, 1 ); + $red = imagecolorallocate( $im, 255, 0, 0 ); + imagefill( $im, 0, 0, $red ); + + $editor = new Dominant_Color_Image_Editor_GD( null ); + $reflection = new ReflectionClass( $editor ); + $property = $reflection->getProperty( 'image' ); + $property->setAccessible( true ); + $property->setValue( $editor, $im ); + + $result = $editor->get_dominant_color(); + + $this->assertIsArray( $result ); + $this->assertSame( array( 'r' => 255, 'g' => 0, 'b' => 0 ), $result ); + } + + /** + * @covers ::has_transparency + */ + public function test_has_no_transparency(): void { + $im = imagecreatetruecolor( 1, 1 ); + $red = imagecolorallocate( $im, 255, 0, 0 ); + imagefill( $im, 0, 0, $red ); + + $editor = new Dominant_Color_Image_Editor_GD( null ); + $reflection = new ReflectionClass( $editor ); + $property = $reflection->getProperty( 'image' ); + $property->setAccessible( true ); + $property->setValue( $editor, $im ); + + $result = $editor->has_transparency(); + + $this->assertFalse( $result ); + } + + /** + * @covers ::has_transparency + */ + public function test_has_transparency_with_transparency(): void { + $im = imagecreatetruecolor( 1, 1 ); + $alpha_color = imagecolorallocatealpha( $im, 255, 0, 0, 64 ); + imagefill( $im, 0, 0, $alpha_color ); + + $editor = new Dominant_Color_Image_Editor_GD( null ); + $reflection = new ReflectionClass( $editor ); + $property = $reflection->getProperty( 'image' ); + $property->setAccessible( true ); + $property->setValue( $editor, $im ); + + $result = $editor->has_transparency(); + + $this->assertTrue( $result ); + } } diff --git a/plugins/dominant-color-images/tests/test-dominant-color.php b/plugins/dominant-color-images/tests/test-dominant-color.php index c4ad65afa1..4cba206d25 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color.php +++ b/plugins/dominant-color-images/tests/test-dominant-color.php @@ -408,26 +408,6 @@ public function test_dominant_color_render_generator(): void { $this->assertStringContainsString( 'dominant-color-images ' . DOMINANT_COLOR_IMAGES_VERSION, $tag ); } - /** - * @covers Dominant_Color_Image_Editor_GD::get_dominant_color - */ - public function test_invalid_image_type(): void { - $editor = new Dominant_Color_Image_Editor_GD( '/invalid/type' ); - $result = $editor->get_dominant_color(); - $this->assertWPError( $result ); - $this->assertEquals( 'image_editor_dominant_color_error_no_image', $result->get_error_code() ); - } - - /** - * @covers Dominant_Color_Image_Editor_GD::get_dominant_color - */ - public function test_corrupted_image_file(): void { - $editor = new Dominant_Color_Image_Editor_GD( 'path/to/corrupted/file.jpg' ); - $result = $editor->get_dominant_color(); - $this->assertWPError( $result ); - $this->assertEquals( 'image_editor_dominant_color_error_no_image', $result->get_error_code() ); - } - /** * @covers ::dominant_color_add_inline_style */ From 17707796dce8c1db56a656726533a53967a8ed3d Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Wed, 3 Jun 2026 14:37:05 -0600 Subject: [PATCH 11/12] return raw rgb rather than hex. This will facilitate the lqip gradient stuff coming in other PR. Also, cleaner to just convert in one place for all editors --- .../class-dominant-color-image-editor-gd.php | 17 +++++++---------- ...lass-dominant-color-image-editor-imagick.php | 14 +++++++------- plugins/dominant-color-images/helper.php | 11 ++++++++++- ...test-dominant-color-image-editor-imagick.php | 2 +- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/plugins/dominant-color-images/class-dominant-color-image-editor-gd.php b/plugins/dominant-color-images/class-dominant-color-image-editor-gd.php index df4be5633a..be78b128d6 100644 --- a/plugins/dominant-color-images/class-dominant-color-image-editor-gd.php +++ b/plugins/dominant-color-images/class-dominant-color-image-editor-gd.php @@ -21,11 +21,11 @@ class Dominant_Color_Image_Editor_GD extends WP_Image_Editor_GD { /** - * Get dominant color from a file. + * Get dominant color from a file as raw RGB values. * * @since 1.0.0 * - * @return string|WP_Error Dominant hex color string, or an error on failure. + * @return array{r: int, g: int, b: int}|WP_Error RGB values (0-255), or WP_Error on failure. */ public function get_dominant_color() { @@ -49,15 +49,12 @@ public function get_dominant_color() { if ( false === $rgb ) { return new WP_Error( 'image_editor_dominant_color_error', __( 'Dominant color detection failed.', 'dominant-color-images' ) ); } - $r = ( $rgb >> 16 ) & 0xFF; - $g = ( $rgb >> 8 ) & 0xFF; - $b = $rgb & 0xFF; - $hex = dominant_color_rgb_to_hex( $r, $g, $b ); - if ( null === $hex ) { - return new WP_Error( 'image_editor_dominant_color_error', __( 'Dominant color detection failed.', 'dominant-color-images' ) ); - } - return $hex; + return array( + 'r' => ( $rgb >> 16 ) & 0xFF, + 'g' => ( $rgb >> 8 ) & 0xFF, + 'b' => $rgb & 0xFF, + ); } /** diff --git a/plugins/dominant-color-images/class-dominant-color-image-editor-imagick.php b/plugins/dominant-color-images/class-dominant-color-image-editor-imagick.php index f42c957142..013e375518 100644 --- a/plugins/dominant-color-images/class-dominant-color-image-editor-imagick.php +++ b/plugins/dominant-color-images/class-dominant-color-image-editor-imagick.php @@ -21,11 +21,11 @@ class Dominant_Color_Image_Editor_Imagick extends WP_Image_Editor_Imagick { /** - * Get dominant color from a file. + * Get dominant color from a file as raw RGB values. * * @since 1.0.0 * - * @return string|WP_Error Dominant hex color string, or an error on failure. + * @return array{r: int, g: int, b: int}|WP_Error RGB values (0-255), or WP_Error on failure. */ public function get_dominant_color() { @@ -38,12 +38,12 @@ public function get_dominant_color() { $this->image->resizeImage( 1, 1, Imagick::FILTER_LANCZOS, 1 ); $pixel = $this->image->getImagePixelColor( 0, 0 ); $color = $pixel->getColor(); - $hex = dominant_color_rgb_to_hex( $color['r'], $color['g'], $color['b'] ); - if ( null === $hex ) { - return new WP_Error( 'image_editor_dominant_color_error', __( 'Dominant color detection failed.', 'dominant-color-images' ) ); - } - return $hex; + return array( + 'r' => $color['r'], + 'g' => $color['g'], + 'b' => $color['b'], + ); } catch ( Exception $e ) { /* translators: %s is the error message. */ return new WP_Error( 'image_editor_dominant_color_error', sprintf( __( 'Dominant color detection failed: %s', 'dominant-color-images' ), $e->getMessage() ) ); diff --git a/plugins/dominant-color-images/helper.php b/plugins/dominant-color-images/helper.php index 57353ae785..56e04eef08 100644 --- a/plugins/dominant-color-images/helper.php +++ b/plugins/dominant-color-images/helper.php @@ -130,7 +130,16 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) { if ( is_wp_error( $dominant_color ) ) { return $dominant_color; } - $dominant_color_data['dominant_color'] = $dominant_color; + + $hex = dominant_color_rgb_to_hex( $dominant_color['r'], $dominant_color['g'], $dominant_color['b'] ); + if ( null === $hex ) { + return new WP_Error( + 'image_editor_dominant_color_error', + __( 'Dominant color detection failed.', 'dominant-color-images' ) + ); + } + $dominant_color_data['dominant_color'] = $hex; + return $dominant_color_data; } diff --git a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php index 5e8beb1c90..f6823a5977 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php +++ b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php @@ -152,7 +152,7 @@ public function test_get_dominant_color_success(): void { $result = $editor->get_dominant_color(); - $this->assertEquals( 'ff0000', $result ); + $this->assertEquals( array( 'r' => 255, 'g' => 0, 'b' => 0 ), $result ); } /** From ea2c1833caedabb5dca5bb6a08128f738bf707e2 Mon Sep 17 00:00:00 2001 From: Nick Chomey Date: Mon, 8 Jun 2026 09:06:29 -0600 Subject: [PATCH 12/12] fix linting --- plugins/dominant-color-images/helper.php | 5 ++-- .../test-dominant-color-image-editor-gd.php | 27 ++++++++++++------- ...st-dominant-color-image-editor-imagick.php | 9 ++++++- .../tests/test-dominant-color.php | 4 +-- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/plugins/dominant-color-images/helper.php b/plugins/dominant-color-images/helper.php index 56e04eef08..404e8d8398 100644 --- a/plugins/dominant-color-images/helper.php +++ b/plugins/dominant-color-images/helper.php @@ -140,7 +140,6 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) { } $dominant_color_data['dominant_color'] = $hex; - return $dominant_color_data; } @@ -150,9 +149,9 @@ function dominant_color_get_dominant_color_data( int $attachment_id ) { * @since 1.0.0 * * @param int $attachment_id Attachment ID. - * @return array|null Attachment metadata array or null if not an image or metadata unavailable. + * @return array|null Attachment metadata array, or null if not an image or metadata unavailable. */ -function dominant_color_get_attachment_metadata( int $attachment_id ) { +function dominant_color_get_attachment_metadata( int $attachment_id ): ?array { if ( ! wp_attachment_is_image( $attachment_id ) ) { return null; diff --git a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php index ce8c9e40d1..24c9300b60 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php +++ b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-gd.php @@ -77,33 +77,40 @@ public function test_has_transparency_no_image(): void { * @covers ::get_dominant_color */ public function test_get_dominant_color_success(): void { - $im = imagecreatetruecolor( 1, 1 ); + $im = imagecreatetruecolor( 1, 1 ); $red = imagecolorallocate( $im, 255, 0, 0 ); imagefill( $im, 0, 0, $red ); - $editor = new Dominant_Color_Image_Editor_GD( null ); + $editor = new Dominant_Color_Image_Editor_GD( null ); $reflection = new ReflectionClass( $editor ); - $property = $reflection->getProperty( 'image' ); + $property = $reflection->getProperty( 'image' ); $property->setAccessible( true ); $property->setValue( $editor, $im ); $result = $editor->get_dominant_color(); $this->assertIsArray( $result ); - $this->assertSame( array( 'r' => 255, 'g' => 0, 'b' => 0 ), $result ); + $this->assertSame( + array( + 'r' => 255, + 'g' => 0, + 'b' => 0, + ), + $result + ); } /** * @covers ::has_transparency */ public function test_has_no_transparency(): void { - $im = imagecreatetruecolor( 1, 1 ); + $im = imagecreatetruecolor( 1, 1 ); $red = imagecolorallocate( $im, 255, 0, 0 ); imagefill( $im, 0, 0, $red ); - $editor = new Dominant_Color_Image_Editor_GD( null ); + $editor = new Dominant_Color_Image_Editor_GD( null ); $reflection = new ReflectionClass( $editor ); - $property = $reflection->getProperty( 'image' ); + $property = $reflection->getProperty( 'image' ); $property->setAccessible( true ); $property->setValue( $editor, $im ); @@ -116,13 +123,13 @@ public function test_has_no_transparency(): void { * @covers ::has_transparency */ public function test_has_transparency_with_transparency(): void { - $im = imagecreatetruecolor( 1, 1 ); + $im = imagecreatetruecolor( 1, 1 ); $alpha_color = imagecolorallocatealpha( $im, 255, 0, 0, 64 ); imagefill( $im, 0, 0, $alpha_color ); - $editor = new Dominant_Color_Image_Editor_GD( null ); + $editor = new Dominant_Color_Image_Editor_GD( null ); $reflection = new ReflectionClass( $editor ); - $property = $reflection->getProperty( 'image' ); + $property = $reflection->getProperty( 'image' ); $property->setAccessible( true ); $property->setValue( $editor, $im ); diff --git a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php index f6823a5977..f39f474341 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php +++ b/plugins/dominant-color-images/tests/test-dominant-color-image-editor-imagick.php @@ -152,7 +152,14 @@ public function test_get_dominant_color_success(): void { $result = $editor->get_dominant_color(); - $this->assertEquals( array( 'r' => 255, 'g' => 0, 'b' => 0 ), $result ); + $this->assertEquals( + array( + 'r' => 255, + 'g' => 0, + 'b' => 0, + ), + $result + ); } /** diff --git a/plugins/dominant-color-images/tests/test-dominant-color.php b/plugins/dominant-color-images/tests/test-dominant-color.php index 4cba206d25..1dbf52bdb5 100644 --- a/plugins/dominant-color-images/tests/test-dominant-color.php +++ b/plugins/dominant-color-images/tests/test-dominant-color.php @@ -26,7 +26,7 @@ public function test_dominant_color_metadata( string $image_path, array $expecte $this->assertEmpty( $dominant_color_metadata ); // Creating attachment. - $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); + $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); $dominant_color_metadata = dominant_color_metadata( array(), $attachment_id ); $this->assertArrayHasKey( 'dominant_color', $dominant_color_metadata ); $this->assertNotEmpty( $dominant_color_metadata['dominant_color'] ); @@ -76,7 +76,7 @@ public function test_has_transparency_metadata( string $image_path, array $expec $transparency_metadata = dominant_color_metadata( array(), 1 ); $this->assertEmpty( $transparency_metadata ); - $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); + $attachment_id = self::factory()->attachment->create_upload_object( $image_path ); $transparency_metadata = dominant_color_metadata( array(), $attachment_id ); $this->assertArrayHasKey( 'has_transparency', $transparency_metadata ); $this->assertSame( $expected_transparency, $transparency_metadata['has_transparency'] );