From 72a43bca8ffcb3f7598165f53f3e7296d1f6c042 Mon Sep 17 00:00:00 2001 From: Adam Silverstein Date: Fri, 7 Oct 2022 19:01:32 +0000 Subject: [PATCH] Media: improve image engine detection when using the output format filter. When the output format is altered with the `image_editor_output_format` filter, prefer the image engine that supports both input an output types, falling back to the engine that supports the input type. Correct an issue where the output format filter wasn't respected because the selected engine didn't support the output format. Props mikeschroder, ironprogrammer. Fixes #54476. git-svn-id: https://develop.svn.wordpress.org/trunk@54416 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/media.php | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index 065efde579..b12d8bd7ae 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -3838,6 +3838,7 @@ function wp_max_upload_size() { function wp_get_image_editor( $path, $args = array() ) { $args['path'] = $path; + // If the mime type is not set in args, try to extract and set it from the file. if ( ! isset( $args['mime_type'] ) ) { $file_info = wp_check_filetype( $args['path'] ); @@ -3848,6 +3849,15 @@ function wp_get_image_editor( $path, $args = array() ) { } } + // Check and set the output mime type mapped to the input type. + if ( isset( $args['mime_type'] ) ) { + /** This filter is documented in wp-includes/class-wp-image-editor.php */ + $output_format = apply_filters( 'image_editor_output_format', array(), $path, $args['mime_type'] ); + if ( isset( $output_format[ $args['mime_type'] ] ) ) { + $args['output_mime_type'] = $output_format[ $args['mime_type'] ]; + } + } + $implementation = _wp_image_editor_choose( $args ); if ( $implementation ) { @@ -3900,12 +3910,14 @@ function _wp_image_editor_choose( $args = array() ) { * 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD'. */ $implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) ); + $supports_input = false; foreach ( $implementations as $implementation ) { if ( ! call_user_func( array( $implementation, 'test' ), $args ) ) { continue; } + // Implementation should support the passed mime type. if ( isset( $args['mime_type'] ) && ! call_user_func( array( $implementation, 'supports_mime_type' ), @@ -3914,16 +3926,31 @@ function _wp_image_editor_choose( $args = array() ) { continue; } + // Implementation should support requested methods. if ( isset( $args['methods'] ) && array_diff( $args['methods'], get_class_methods( $implementation ) ) ) { continue; } + // Implementation should ideally support the output mime type as well if set and different than the passed type. + if ( + isset( $args['mime_type'] ) && + isset( $args['output_mime_type'] ) && + $args['mime_type'] !== $args['output_mime_type'] && + ! call_user_func( array( $implementation, 'supports_mime_type' ), $args['output_mime_type'] ) + ) { + // This implementation supports the imput type but not the output type. + // Keep looking to see if we can find an implementation that supports both. + $supports_input = $implementation; + continue; + } + + // Favor the implementation that supports both input and output mime types. return $implementation; } - return false; + return $supports_input; } /**