This is to restore basic compatibility with the Perfect Images (formerly "WP Retina 2x"), enabling Imagify to process the retina images generated by Perfect Images, and also re-optimizing images when the Perfect Images "Regenerate Thumbnails" feature is used.
NOTE: This PR provides compatibility with the FREE Perfect Images version. Neither the PRO version, nor the new use of Perfect Images Easy IO (EWWW) CDN service are included here.
Context:
Compatibility with WP Retina 2x was removed from Imagify in v 1.9 when the "new" architecture and webp was added. See #490. Since that time, WP Retina 2x became "Perfect Images" and implemented several new features, including a Optimization/CDN partnership with EWWW. On the code side, Perfect Images now uses the WP_Rest API instead of AJAX to initiate functionality.
Coding Considerations:
Previously, we attached hooks to WP Retina 2x AJAX hooks, passing our own nonces, etc. With the new Rest API approach, Perfect Images defines each endpoint with its own validation, per the WP endpoint definitions. We hook into the Perfect Images functionality after requests have already been checked and retina processing is already started.
The 3 PI processes we are interested in are: Retina Generation, Regenerate Thumbnails, and remove retina images.
For both generation processes, Imagify needs to replace the current full-size image (if it has been previously optimized) with the originally uploaded file we have moved to Imagify's backup. This is to insure that the new retinas or regenerated thumbnails will be created from the original image. Then, after the process is completed, we need to put the original uploaded version back into the backup location. This is done in the compatibility class's restore_originally_uploaded_image() and reset_optimized_full_size_image() methods. (NOTE: similar methods are also used for other compatibilities -- the Regenerate Thumbnails plugin compat, for example. These similar methods should ideally be extracted from the various compatibilities and moved into a "BackupHelper" class of some kind.)
For the retina generation, we need to track which sizes PI generates. Then, after all the retina sizes are generated, we need to find them and send them to Imagify background process for optimization. We also need to tell Imagify how to handle the @2x filenames in order to generate the related webp versions, when Imagify's "Generate Webp" option is enabled. Collecting the list of image sizes PI is generating retinas for is in add_retina_size(). Handling retina filenames and queuing them for optimization is done in optimize_retina_sizes(). Finally, after the retina files have been optimized, the optimized image data needs to be stored in the Imagify's data for the attachment/media. That is done in add_retina_sizes_meta() (hooked to the job process for each image as it is optimized from the background).
For the regenerate thumbnails, besides handling the backup and restore of the original, we just need to send the newly regenerated images to Imagify's queue for background processing after PI has done it's thing. That is handled by reoptimize_regenerated_images()
For the deletion of retina images, we need to do 2 things: (1) we need to delete the corresponding webp images that we created during the generation. (PI doesn't know anything about these images, so getting rid of them is on us!) We do that in remove_retina_webp_size(). Then (2) we need to remove the data from Imagify's data storage that we saved about the retina sizes -- and their related webp retina sizes. We do that in remove_imagify_retina_data().
Other "how it works" considerations:
PI has (Pro) functionality to upload/create a "full size" retina image. The thumbnail retina sizes, as opposed to the full-size, are generated, where possible, from re-sizing the full-size image. So ordinarily any thumbnail sizes that have a dimension more than half the full size will not be generated by PI, the adequate resolution to create the thumbnail not being present. By (pro) uploading an original retina full-size, PI is able to generate all the thumbnail sizes from that 2x original. Provided the pro version uses the same hook when generating retinas from the pro @2x original upload, Imagify should still optimize the retina sizes, as well as optimizing the @2x original upload as it would for any other uploaded image. None of this is verified, however, at this time. It would be great if we could reach out to the PI dev to confirm/add Pro compatibility for this and other pro features.
Also, it's probably out of the picture to be compatible with a direct competitor's Optmimzation/CDN service.
Long term, having native retina support in Imagify would be ideal.
This is to restore basic compatibility with the Perfect Images (formerly "WP Retina 2x"), enabling Imagify to process the retina images generated by Perfect Images, and also re-optimizing images when the Perfect Images "Regenerate Thumbnails" feature is used.
NOTE: This PR provides compatibility with the FREE Perfect Images version. Neither the PRO version, nor the new use of Perfect Images Easy IO (EWWW) CDN service are included here.
Context: Compatibility with WP Retina 2x was removed from Imagify in v 1.9 when the "new" architecture and webp was added. See #490. Since that time, WP Retina 2x became "Perfect Images" and implemented several new features, including a Optimization/CDN partnership with EWWW. On the code side, Perfect Images now uses the WP_Rest API instead of AJAX to initiate functionality.
Coding Considerations: Previously, we attached hooks to WP Retina 2x AJAX hooks, passing our own nonces, etc. With the new Rest API approach, Perfect Images defines each endpoint with its own validation, per the WP endpoint definitions. We hook into the Perfect Images functionality after requests have already been checked and retina processing is already started.
The 3 PI processes we are interested in are: Retina Generation, Regenerate Thumbnails, and remove retina images.
For both generation processes, Imagify needs to replace the current full-size image (if it has been previously optimized) with the originally uploaded file we have moved to Imagify's backup. This is to insure that the new retinas or regenerated thumbnails will be created from the original image. Then, after the process is completed, we need to put the original uploaded version back into the backup location. This is done in the compatibility class's
restore_originally_uploaded_image()
andreset_optimized_full_size_image()
methods. (NOTE: similar methods are also used for other compatibilities -- the Regenerate Thumbnails plugin compat, for example. These similar methods should ideally be extracted from the various compatibilities and moved into a "BackupHelper" class of some kind.)For the retina generation, we need to track which sizes PI generates. Then, after all the retina sizes are generated, we need to find them and send them to Imagify background process for optimization. We also need to tell Imagify how to handle the @2x filenames in order to generate the related webp versions, when Imagify's "Generate Webp" option is enabled. Collecting the list of image sizes PI is generating retinas for is in
add_retina_size()
. Handling retina filenames and queuing them for optimization is done inoptimize_retina_sizes()
. Finally, after the retina files have been optimized, the optimized image data needs to be stored in the Imagify's data for the attachment/media. That is done inadd_retina_sizes_meta()
(hooked to the job process for each image as it is optimized from the background).For the regenerate thumbnails, besides handling the backup and restore of the original, we just need to send the newly regenerated images to Imagify's queue for background processing after PI has done it's thing. That is handled by
reoptimize_regenerated_images()
For the deletion of retina images, we need to do 2 things: (1) we need to delete the corresponding webp images that we created during the generation. (PI doesn't know anything about these images, so getting rid of them is on us!) We do that in
remove_retina_webp_size()
. Then (2) we need to remove the data from Imagify's data storage that we saved about the retina sizes -- and their related webp retina sizes. We do that inremove_imagify_retina_data()
.Other "how it works" considerations: PI has (Pro) functionality to upload/create a "full size" retina image. The thumbnail retina sizes, as opposed to the full-size, are generated, where possible, from re-sizing the full-size image. So ordinarily any thumbnail sizes that have a dimension more than half the full size will not be generated by PI, the adequate resolution to create the thumbnail not being present. By (pro) uploading an original retina full-size, PI is able to generate all the thumbnail sizes from that 2x original. Provided the pro version uses the same hook when generating retinas from the pro @2x original upload, Imagify should still optimize the retina sizes, as well as optimizing the @2x original upload as it would for any other uploaded image. None of this is verified, however, at this time. It would be great if we could reach out to the PI dev to confirm/add Pro compatibility for this and other pro features.
Also, it's probably out of the picture to be compatible with a direct competitor's Optmimzation/CDN service.
Long term, having native retina support in Imagify would be ideal.