I have written this function code for compressing and converting uploading images to WebP format using Imagick and adding them to media library and delete the original uploading file format.
I've written this function at WordPress Theme Functions (functions.php):
/*
* Compress and convert to WebP for uploading images
*/
function compress_and_convert_images_to_webp($file) {
// Check if file type is supported
$supported_types = ['image/jpeg', 'image/jpg', 'image/png'];
if (!in_array($file['type'], $supported_types)) {
return $file;
}
// Get the path to the upload directory
$wp_upload_dir = wp_upload_dir();
// Set up the file paths
$old_file_path = $file['file'];
$file_name = basename($file['file']);
$webp_file_path = $wp_upload_dir['path'] . '/' . pathinfo($file_name, PATHINFO_FILENAME) . '.webp';
// Check if file is already a WebP image
if (pathinfo($old_file_path, PATHINFO_EXTENSION) === 'webp') {
return $file;
}
// Load the image using Imagick
$image = new Imagick($old_file_path);
// Compress the image
$quality = 75; // Adjust this value to control the compression level
$image->setImageCompressionQuality($quality);
$image->stripImage(); // Remove all profiles and comments to reduce file size
// Convert the image to WebP
$image->setImageFormat('webp');
$image->setOption('webp:lossless', 'false');
$image->setOption('webp:method', '6'); // Adjust this value to control the compression level for WebP
$image->writeImage($webp_file_path);
// Allow WebP mime type
add_filter('upload_mimes', function($mimes) {
$mimes['webp'] = 'image/webp';
return $mimes;
});
// Set file permissions to 0644
chmod($webp_file_path, 0644);
// Add the new WebP image to the media library
$attachment_id = media_handle_upload(pathinfo($file_name, PATHINFO_FILENAME), 0, [
'post_mime_type' => 'image/webp',
'file' => $webp_file_path
]);
if (is_wp_error($attachment_id)) {
error_log("The Attachment ID Error is: " . $attachment_id->get_error_message());
}
// Delete the old image file
unlink($old_file_path);
// Update the attachment metadata with the WebP image URL
update_post_meta($attachment_id, '_wp_attached_file', substr($webp_file_path, strlen($wp_upload_dir['basedir']) + 1));
// Return the updated file information
return [
'file' => $webp_file_path,
'url' => wp_get_attachment_url($attachment_id),
'type' => 'image/webp',
];
}
add_filter('wp_handle_upload', 'compress_and_convert_images_to_webp');
This code works fine and compress and convert uploading image files and show them in media library and deletes uploading original format but it raise warnings every time I upload new file.
I've searched about warnings and they are about "$attachment_id" variable problem:
as you can see this variable uses "media_handle_upload" function for getting new attachment ID but it returns this error (WP_ERROR object):
"Specified file failed upload test.".
the warning messages are:
PHP Warning: Trying to access array offset on value of type null in wp-admin/includes/file.php on line 906
PHP Deprecated: is_uploaded_file(): Passing null to parameter #1 ($filename) of type string is deprecated in wp-admin/includes/file.php on line 906
PHP Warning: Object of class WP_Error could not be converted to int in wp-includes/post.php on line 6590
What should I do?