Problem/Motivation
Today we have a website using Crop API and Image Widget Crop. We created an image style with some "crop types" effects, and set it inside our image field.
The result is something like:

The problem is, if I crop something inside 4:3 Crop, save and publish the node, the hash will not be appended on the URL, and this is a important feature for the website because it's using a CDN.
FYI: Check crop_file_url_alter for more details about the hash and it's implementation.
Steps to reproduce
- Install a new instance of drupal 9.
- Require and install crop api module:
- Require and install image_widget_crop module:
- Create at least two new crop types
- Add a new image style with the crops effects
- If you're using a new drupal instance, you probably have the Article content type.
- Now you need to change the manage display of the content type.
- Create a new content with an image, you'll have to choose between two crop types, if you choose the first one it will not work as expected, just the last crop type will work as expect and append the hash to the URL.
composer require 'drupal/crop:^2.1'
drush en crop
composer require 'drupal/image_widget_crop:^2.3'
drush en image_widget_crop
Go to /admin/config/media/crop and click on Add crop type
Go to /admin/config/media/image-styles/add and a "test image style".
On the next screen, select Manual Crop and add the crops created on the step 4.
So go to the content type form display /admin/structure/types/manage/article/form-display and change the image field type to use ImageWidget crop.
Go to /admin/structure/types/manage/article/display and change the Image field to use the new image style created on step 5.
Proposed resolution
Currently the code have the function getEffectsFromImageStyleId which is responsable for retrieving all the effects from the image style, the main problem is, the code is expecting just one plugin of crop_crop and it's always overriding the array. If you have more than one crop type on the image style, just the last crop will be added to the $effects variable.
The proposed solution here is to create a multi dimension array containing all the crop_crop effects, this way getCropFromImageStyleId is able to find the correct crop and the hash will be attached.
Remaining tasks
Write a patch- Review
API changes
The \Drupal\crop\Entity\Crop::$effectsByImageStyle will have an array of effects.
| Comment | File | Size | Author |
|---|---|---|---|
| #18 | 3259571-IWC.png | 75.9 KB | drdam |
| #18 | 3259571-imageStyles.png | 27.76 KB | drdam |
| #16 | 3259571-5.patch | 2.32 KB | pablorigueto |
| #4 | cat_image_field.png | 427.44 KB | murilohp |
| #2 | 3259571-2.patch | 2.29 KB | murilohp |
Issue fork crop-3259571
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
murilohp commentedHere's a patch to fix this issue.
Comment #3
murilohp commentedComment #4
murilohp commentedComment #5
murilohp commentedComment #6
murilohp commentedComment #7
murilohp commentedComment #8
murilohp commentedComment #9
murilohp commentedComment #10
drdam commentedPatch work fine.
Comment #11
phenaproximaThis is going to need automated test coverage.
Comment #12
murilohp commentedHey @phenaproxima, thanks for reviewing I'm trying to create a test here, but I'm having some problems.
Could you help me here?
Comment #14
sickness29 commentedHi @murilohp
image widget crop does not allow to add multiple crop types per image style and it does not make sense.
Steps to reproduce is not accurate as you need to hack module code to make 5th point work
Hi @phenaproxima
please check my comment and move issue status to fixed if you agree. Thanks
Comment #15
drdam commented@sickness29 :
In fact, it's a limitation of the Crop Entity it self.
I actually have a real use case for this type (particularly when you want to render several versions of the image via responsive).
- You can define 2 distinct image styles: "16-9-large" and "16-9-thumbnail" (both using the same "16-9" CROP-TYPE). The difference is in the dimensions displayed (one 1k px wide, the other x00 px wide).
- You can render the image in the 2 styles separately (using the image formatter or using responsives images).
- For ALL the other styles, you can choose an area of interest different to that of 16-9 CROP-TYPE (That's main adventage in frontof focal-point).
- But if your 2 images use the same type of CROP, you can no longer have 2 different aera of interest (one for each style).
The "classic method" for handling this case consists of creating a CROP-TYPE for each variant of the "same CROP-TYPE" (on for the "16-9-large" and another for "16-9-thumbnail"), and finally have a CROP-TYPE for each image style that uses a CROP.
What is the point of distinguishing the CROP-TYPE from the image style if the global solution are to have a 1-1 relation ?
Comment #16
pablorigueto commentedAt the line 184 I just put an isset to validate if the key type is there
if (isset($effect['type']) && $crop = self::findCrop($uri, $effect['type'])) {
return $crop;
}
Comment #17
nikolay shapovalov commentedPut back to NW, still need tests.
Comment #18
drdam commentedTest : Drupal 11, crop 2.4, ImageWidgetCrop 3.0.0
On a fresh drupal install
- I have create 2 crop type
- On a unique image style, I add 2 effect "manual crop" (one for each crop)
- On the article mange display interface, I choose the image style which use the both crop
- On the article manage form display, I choose "ImageWidget Crop" widget. It only propose the "last crop type" for selection.
see 3259571-IWC.png & 3259571-imageStyles.png
I propose to close this issue, It seems it was corrected in ImageWidgetCrop 3.x
Comment #19
drdam commentedComment #20
drdam commented