imagify-plugin
imagify-plugin copied to clipboard
Add compatibility for Responsive Pics
Responsive pics compatibility
I am using https://github.com/clarifynl/responsive-pics in a lot of projects, but imagify is not optimizing the images generated by Responsive Pics. I did some digging, and I assume the best way to add compatibility, is to add the generated images in the imagify_media_files
filter.
How Responsive Pics works
In my template, I fetch an image from the media library (let’s say with an ID of 5, 2024/01/filename.png
). We can define the width and aspect ratio we want to generate:
ResponsivePics::get_image(5, 'md-6, xl-4', 1)
When the image is requested for the first time (first page view), an action is scheduled to generate the requested image sizes. When action scheduler has run the queue, the images are placed in the same upload directory (2024/01/filename-330x330-crop-50-50.png
, 2024/01/[email protected]
etc.)
Working solution
Add generated images to imagify_media_files
add_filter('imagify_media_files', function ($files, $mediaObject) {
$fileName = pathinfo($mediaObject->get_raw_original_path(), PATHINFO_FILENAME);
$fileExtension = pathinfo($mediaObject->get_raw_original_path(), PATHINFO_EXTENSION);
$filePath = pathinfo($mediaObject->get_raw_original_path(), PATHINFO_DIRNAME);
$pattern = "{$filePath}/{$fileName}-*x*-crop-*-*.{$fileExtension}";
$responsivePicsFiles = glob($pattern);
foreach ($responsivePicsFiles as $file) {
preg_match('/(\d+x\d+)(?=-crop)/', $file, $matches);
$size = $matches[0];
if ($size) {
$key = $size . '_crop';
if (strpos($file, '@2x') !== false) {
$key .= '@2x';
}
$files[$key] = [
'size' => $size,
'path' => $file,
'width' => (int)explode('x', $size)[0],
'height' => (int)explode('x', $size)[1],
'mime-type' => $mediaObject->get_mime_type(),
'disabled' => false,
];
}
}
return $files;
}, 10, 2);
Schedule optimize images
We need to make sure Responsive Pics has finished generating the images, so we add a 60 second delay
add_action('responsive_pics_request_processed', function ($postId) {
$action = 'imagify_responsive_pics_optimize_image';
$args = ['post_id' => $postId];
if (!as_next_scheduled_action($action, $args)) {
as_schedule_single_action(
time() + 60,
$action,
$args
);
}
}, 10);
Optimize the images
As the image was already optimized, we need to change the status to make sure the optimization process runs
add_action('imagify_responsive_pics_optimize_image', function ($postId) {
// Force Imagify to optimize the image
$originalStatus = get_post_meta($postId, '_imagify_status', true);
update_post_meta($postId, '_imagify_status', 'already_optimized');
$optimized = imagify_get_optimization_process($postId, 'WP')->optimize();
if ($optimized) {
update_post_meta($postId, '_imagify_status', 'success');
} else {
update_post_meta($postId, '_imagify_status', $originalStatus);
}
});
I’m sure this is not the best way to fix my problem, but it works. Could this be an integration that you would consider building in to the plugin itself? If not, could you give me some pointers on how to optimize the process? Can you find any potential problems in this code?