Skip to content
18 changes: 5 additions & 13 deletions modules/images/webp-uploads/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -709,8 +709,7 @@ function webp_uploads_update_rest_attachment( WP_REST_Response $response, WP_Pos
/**
* Returns the attachment sources array ordered by filesize.
*
* @since n.e.xt
* @private
* @since n.e.x.t
*
* @param int $attachment_id The attachment ID.
* @param string $size The attachment size.
Expand Down Expand Up @@ -739,8 +738,7 @@ function webp_uploads_get_attachment_sources( $attachment_id, $size = 'thumbnail
* Filters on `webp_uploads_content_image_mimes` to generate the available mime types for an attachment
* and orders them by the smallest filesize first.
*
* @since n.e.xt
* @private
* @since n.e.x.t
*
* @param array $mime_types The list of mime types that can be used to update images in the content.
* @param int $attachment_id The attachment ID.
Expand All @@ -759,25 +757,19 @@ function webp_uploads_get_mime_types_by_filesize( $mime_types, $attachment_id, $
$sources = array_filter(
$sources,
function( $source ) {
return $source['filesize'] > 0;
return isset( $source['filesize'] ) && $source['filesize'] > 0;
}
);

// Order sources by filesize in ascending order.
uasort(
$sources,
function( $a, $b ) {
if ( $a['filesize'] === $b['filesize'] ) {
return 0;
}

return ( $a['filesize'] < $b['filesize'] ) ? -1 : 1;
return $a['filesize'] - $b['filesize'];
}
);

// Create an array of available mime types ordered by smallest filesize.
$mime_types = array_values( array_keys( $sources ) );

return $mime_types;
return array_keys( $sources );
}
add_filter( 'webp_uploads_content_image_mimes', 'webp_uploads_get_mime_types_by_filesize', 10, 3 );
91 changes: 91 additions & 0 deletions tests/modules/images/webp-uploads/webp-uploads-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -808,4 +808,95 @@ function( $transforms ) {
$this->assertImageNotHasSizeSource( $attachment_id, $size_name, 'image/jpeg' );
}
}

/**
* Test webp_uploads_get_mime_types_by_filesize returns smallest filesize, in this case webp.
*
* @test
*/
public function it_should_return_smaller_webp_mime_type() {
// File should generate smallest webp image size.
$attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/car.jpeg' );

$mime_types = webp_uploads_get_mime_types_by_filesize( array( 'image/jpeg', 'image/webp' ), $attachment_id, 'the_content' );

$this->assertIsArray( $mime_types );
$this->assertSame( 'image/webp', $mime_types[0] );
$this->assertSame( 'image/jpeg', $mime_types[1] );
}

/**
* Test webp_uploads_get_mime_types_by_filesize returns smallest filesize, in this case jpeg.
*
* @test
*/
public function it_should_return_smaller_jpeg_mime_type() {
// File should generate smallest jpeg image size.
$attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/paint.jpeg' );

// Mock attachment meta data to test when jpeg image is smaller.
add_filter(
'wp_get_attachment_metadata',
function( $data, $attachment_id ) {
$data['sources'] = array(
'image/jpeg' => array(
'file' => 'paint.jpeg',
'filesize' => 1000,
),
'image/webp' => array(
'file' => 'paint.webp',
'filesize' => 2000,
),
);
},
10,
2
);

$mime_types = webp_uploads_get_mime_types_by_filesize( array( 'image/jpeg', 'image/webp' ), $attachment_id, 'the_content' );

$this->assertIsArray( $mime_types );
$this->assertSame( 'image/jpeg', $mime_types[0] );
$this->assertSame( 'image/webp', $mime_types[1] );
}

/**
* Test webp_uploads_get_mime_types_by_filesize removes invalid mime types with zero filesize.
*
* @test
*/
public function it_should_remove_mime_types_with_zero_filesize() {
// File should generate smallest jpeg image size.
$attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/paint.jpeg' );

// Mock attachment meta data to test mime type with zero filesize.
add_filter(
'wp_get_attachment_metadata',
function( $data, $attachment_id ) {
$data['sources'] = array(
'image/jpeg' => array(
'file' => 'paint.jpeg',
'filesize' => 1000,
),
'image/webp' => array(
'file' => 'paint.webp',
'filesize' => 2000,
),
'image/invalid' => array(
'file' => 'paint.avif',
'filesize' => 0,
),
);
},
10,
2
);

$mime_types = webp_uploads_get_mime_types_by_filesize( array( 'image/jpeg', 'image/webp' ), $attachment_id, 'the_content' );

$this->assertIsArray( $mime_types );
$this->assertNotContains( 'image/invalid', $mime_types );
$this->assertSame( 'image/jpeg', $mime_types[0] );
$this->assertSame( 'image/webp', $mime_types[1] );
}
}