-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restore Retina Support (via WP Retina 2x, aka Perfect Images, plugin compat) #656
Open
iCaspar
wants to merge
21
commits into
develop
Choose a base branch
from
enhancement/490-wp-retina-support
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is just grabbing the WPR2X code that was deleted. It's no longer wired into our stuff, so it won't do anything yet.
PHPCS - update minimum PHP version to 7.0 Rename wp-retina-2x classes to PerfectImages and add namespace Add PerfectImages namespace to composer PSR4 Use new class names in 3rd-party PerfectImages loader file Add PerfectImages fileloader to 3rd-party required files Stop using deprecated user_can() check - use WP context user check instead Update asset script localization to use updated enqueue
The 3 assets here were included by the previous compatibility. (Not sure yet if we will still need them, but adding them back because they are still trying to be loaded on library page -- until we can sort it out.)
The WP min version is set in the plugin.php to 5.3 -- phpcs should match.
Add first a new property `$retina_sizes[]` to store some size info when Perfect Images generates a new retina file. Comment out (for now) the old ajax hooks, as Perfect Image no longer uses ajax. Add 3 methods: 1. `add_retina_sizes(int $media_id, string $retina_file, string $size_name): void` hooked to Perfect Images `wr2x_retina_file_added `, will store the media ID, retina filepath, and size name in our new `$retina_sizes` property whenever Perfect Images generates a new retina file. 2. `optimize_retina_sizes(int $media_id): void` hooked to Perfect Images `wr2x_generate_retina`, will find all the retina sizes added at the end of a Perfect Images retina generation process for a media ID (as stored in our class property) and start a new Imagify Optimization process for the newly generated retina files. 3. `add_retina_sizes_meta(array $sizes): array` hooked to Imagify's `imagify_media_files` will filter the imagify Media size meta to include the retina sizes, and flag the new sizes as being allowed to optimize.
We add 4 methods here, 2 public, and 2 private helpers: The 2 public methods are both hooked on Perfect Images `wr2x_retina_file_removed` action. 1. `remove_retina_webp_size(int $media_id, string $retina_file ): void` will check for any webp versions of the retina file that was deleted and remove it if it exists. Note we run this even if Imagify's webp option is not currently enabled, because it may have been enabled at the time the retina was generated, and disabled since. This uses the private helper method: 2. `get_retina_webp_filepath(string $attachment_file, string $retina_file): string`. This method handles the subtask of getting the correct webp file path based on the attachment's original filepath and the retina image's filename. 3. `remove_imagify_retina_data(int $media_id, string $retina_file): void` will purge optimization data imagify uses to track the status of retina images it has optimized. Two entries have to be checked and removed for each retina image size that's been deleted: the optimization data generated when we optimized the @2x image Perfect Images created, and the @2x@imagify-webp data for the webp version (if any) that Imagify created in connection with that retina size. This uses the private helper method: 4. `get_retina_imagify_data_size_names(array $sizes, string $origina_size_name): array`. This method compares the sizes information (formatted per `wp_get_attachment_metadata()` to the original filename of an attachment that included a retina image size, and gives us an array of all the related size names that might be present in Imagify's optimization data for the attachment.
Adds a method to restore a full-size image from the backed up original. Adds a method to replace back the previously optimized full-size image after image regeneration. Adds a method to send regenerated images to the queue for re-optimization. We also hook the restore/replace before and after the generation of retina sizes to insure that the original is being used to generate the retinas as well.
These were added back in on 4ffeb21 just in case. It turns out we don't need them any more.
All Perfect Images functionality is handled in the PerfectImages class now. The PerfectImagesCore is dead code.
Also, cleans up some phpcs spacing and comment formatting.
remyperona
reviewed
Feb 7, 2022
We're not going to use the related data in this case. Just get the keys and eliminate the unused variable inside foreach.
The cyclomatic complexity (and readability) of `restore_originally_uploaded_image()` was 10. All of that is due to checking the various conditions before doing the restore. This extracts all the checking to a helper method.
Refactors the process for getting the needed webp sizes for optimization to it's own method.
For new uploads, we're going optimize everything after all the other things run their stuff. In this case we don't want to start a proces for this media now -- doing so will "Lock" the media when the full process tries to run in a few moments, and while retinas will be processed nothing else will be included!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.