Duplicate image sizes result in broken thumbnails and bad metadata
-
Hi there @katsushi-kawamori, hope you’re doing well. We’ve been installing your plugin on more of our sites and it’s been a great experience overall.
We did end up finding one bug on one of our WooCommerce sites in which the image thumbnails were appearing broken in the Media Library due to it trying to load them as image-100×100.png rather than image-100×100.webp.
Strangely, the bug was only happening on one of our WooCommerce sites but not the others. After some initial debugging, we first thought that it was due to a three-way plugin conflict with WooCommerce, your plugin, and a WooCommerce extension, but after digging deep into the issue, we found that it wasn’t directly related to WooCommerce or the other plugin but rather due to any two plugins defining the same image size.
Here’s an example of a snippet that will break the thumbnails when your plugin’s “Replace” setting is enabled:
add_action( 'init', 'webpdebug_add_image_sizes');
function webpdebug_add_image_sizes()
{
add_image_size( 'webpdebug_bugtest_size', 100, 100, 1 );
add_image_size( 'woocommerce_gallery_thumbnail', 100, 100, 1 );
}After doing a deep dive into your plugin’s code, we found that this code in /lib/class-pluswebp.php was the source of the issue:
foreach ( (array) $metadata['sizes'] as $key => $value )
{
$file_thumb = $value['file'];
$file_thumb_webp = $this->change_ext( $file_thumb, $ext, $pluswebp_settings['addext'] );
$ret = $this->create_webp( $path . $file_thumb, $mime_type, $path . $file_thumb_webp, $pluswebp_settings['quality'], $pluswebp_settings['output_mime'] );
if ( $ret || file_exists($path . $file_thumb_webp) )
{
$metadata_webp['sizes'][ $key ]['file'] = $file_thumb_webp;
$metadata_webp['sizes'][ $key ]['mime-type'] = $pluswebp_settings['output_mime'];
$webp_size = filesize( $path . wp_basename( $file_thumb_webp ) );
$metadata_webp['sizes'][ $key ]['filesize'] = $webp_size;
if ( $pluswebp_settings['replace'] )
{
wp_delete_file( $path . $file_thumb );
$this->change_db( $url . $file_thumb, $url . $file_thumb_webp );
}
}
}The code above has a bug where, if the WebP or AVIF image already exists, it won’t update the database value due to the create_webp call returning false.
We experimented with several different fixes and found that the most straightforward fix is just a simple fallback condition that checks to see if the image already exists:
if ( $ret || file_exists($path . $file_thumb_webp) )
Technically there are other possible ways to fix it like performing the file_exists check in the create_webp function and returning true instead of false, but either way should be fine.
- You must be logged in to reply to this topic.