diff --git a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php index 7b3ae9d160d11..ca69a601cbca2 100644 --- a/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php +++ b/src/wp-includes/rest-api/endpoints/class-wp-rest-attachments-controller.php @@ -1614,19 +1614,15 @@ public function prepare_item_for_response( $item, $request ) { * Per-file output format for images, evaluated with the real filename * and MIME type so plugins filtering image_editor_output_format can * make per-attachment decisions (e.g. JPEG -> WebP). Resolved the same - * way WP_Image_Editor::set_quality() resolves the output format. + * way WP_Image_Editor::get_output_format() resolves the output format. */ if ( in_array( 'image_output_format', $fields, true ) ) { $filename = get_attached_file( $post->ID ); - /** This filter is documented in wp-includes/media.php */ - $output_formats = apply_filters( - 'image_editor_output_format', - array( $mime_type => $mime_type ), + $output_formats = wp_get_image_editor_output_format( $filename ? $filename : '', $mime_type ); - $output_mime = $output_formats[ $mime_type ] ?? $mime_type; $data['image_output_format'] = ( $output_mime !== $mime_type ) ? $output_mime : null; } @@ -1643,10 +1639,7 @@ public function prepare_item_for_response( $item, $request ) { if ( in_array( 'image_quality', $fields, true ) ) { $filename = get_attached_file( $post->ID ); - /** This filter is documented in wp-includes/media.php */ - $output_formats = apply_filters( - 'image_editor_output_format', - array( $mime_type => $mime_type ), + $output_formats = wp_get_image_editor_output_format( $filename ? $filename : '', $mime_type ); diff --git a/tests/phpunit/tests/rest-api/rest-attachments-controller.php b/tests/phpunit/tests/rest-api/rest-attachments-controller.php index 5ae35d5ee370d..46390261862c0 100644 --- a/tests/phpunit/tests/rest-api/rest-attachments-controller.php +++ b/tests/phpunit/tests/rest-api/rest-attachments-controller.php @@ -2356,6 +2356,37 @@ static function ( $formats, $filename, $mime_type ) use ( &$captured ) { $this->assertSame( 'image/jpeg', $captured['mime_type'] ); } + /** + * Verifies image_output_format respects filters that use array union (+) + * without overwriting existing keys, ensuring parity with WP_Image_Editor::get_output_format(). + * + * @ticket 64677 + * + * @covers WP_REST_Attachments_Controller::prepare_item_for_response + */ + public function test_image_output_format_with_array_union_filter(): void { + wp_set_current_user( self::$superadmin_id ); + + $attachment_id = self::factory()->attachment->create_upload_object( DIR_TESTDATA . '/images/canola.jpg' ); + + add_filter( + 'image_editor_output_format', + static function ( $formats ) { + return $formats + array( 'image/jpeg' => 'image/webp' ); + } + ); + + $request = new WP_REST_Request( 'GET', '/wp/v2/media/' . $attachment_id ); + $request->set_param( 'context', 'edit' ); + + $response = rest_get_server()->dispatch( $request ); + $data = $response->get_data(); + + $this->assertSame( 200, $response->get_status() ); + $this->assertArrayHasKey( 'image_output_format', $data ); + $this->assertSame( 'image/webp', $data['image_output_format'] ); + } + /** * Verifies image_save_progressive surfaces the filter result for the * attachment's MIME type.