Skip to content

Commit 3e52cfe

Browse files
fix: add logic for sending convert_to params
1 parent 546fe25 commit 3e52cfe

File tree

2 files changed

+112
-7
lines changed

2 files changed

+112
-7
lines changed

src/class-tiny-image.php

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
class Tiny_Image {
2222
const ORIGINAL = 0;
2323

24+
/** @var Tiny_Settings */
2425
private $settings;
2526
private $id;
2627
private $name;
@@ -179,7 +180,6 @@ public function compress() {
179180
$success = 0;
180181
$failed = 0;
181182

182-
$compressor = $this->settings->get_compressor();
183183
$active_tinify_sizes = $this->settings->get_active_tinify_sizes();
184184

185185
if ( $this->settings->get_conversion_enabled() ) {
@@ -191,20 +191,26 @@ public function compress() {
191191
$unprocessed_sizes = $this->filter_image_sizes( 'uncompressed', $active_tinify_sizes );
192192
}
193193

194+
$compressor = $this->settings->get_compressor();
195+
$convert_to = $this->convert_to();
196+
194197
foreach ( $unprocessed_sizes as $size_name => $size ) {
195198
if ( ! $size->is_duplicate() ) {
196199
$size->add_tiny_meta_start();
197200
$this->update_tiny_post_meta();
198201
$resize = $this->settings->get_resize_options( $size_name );
199202
$preserve = $this->settings->get_preserve_options( $size_name );
200-
$convert_opts = $this->settings->get_conversion_options();
201203
try {
202204
$response = $compressor->compress_file(
203205
$size->filename,
204206
$resize,
205207
$preserve,
206-
$convert_opts
208+
$convert_to
207209
);
210+
211+
// ensure that all conversion are in the same format as the first one
212+
$convert_to = isset($response['convert']) ? array($response['convert']['type']) : $convert_to;
213+
208214
$size->add_tiny_meta( $response );
209215
$success++;
210216
} catch ( Tiny_Exception $e ) {
@@ -243,17 +249,19 @@ public function compress_retina( $size_name, $path ) {
243249
if ( ! isset( $this->sizes[ $size_name ] ) ) {
244250
$this->sizes[ $size_name ] = new Tiny_Image_Size( $path );
245251
}
252+
246253
$size = $this->sizes[ $size_name ];
254+
255+
$compressor = $this->settings->get_compressor();
256+
$convert_to = $this->convert_to();
247257

248258
if ( ! $size->has_been_compressed() ) {
249259
$size->add_tiny_meta_start();
250260
$this->update_tiny_post_meta();
251-
$compressor = $this->settings->get_compressor();
252261
$preserve = $this->settings->get_preserve_options( $size_name );
253-
$conversion = $this->settings->get_conversion_options();
254262

255263
try {
256-
$response = $compressor->compress_file( $path, false, $preserve, $conversion );
264+
$response = $compressor->compress_file( $path, false, $preserve, $convert_to );
257265
$size->add_tiny_meta( $response );
258266
} catch ( Tiny_Exception $e ) {
259267
$size->add_tiny_meta_error( $e );
@@ -472,6 +480,37 @@ public function can_be_converted() {
472480
return $this->settings->get_conversion_enabled() && $this->file_type_allowed();
473481
}
474482

483+
/**
484+
* Get the targeted conversion.
485+
* If original is already converted, then we use the originals' mimetype.
486+
* If nothing is converted yet, we use the settings conversion settings.
487+
*
488+
* @since 3.6.4
489+
*
490+
* @return array{string} mimetypes to which the image should be converted to
491+
*/
492+
private function convert_to() {
493+
$convert_settings = $this->settings->get_conversion_options();
494+
if ( ! $convert_settings['convert'] ) {
495+
// conversion is off so return no mimetypes to convert to
496+
return array();
497+
}
498+
499+
if ( isset( $this->sizes[ self::ORIGINAL ] ) ) {
500+
// original is not in sizes so mimetypes are open
501+
return $convert_settings['convert_to'];
502+
}
503+
504+
$original_img_size = $this->sizes[ self::ORIGINAL ];
505+
if ( $original_img_size->converted() ) {
506+
// original has been convert so use that mimetype to convert to
507+
return array($original_img_size->meta['convert']['type']);
508+
}
509+
510+
return $convert_settings['convert_to'];
511+
512+
}
513+
475514
/**
476515
* Marks the image as compressed without actually compressing it.
477516
*

test/unit/TinyImageTest.php

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ public function test_update_tiny_post_data_should_call_do_action() {
176176
* In case a customer has already compressed a couple of images and then turns
177177
* on the conversion feature.
178178
*/
179-
public function test_compressed_images_can_be_converted() {
179+
public function test_compressed_images_can_be_converted() {
180180
// Enable conversion and all image sizes
181181
$this->wp->addOption('tinypng_conversion_enabled', true);
182182
$this->wp->addOption('tinypng_convert_to', 'smallest');
@@ -194,4 +194,70 @@ public function test_compressed_images_can_be_converted() {
194194
$this->assertCount(4, $unconverted_sizes, 'All 4 sizes should be converted');
195195
$this->assertCount(4, $unprocessed_sizes, 'All sizes should be processed');
196196
}
197+
198+
/**
199+
* Test conversion to see if follow-up conversion will be done with the same mimetype
200+
*/
201+
public function test_conversion_same_mimetype()
202+
{
203+
$this->wp->addOption('tinypng_convert_format', array(
204+
'convert' => 'on',
205+
'convert_to' => 'smallest',
206+
));
207+
$this->wp->addOption('tinypng_sizes', array(
208+
Tiny_Image::ORIGINAL => 'on',
209+
'thumbnail' => 'on',
210+
));
211+
$this->wp->createImages(array(
212+
'thumbnail' => 1000,
213+
));
214+
$this->wp->stub('get_post_mime_type', function () {
215+
return 'image/png';
216+
});
217+
218+
$metadata = $this->wp->getTestMetadata();
219+
$settings = new Tiny_Settings();
220+
221+
// create a mock compressor to spy on calls
222+
$mock_compressor = $this->createMock(Tiny_Compress::class);
223+
224+
// we expect for all sizes a webp
225+
$converted_type = 'image/webp';
226+
$responses = array(
227+
array(
228+
'input' => array('size' => 1000),
229+
'output' => array('size' => 800, 'type' => 'image/png'),
230+
'convert' => array('type' => $converted_type, 'size' => 750, 'path' => 'vfs://root/converted-1.webp'),
231+
),
232+
array(
233+
'input' => array('size' => 1000),
234+
'output' => array('size' => 780, 'type' => 'image/png'),
235+
'convert' => array('type' => $converted_type, 'size' => 720, 'path' => 'vfs://root/converted-2.webp'),
236+
),
237+
);
238+
239+
$compress_calls = array();
240+
$mock_compressor->expects($this->exactly(2))
241+
->method('compress_file')
242+
->willReturnCallback(function ($file, $resize, $preserve, $convert_to) use (&$compress_calls, &$responses) {
243+
$compress_calls[] = array(
244+
'file' => $file,
245+
'convert_to' => $convert_to,
246+
);
247+
return array_shift($responses);
248+
});
249+
$settings->set_compressor($mock_compressor);
250+
251+
$tinyimg = new Tiny_Image($settings, 999, $metadata);
252+
$tinyimg->compress();
253+
254+
// should have been 2 calls to our mock 'compress_file'
255+
$this->assertCount(2, $compress_calls);
256+
257+
// first call would have been width all mimetypes
258+
$this->assertEquals(array('image/avif', 'image/webp'), $compress_calls[0]['convert_to']);
259+
260+
// second call should be only with image/webp because first call was a image/webp
261+
$this->assertEquals(array('image/webp'), $compress_calls[1]['convert_to']);
262+
}
197263
}

0 commit comments

Comments
 (0)