<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[54416] trunk/src/wp-includes/media.php: Media: improve image engine detection when using the output format filter.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/54416">54416</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/54416","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>adamsilverstein</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2022-10-07 19:01:32 +0000 (Fri, 07 Oct 2022)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>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 <a href="https://core.trac.wordpress.org/ticket/54476">#54476</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesmediaphp">trunk/src/wp-includes/media.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesmediaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/media.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/media.php   2022-10-07 15:44:31 UTC (rev 54415)
+++ trunk/src/wp-includes/media.php     2022-10-07 19:01:32 UTC (rev 54416)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3838,6 +3838,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> function wp_get_image_editor( $path, $args = array() ) {
</span><span class="cx" style="display: block; padding: 0 10px">        $args['path'] = $path;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        // If the mime type is not set in args, try to extract and set it from the file.
</ins><span class="cx" style="display: block; padding: 0 10px">         if ( ! isset( $args['mime_type'] ) ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $file_info = wp_check_filetype( $args['path'] );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3848,6 +3849,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        // 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'] ];
+               }
+       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $implementation = _wp_image_editor_choose( $args );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( $implementation ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3900,6 +3910,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *                                'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD'.
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        $implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+        $supports_input  = false;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        foreach ( $implementations as $implementation ) {
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! call_user_func( array( $implementation, 'test' ), $args ) ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3906,6 +3917,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        continue;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                // Implementation should support the passed mime type.
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( isset( $args['mime_type'] ) &&
</span><span class="cx" style="display: block; padding: 0 10px">                        ! call_user_func(
</span><span class="cx" style="display: block; padding: 0 10px">                                array( $implementation, 'supports_mime_type' ),
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3914,6 +3926,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        continue;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                // Implementation should support requested methods.
</ins><span class="cx" style="display: block; padding: 0 10px">                 if ( isset( $args['methods'] ) &&
</span><span class="cx" style="display: block; padding: 0 10px">                        array_diff( $args['methods'], get_class_methods( $implementation ) ) ) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3920,10 +3933,24 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        continue;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                // 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.
</ins><span class="cx" style="display: block; padding: 0 10px">                 return $implementation;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        return false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return $supports_input;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px"> /**
</span></span></pre>
</div>
</div>

</body>
</html>