#248 | interdiff-247-248.txt | 503 bytes | Rassoni |
#248 | 2825812-248.patch | 13.87 KB | Rassoni |
|
#247 | interdiff-245-247.txt | 961 bytes | Rassoni |
#247 | 2825812-247.patch | 13.84 KB | Rassoni |
|
#245 | interdiff_240-245.txt | 2.52 KB | ravi.shankar |
#245 | 2825812-245.patch | 13.54 KB | ravi.shankar |
|
#240 | interdiff_239-240.txt | 1.34 KB | vsujeetkumar |
#240 | 2825812-240.patch | 13.48 KB | vsujeetkumar |
|
#239 | interdiff_237-239.txt | 4.66 KB | vsujeetkumar |
#239 | 2825812-239.patch | 13.51 KB | vsujeetkumar |
|
#237 | 2825812-237.patch | 13.32 KB | vsujeetkumar |
|
#233 | reroll_diff_229-233.txt | 4.85 KB | Vinay15 |
#233 | 2825812-233.patch | 13.32 KB | Vinay15 |
|
#232 | 2825812-232.patch | 13.5 KB | iivanov |
|
#229 | 2825812_229.patch | 13.5 KB | vsujeetkumar |
|
#227 | interdiff-2825812-214-227.txt | 698 bytes | ndobromirov |
#227 | 2825812-227.patch | 14.2 KB | ndobromirov |
|
#224 | interdiff-212-224.txt | 698 bytes | ndobromirov |
#224 | 2825812-224.patch | 14.18 KB | ndobromirov |
|
#214 | 2825812-214.patch | 14.16 KB | vtcore |
|
#212 | 2825812-212.patch | 14.21 KB | miiimooo |
|
#205 | 2825812-205.patch | 14.28 KB | jofitz |
|
#205 | interdiff-2825812-201-205.txt | 6.81 KB | jofitz |
#201 | 2825812-201.patch | 6.93 KB | e0ipso |
|
#201 | 2825812--interdiff--199-201.txt | 1.45 KB | e0ipso |
#199 | 2825812-199.patch | 13.99 KB | Wim Leers |
|
#199 | interdiff.txt | 1.01 KB | Wim Leers |
#197 | 2825812-197.patch | 13.11 KB | Wim Leers |
|
#197 | interdiff.txt | 4.1 KB | Wim Leers |
#195 | 2825812-195.patch | 11.84 KB | Wim Leers |
|
#195 | interdiff.txt | 3 KB | Wim Leers |
#194 | interdiff-187-194.txt | 1.19 KB | Wim Leers |
#194 | 2825812-194.patch | 10.41 KB | Wim Leers |
|
#191 | interdiff-2825812-180-191.txt | 622 bytes | BR0kEN |
#191 | 2825812-191.patch | 14.41 KB | BR0kEN |
|
#187 | 2825812-187.patch | 10.35 KB | Wim Leers |
|
#187 | interdiff.txt | 1.51 KB | Wim Leers |
#186 | 2825812-186.patch | 10.22 KB | Wim Leers |
|
#186 | interdiff.txt | 1.38 KB | Wim Leers |
#182 | 2825812-182.patch | 8.96 KB | Wim Leers |
|
#182 | interdiff.txt | 2.52 KB | Wim Leers |
#181 | 2825812-181.patch | 8.97 KB | Wim Leers |
|
#181 | interdiff-156-181.txt | 5.82 KB | Wim Leers |
#180 | interdiff-2825812-177-180.txt | 1.51 KB | BR0kEN |
#180 | interdiff-2825812-156-180.txt | 15.87 KB | BR0kEN |
#180 | 2825812-180.patch | 14.36 KB | BR0kEN |
|
#177 | interdiff-2825812-176-177.txt | 1017 bytes | BR0kEN |
#177 | interdiff-2825812-156-177.txt | 14.35 KB | BR0kEN |
#177 | 2825812-177.patch | 14.45 KB | BR0kEN |
|
#176 | interdiff-2825812-173-176.txt | 306 bytes | BR0kEN |
#176 | interdiff-2825812-156-176.txt | 14.35 KB | BR0kEN |
#176 | 2825812-176.patch | 14.45 KB | BR0kEN |
|
#173 | interdiff-2825812-172-173.txt | 1.68 KB | BR0kEN |
#173 | interdiff-2825812-156-173.txt | 14.33 KB | BR0kEN |
#173 | 2825812-173.patch | 14.45 KB | BR0kEN |
|
#172 | interdiff-2825812-170-172.txt | 6.03 KB | BR0kEN |
#172 | interdiff-2825812-156-172.txt | 13.71 KB | BR0kEN |
#172 | 2825812-172.patch | 14.5 KB | BR0kEN |
|
#170 | interdiff-2825812-156-170.txt | 11.36 KB | BR0kEN |
#170 | 2825812-170.patch | 13.59 KB | BR0kEN |
|
#156 | 2825812-156.patch | 12.16 KB | alexpott |
|
#156 | 146-156-interdiff.txt | 13.52 KB | alexpott |
#146 | 2825812-146.patch | 13.21 KB | alexpott |
|
#146 | 144-146-interdiff.txt | 2.36 KB | alexpott |
#144 | 2825812-144.patch | 12.87 KB | alexpott |
|
#144 | 141-144-interdiff.txt | 13.19 KB | alexpott |
#141 | 2825812-141.patch | 20.88 KB | alexpott |
|
#141 | 140-141-interdiff.txt | 9.52 KB | alexpott |
#140 | 2825812-140.patch | 14.58 KB | alexpott |
|
#140 | 139-140-interdiff.txt | 5.48 KB | alexpott |
#139 | 2825812-139.patch | 13.72 KB | justafish |
|
#137 | 2825812-137.patch | 14.96 KB | justafish |
|
#136 | interdiff.txt | 3.28 KB | justafish |
#136 | 2825812-135.patch | 13.59 KB | justafish |
|
#127 | 2825812-properly_use_typed_data_but_i_cant_figure_it_out-do-not-test.patch | 3.67 KB | Wim Leers |
|
#124 | 2825812-124.patch | 11.89 KB | Wim Leers |
|
#124 | interdiff.txt | 2.16 KB | Wim Leers |
#120 | interdiff.txt | 862 bytes | Wim Leers |
#119 | 2825812-119.patch | 11.79 KB | Wim Leers |
|
#119 | interdiff.txt | 1.12 KB | Wim Leers |
#116 | 2825812-115.patch | 11.79 KB | Wim Leers |
|
#116 | interdiff.txt | 2.65 KB | Wim Leers |
#114 | 2825812-114.patch | 11.79 KB | Wim Leers |
|
#114 | interdiff.txt | 5.51 KB | Wim Leers |
#110 | 2825812-110.patch | 8.63 KB | Wim Leers |
|
#110 | interdiff.txt | 2.55 KB | Wim Leers |
#107 | 2825812-107.patch | 6.15 KB | Wim Leers |
|
#107 | Screen Shot 2017-11-09 at 12.01.17.png | 97.55 KB | Wim Leers |
#107 | Screen Shot 2017-11-09 at 11.57.30.png | 80.94 KB | Wim Leers |
#101 | 2825812-101.patch | 20.16 KB | tedbow |
|
#101 | interdiff-98-101.txt | 5.75 KB | tedbow |
#98 | 2825812-98.patch | 19.15 KB | tedbow |
|
#98 | interdiff-91-98.txt | 1.71 KB | tedbow |
#91 | 2825812-91.patch | 19.08 KB | Wim Leers |
|
#91 | interdiff.txt | 5.1 KB | Wim Leers |
#90 | 2825812-90.patch | 18.1 KB | tedbow |
|
#90 | interdiff-87-90.txt | 581 bytes | tedbow |
#87 | 2825812-87.patch | 17.53 KB | tedbow |
|
#87 | interdiff-83-87.txt | 669 bytes | tedbow |
#83 | interdiff-72-82.txt | 526 bytes | jofitz |
#83 | 2825812-82.patch | 16.88 KB | jofitz |
|
#72 | interdiff-70-72.txt | 4.3 KB | tedbow |
#72 | 2825812-72.patch | 16.92 KB | tedbow |
|
#70 | interdiff-2825812-67-70.txt | 1.91 KB | himanshu-dixit |
#70 | 2825812-70.patch | 16.97 KB | himanshu-dixit |
|
#67 | 2825812-67.patch | 17.01 KB | tedbow |
|
#67 | interdiff.txt | 9.68 KB | tedbow |
#62 | 2825812-62.patch | 17.14 KB | tedbow |
|
#62 | interdiff-60-62.txt | 5.01 KB | tedbow |
#60 | 2825812-60.patch | 16.42 KB | tedbow |
|
#60 | interdiff-57-60.txt | 1.91 KB | tedbow |
#57 | 2825812-57.patch | 16.36 KB | martin107 |
|
#57 | interdiff-2825812-52-57.txt | 7.05 KB | martin107 |
#52 | interdiff-2825812-49-52.txt | 1.35 KB | martin107 |
#52 | 2825812-52.patch | 16.71 KB | martin107 |
|
#49 | interdiff-2825812-45-49.txt | 11.04 KB | martin107 |
#49 | 2825812-49.patch | 16.68 KB | martin107 |
|
#45 | interdiff-2825812-41-45.txt | 11.31 KB | martin107 |
#45 | 2825812-45.patch | 16.13 KB | martin107 |
|
#41 | 2825812-41.patch | 16.99 KB | tedbow |
|
#41 | interdiff-38-41.txt | 6.93 KB | tedbow |
#38 | interdiff-34-38.txt | 3.43 KB | tedbow |
#38 | 2825812-38.patch | 16.88 KB | tedbow |
|
#34 | interdiff-30-34.txt | 11.49 KB | tedbow |
#34 | 2825812-34.patch | 16.72 KB | tedbow |
|
#30 | interdiff-27-30.txt | 7.83 KB | tedbow |
#30 | 2825812-30.patch | 14.29 KB | tedbow |
|
#27 | 2825812-27.patch | 10.21 KB | tedbow |
|
#27 | 2825812-27-plus-2827218-47.patch | 41.74 KB | tedbow |
|
#27 | interdiff-26-27.txt | 734 bytes | tedbow |
#26 | 2825812-26.patch | 10.21 KB | tedbow |
|
#26 | interdiff-19-26.txt | 1.24 KB | tedbow |
#26 | 2825812-19-plus-2827218-47.patch | 41.66 KB | tedbow |
|
#19 | interdiff-11-19.txt | 3.13 KB | tedbow |
#19 | 2825812-19.patch | 10.14 KB | tedbow |
|
#11 | interdiff-9-11.txt | 4.3 KB | tedbow |
#11 | 2825812-11.patch | 8.89 KB | tedbow |
|
#9 | interdiff-6-9.txt | 7.42 KB | tedbow |
#9 | 2825812-9.patch | 8.79 KB | tedbow |
|
#6 | interdiff-4-6.txt | 1.84 KB | tedbow |
#6 | 2825812-6.patch | 8.33 KB | tedbow |
|
#4 | 2825812-3-image_styles_normalization.patch | 8.23 KB | tedbow |
|
Comments
Comment #2
Wim LeersA follow-up for this: #2825814: [PP-1] Allow URL query argument to limit the image style URLs returned by ImageItemNormalizer.
Comment #3
tedbowWorking on this.
Comment #4
tedbowok here is patch.
It has a test.
This was similar to #2626924: Include processed text in normalizations: "text" field type's "processed" computed property should be non-internal and carry cacheability metadata
\Drupal\Core\Cache\CacheDependencyBubbleTrait was copied directly from there
Couple questions I had:
#2517030: Add a URL formatter for the image field provides the image styles URLs using relative urls. I used relative urls here. But EntityReferenceFieldItemNormalizer which this extends provides the absolute URL. so for images field items you get both like this:
Should we change this to use absolute URLs or provide and extra 'image_url' or should EntityReferenceFieldItemNormalizer provide relative?
I added the cache dependencies for each image styles because if you change the machine name or deleted an image style the urls would update. but also if you added another image style the array would need to be updated. Not sure how to handle that.
Comment #5
dawehnerThis looks pretty good!
I'm wondering whether we should always provide the 'image_styles' key, so client code does not have to explicitly check it.
I think using an absolute URL is the right thing to do, because it makes it easier to use in a custom client. In case it would be a relative URL, the client code would need to know the base URL, do the appending of strings etc.
Comment #6
tedbow@dawehner thanks for the review!
1,2 makes sense and fixed
I also change the priority of the new service because it has to be lower than serializer.normalizer.entity_reference_item.hal or it will break Image fields for HAL.
Which brings up should we be doing the same thing in the HAL module? If so should that be a follow up?
If we don't do it in for HAL should still in follow up create a test in HAL for any field type that extends EntityReference that current normalizer works. Because this normalizer with the higher priority broke Image references in HAL but there were no tests. The same could happen with \Drupal\file\Plugin\Field\FieldType\FileItem
Comment #7
tedbowUnassigning
Comment #8
Wim Leers#4:
Yay!
That's not a file URL. All file URLs must be root-relative since #1494670: References to CSS, JS, and similar files should be root-relative URLs: avoids mixed content warnings & fewer bytes to send.
#5.2:
I humbly disagree. Absolute URLs are fine for fully decoupled apps where the end user-facing app is a web app that lives on a different domain or is a native app. But in all other cases, the root-relative URL is much more useful. It's much easier to do
domain + string_the_rest_api_sent_me
than it is to parse a URL into the separate components and then reassemble correctly again. And for progressively decoupled use cases, you'll want relative URLs anyway.#6:
IMO it should be done here. Fix the normalization across all supported formats in one go. It's very closely related anyway. And probably you can even share some of the test coverage code. Which also benefits from updating the default normalization and HAL's at the same time.
The equivalent in #2626924: Include processed text in normalizations: "text" field type's "processed" computed property should be non-internal and carry cacheability metadata was updated significantly. Let's pull in the latest iteration from there.
s/ImageFieldItem/ImageItem/
Must use interface.
Why not use
File::loadMultiple()
?Must use interface.
Why not use
ImageStyle::loadMultiple()
?Interface.
Use
Cache::mergeTags()
.$image_style_ids
Comment #9
tedbow#5.2 added back file_url_transform_relative
#6 ok. will do hal in this issue(not in this patch)
1. pulled in other version with new name though had to add back \Drupal\Core\Cache\ConditionalCacheabilityMetadataBubblingTrait::renderer
2. fixed - also changed test name to match
3. fixed
4. you mean File::load() not File::loadMultiple() right? if so fixed
5-9 fixed
Comment #10
Wim LeersThis method was removed in the other issue.
Other than that, this looks great. All the remains, is HAL support.
Comment #11
tedbow#9.2 I didn't actually update the test name. Fixed.
re #10
Fixed
Also fix couple small nits in Test.
Comment #12
tedbowHere are the nits I was referring to in #11
Didn't declare field
This was never used. c/p error
Comment #13
Wim LeersCool. :) So, now zero nits remain, we just need to update the HAL normalization to do the same!
Comment #14
garphy CreditAttribution: garphy at ICI LA LUNE commentedJust a thought, we used to implement this in D7 (as an extension of the Service Entity module.
We started exactly like this patch, outputting an associative array of URL indexed by style name but we quickly concluded that it is in most case not enough as there is other useful pieces of information alongside the style URL itself, such as the resulting derivative dimensions.
So instead of just a string literal, we output an associative array with the "URL", "width" and "height" keys.
I would suggest switching to that kind of output.
Comment #15
Wim LeersGreat feedback, thanks @garphy!
Comment #16
tedbowre #14 I think this could open up can of worms.
We can't determine the width or height by just looking at the image style. For instance if you scale an image but only specify height width will be different for each image.
Also if you don't "Allow Upscaling" then you can't tell either because the image could be smaller and then not scaled. Also what about all the contrib image effects where we don't know how to determine the dimensions?
If we had to look at each individual processed image to see what the dimensions are what about images where a particular(or all) image style derivatives have not been made yet? are they still made when first requested? Do we force them to be created so we can provide dimensions?
Comment #17
garphy CreditAttribution: garphy at ICI LA LUNE commentedI've not checked if it's still the case with D8 API (Sorry!) but with D7's Style API, each style operation provide a callback used to compute the final dimension of the image without actually execute the operations, thus allowing to compute the resulting dimensions without creating all possible derivatives.
Of course there will still be edge cases were this precalculation cannot be made, but we still can provide it for the ~90% use cases.
When an (integrated) drupal theme outputs a tag, it use this API to know the dimensions of the image (populating the width/height attributes) without actually generate the image. It'll be generated when the browser will actually request it.
Comment #18
tedbowNo problem at all.
Interesting I will look to see if I can find this in D8.
If it exists still I would be interested if anyone knows what kind of overhead that might involve. Thinking of entities with lots image fields or multiple value image fields with lots of images on 1 entity.
UPDATE:
Ok this is probably it \Drupal\image\ImageStyleInterface::transformDimensions
The docs don't explicitly say the derivative is not created but that would make sense.
So I guess if the overhead is not a concern this seems doable.
Comment #19
tedbowOk here is patch does @garphy suggestion in #14 and adds the height and width as well as url.
It also updates the tests. In the test I had to set all the effect to "upscale" or the dimensions would be the same for all styles.
As per @Wim Leers' comment on #13 this still needs the hal work done.
Comment #20
tedbowRe my worry
I was imagining some image processing going on which is not done. At least for scaling this is done in \Drupal\Component\Utility\Image::scaleDimensions which is just calculations.
Comment #21
dawehnerNote: #2831274: Bring Media entity module to core as Media module will revert this basically.
Comment #22
dawehnerOpened up a follow up in #2835767: Media + REST: comprehensive test coverage for Media + MediaType entity types
Comment #23
garphy CreditAttribution: garphy at ICI LA LUNE commented@dawhener: Why would it revert this ? In my understanding, Media brings in a new entity type alongside File entities, not replacing it.
Comment #24
Wim LeersI think having width + height makes sense also from a decoupled POV: if you want to use those image URLs to generate
<img src="URL" width="WIDTH" height="HEIGHT">
, then you need width and height.<img src="URL">
(without width+height) is a bad practice. It causes poor performance, because it requires the browser to reflow layout, since it cannot know the image dimensions.So +1 from that POV.
Comment #25
damiankloip CreditAttribution: damiankloip at Acquia commentedAlso totally +1 on having the height and width.
I think this is still ok after https://www.drupal.org/node/2827218 ?
nit: new array syntax [] ?
Not sure if it matters too much in the grand scheme of things, but we could get the entity storage from the entity type manager and use load() from that. Same goes for both here.
Do you think there is any value to having both absolute and relative? definitely relative is the more useful/flexible one.
Comment #26
tedbow1. in #2827218: Denormalization on field items is never called: add FieldNormalizer + FieldItemNormalizer with denormalize() methods serialization.normalizer.field_item priority is set to 6 so 7 for image.normalizer.image_item would work(needs to be higher).
but just to be sure including a patch that combines 2825812-19.patch and 2827218-47.patch
2. fixed
3. With on going expansion of the universe what really matters in grand scheme of things?? but Fixed.
4. I would be in favor of just providing relative. clients should be able to easily create absolute if needed.
Comment #27
tedbowThe combination patch 2825812-19-plus-2827218-47.patch actually failed. Not sure why it is green.
I forgot that image.normalizer.image_item needs be higher than serializer.normalizer.entity_reference_field_item because an image reference is a special kind of entity reference.
Comment #30
tedbowOk this patch provides a new \Drupal\image\Normalizer\ImageItemHalNormalizer
and \Drupal\image\Normalizer\ImageItemNormalizerTrait
The trait is used because the adding the Image style information is mostly the same between hal and default.
I haven't had time to create the new test yet but just thought I should post it before I finish for the day. Also will prove it doesn't break any of the existing tests(hopefully, worked locally).
Comment #32
tedbowretesting.
Comment #34
tedbowOk I am not sure what the CI error was in #30
This patch adds the testing for the Hal normalizer.
Comment #36
tedbowTest passed again
Comment #37
dawehnerJust an idea for the future and maybe for new normalizes, ... what about watching both service definitions get the priority and then choose a priority of
(A+B)/2
I'm wondering whether we should check whether this image actually exists.
Note: This could be moved outside of the loop
IMHO we should not provide short variable names
Comment #38
tedbow@dawehner thanks for the review.
1. It seems like having hard-coded numbers while not perfect at least allows custom and contrib normalizers to know where they are in relation to core normalizers. Though custom and contrib could also follow the dynamic method you suggested there are probably normalizers using hard-coded values and developers who are use to this.
2. Fixed
3. This actually has to be inside the loop because $dimensions is passed by reference to \Drupal\image\ImageStyleInterface::transformDimensions. Then the "Implementations have to store the resulting width and height, in pixels." So it is changed in with each iteration of the loop and needs to be reset the original image dimensions.
4. Good suggestion! changed $id to $image_style_id and $img_info to $image_style_dimensions
Comment #39
dawehnerThe world is a sad place ... like I would have expected this method to return the transformed dimensions. Of course this is not caused by this particular patch.
Nitpick, when there is time between now and the commit: We could use
assertContains
here.Comment #40
Wim LeersI think this looks great. I have a bunch of nitpicks, and some naming concerns that are easily fixed.
There is one bigger concern: BC. Can we really just enable this? This would change the responses, just like #2751325: All serialized values are strings, should be integers/booleans when appropriate, only much more so! That one has a BC layer, this one does not. Yet that one is getting BC concerns raised. So I'm pretty sure they'll be raised here too.
Nit s/which 10/which is 10/
s/ImageItem normalizer/ImageItem HAL normalizer/
ImageItemHalNormalizer
s/images/image/
s/ItemItem/ImageItem/
I think:
? It currently is pretty strange.$data
is super generic.I think this would be clearer:
ItemItemNormalizerBase
?ImageItemNormalizerBase
!Needs a touch of language improvement :)
s/$data/$normalization/
Comment #41
tedbow#39.2 fixed
#40
1-4 fixed
5. Changed from "The field image item." to "The image field item."
IMHO "The image field." doesn't specify it is an individual item in a field list.
6,7 fixed
8. changed to "Set upscale to TRUE in all image style scale effects."
9. fixed
RE
I think #2751325: All serialized values are strings, should be integers/booleans when appropriate is more disruptive because it changes the data types of existing parts of the response. This just adds new elements on the field item level which is more like #2060677: Add target_type, target_uuid to serialized output of entity reference fields in non-HAL formats. There was no BC layer for that. The client would have to be validating that no unknown keys on the field item level in both case to break.
Comment #43
Wim Leers"to the current render context, if any"
Why can't we put this in
image.services.yml
?Let's document the reason.
This is probably THE most essential part of the patch. What this means is that image items are normalized just like before… but we just also add image style information to the normalization, if the field is not empty.
But I think the logic can be much simpler:
Bonus points for renaming
$object
to$field_item
and adding a type hint comment.Why not
File::load()
andImageStyle::loadMultiple()
?Easier to read, and we would no longer need to have the entity type manager injected.
The name currently doesn't make it clear that this is a test class.
This should be renamed to
ImageItemNormalizerTestBase
.Extraneous blank line.
$this->serializer = $this->container->get('serializer');
s/array()/[]/
Let's rename
$data
to either$normalization
or$normalized_entity
.s/expected/expected bubbled/
s/The/The expected bubbled/
Comment #44
martin107 CreditAttribution: martin107 as a volunteer commentedI've been following along for a while ...all of #43 looks reasonable
it is high time I contributed a little
Comment #45
martin107 CreditAttribution: martin107 as a volunteer commented1) Fixed.
2) Fixed by adding a dependencies comment to ImageServiceProvider
3-11) Fixed
In addition I fixed :-
ImageItemHalNormalizer was injected with a deprecated \Drupal\rest\LinkManager\LinkManagerInterface type object.
which feed it onto the parent EntityReferenceItemNormalizer which was actually expecting a \Drupal\serialization\LinkManager\LinkManagerInterface type object.
Comment #47
Wim LeersThanks!
2) I don't see that comment?
RE: the additional thing: great find! :) That's very recent, but it's great to have it done correctly here! Well-spotted!
Interdiff review:
Must be typehinted to the interface, not the implementation.
It's done correctly here :)
Patch review:
After I posted #43 yesterday, I was thinking a bit more about this.
These are two new normalizers. But
ImageItem
s were already normalized jsut fine without this patch.What this patch is doing, and what these normalizers are doing is not normalizing
ImageItem
s but decoratingImageItem
normalizations!Think about it: image styles are NOT part of
ImageItem
s in any way: image items are 100% unaware of image styles.It's just that we are deciding that it makes sense to provide image style information for every image in an image field.
So… I'm now thinking that it'd be better to name this
ImageItemWithImageStyle(Hal)Normalizer
(andImageItemWithImageStyleNormalizerTrait
), which would fully explain what this is doing.Or something like that. What do you think? tedbow, what do you think?
The
addImageStyles()
method would then also need to be renamed todecorateWithImageStyles()
.The
rest
module no longer needs to be enabled as of #2758897: Move rest module's "link manager" services to serialization module + #45's insight to not use the deprecated REST link manager, but the Serialization link manager :)Also, this does not need to list the system, image etc modules, it inherits that from the base class automatically! This can be reduced to just
['hal']
now :)The format whose normalization to test.
Comment #48
Wim LeersThis is now also blocking #2748617: EntityResource only sets entity cache tags on response; cache tags for entity reference fields missing because this adds
ConditionalCacheabilityMetadataBubblingTrait
, which that issue also needs.Comment #49
martin107 CreditAttribution: martin107 as a volunteer commentedInterdiff Review:
Fixed. [Me stares at the ground mumbling] I hear that happens SOMETIMES when you create a patch before you press save in your editor. #ThatIsMyLineAndIAmStickingToIt.
I have appended the word Interface t the annonation.
Thanks for keeping me honest!
Patch Review
1) 2) Fixed
In the last iteration the critical method was named addImageStyles() [Plural] so I pluralized the name changes
An example of the pattern I went with was
ImageItemWithStylesHalNormalizerTest
3) Fixed.
A Small nit I noticed while work on this
ImageItemNormalizerTrait::addImageStyles()
There was a disconnect between the annotated @parm name "normalization" and the method param name ... I went with $normalization.
On Sunday I will try and workout whatever screw up I introduced that broken testing..
Comment #51
tedbowNeeds a "\"
Re @Wim Leers' comment #47
The problem with ImageItemWithImageStyle(Hal)Normalizer is that this what we are doing with the normalizer now. But since we can only have 1 normalizer for ImageItem I think we should keep it generic. Because what happens when we find there is something else we need to do in ImageItem normalization(or denormalization) that does have to do with 1 of ImageItem properties? We have to add it to this class and we can't rename it. Probably makes sense to re-name the trait but I think it makes sense for normalizers to be name after the thing that they are normalizing.
Comment #52
martin107 CreditAttribution: martin107 as a volunteer commented#49
Fixed.
#51
Thanks fixed.
Hmm still thinking up a better name....for ImageItemWithImageStyle(Hal)Normalizer
Comment #54
Wim Leers#51: great point! So perhaps best to stick with
ImageItemNormalizer
, but make it very explicit in the documentation that this is decorating the default normalization with image style metadata.Comment #55
Wim LeersJust discussed this with @tedbow and the Serialization module maintainer, @damiankloip. He agrees with Ted. The name of the class should always match the
$supportedInterfaceOrClass
property. So, it should beImageItemNormalizer
, and we can make it clear in the documentation that it's just decorating the default normalization.Comment #56
garphy CreditAttribution: garphy at ICI LA LUNE commentedQuick feedback:
I was hoping that advances made with this patch would also be useful when using json:api.
But unfortunately, as style URLs are added at the field item level, it is merely "invisible" on json:api output which treat entity reference generically.
I think that image styles information (URL, size, ...) would be valuable at the file-entity level when the said entity is an image. As a result we could have this information when querying file entites with rest (entity/file/?_format=json) or when including referenced entities with json:api (api/node//?include=field_image).
Comment #57
martin107 CreditAttribution: martin107 as a volunteer commentedJust limiting the change to a rename.
Comment #58
tedbow@garphy re
The file entity itself doesn't know anything about styles. The only thing that makes image styles available I think is if upload as part of an image field. For a file entity if the file itself is an image file you can't tell if there should be image styles unless you check its usage in a image field. That is you could upload an image in a file field and then the images styles would not be available.
Comment #59
tedbowNit: class description should be 1 line then empty followed longer description if needed.
Need to update class name in comment
Comment #60
tedbowFixed nits I mentioned in #59 and 1 small other 1. All in comments
Comment #61
Wim LeersProvides normalizer services for the "image" field type.
Well this does not explain why we can't put these in
image.services.yml
.Nit: s/$data/$normalization/
Also in the other normalizer class.
Why can't we use
!$field_item->isEmpty()
here, just like we do inImageItemNormalizer
?I started to wonder whether this was actually correct: whether this still worked for multi-valued fields. My manual testing shows it works. And stepping through it with a debugger shows that this indeed makes sense!
This is still missing a
comment.
Point 2 is my main concern. Once that is fixed, this is RTBC.
Comment #62
tedbow1. fixed
2. Expanded the comment to list the reasons which are the classes extend class from the hal and serialization modules, they have no use without these modules and the hal one will throw a ServiceNotFoundException because of a missing argument service.
I also nested the check for the hal module under the check for the serialization module. The hal service requires services from the serialization module. So even if serialization wasn't dependent on serialization this service would be.
3. fixed in both classes.
4. It can.fixed.
5. Yep, makes sense the way it is.
6. Added the comment to both classes. and change parameter name in \Drupal\image\Normalizer\ImageItemHalNormalizer::normalize to $field_item to match the other class.
Comment #63
Wim LeersHurray :)
Comment #64
Wim LeersLet's rename this to
ImageItemNormalizer
. All of the existing normalizers in the HAL module also don't mentionHal
in their classnames!Comment #65
Wim LeersAh, damn, #64 does not make sense, because we have
ImageItemNormalizer
forserialization
(i.e. default normalizer) andImageItemHalNormalizer
forhal
, and both live in the same directory and namespace. That's why #64 is not feasible.Comment #66
Wim LeersThe way the
jsonapi
module does this instead:We could make
\Drupal\rest\EventSubscriber\ResourceResponseSubscriber::renderResponseBody()
work int he same way.Then we wouldn't be bubbling onto "the current global render context" anymore. Which feels a lot less brittle.
And it means this can become a unit test!
Thoughts? @tedbow in particular?
Comment #67
tedbow1. that looks a good idea.
I implemented this. I could remove ConditionalCacheabilityMetadataBubblingTrait.
2. I left as a kernel test for now because wanted to see if would still pass. I had remove the url.site cache context from Hal test but think that is because not serializing in render context anymore.
Will update test to unit if this passes without breaking any rest tests.
Comment #68
Wim LeersThis can be simply
Because
ImageStyle
implementsEntityInterface
which implementsCacheableDependencyInterface
.s/cacheable_metadata/cacheability/
Comment #69
Wim LeersComment #70
himanshu-dixit CreditAttribution: himanshu-dixit as a volunteer commentedFixed #68 in this new patch. I am not sure about the second point, @WimLeers can you see if it is correct ?
Comment #72
tedbow@himanshu-dixit thanks for fixing #68.1
I think for #68.2 @Wim Leers was just saying to swap out 'cacheability' for 'cacheable_metadata' in the array we use for the context array.
You should gotten some fails in the test b/c you updated the key but it needs to be the same in ImageItemNormalizerTrait, ImageItemNormalizerTestBase and ResourceResponseSubscriber.
I updated this.
There were a bunch of other fails just because #2854830: Move rest/serialization module's "link manager" services to HAL module landed since #67. So we need use the hal.link_manager service instead of the serialization.link_manager service
I just had to do this for another issue so I updated this too.
Comment #73
Wim LeersPerfect!
Comment #75
denutkarsh CreditAttribution: denutkarsh at Google Code-In commentedThat was a unrelated fail. Returning the RTBC Status
Comment #77
Wim LeersDrupal CI had a bad moment.
Comment #79
Wim LeersRetesting. Might be a legitimate fail though. Cache contexts for GET responses have changed, it seems, due to some commit today (EDIT: likely #2853211: EntityResource::post() incorrectly assumes that every entity type has a canonical URL).
Comment #81
Wim LeersComment #82
martin107 CreditAttribution: martin107 as a volunteer commented2825812-72.patch applies for me 8.4.x, I am retesting.
BTW I am on commit df2fd66d5999884504ab1d66f921aa6d0bf73711
here is the git log output
Author: Alex Pott
Date: Mon Mar 27 11:39:13 2017 +0100
Issue #2843756
Comment #83
jofitz CreditAttribution: jofitz at ComputerMinds commentedDoes not require re-roll - patches applies ok.
Removed unused
use
statement.Comment #84
Wim LeersSorry, by
I meant "reroll and need small patch fix", I don't mean "reroll to apply cleanly on latest HEAD".#83 will fail.
Comment #85
tedbow@wim re: #79
I could see that #2853211: EntityResource::post() incorrectly assumes that every entity type has a canonical URL would have changed the cache contexts and \Drupal\entity_test\Entity\EntityTestLabel entity doesn't have a canonical so for that reason the context 'url.site' would not be expected.
But it seems link since \Drupal\hal\LinkManager\LinkManagerBase::getLinkDomain might use
$request->getSchemeAndHttpHost() . $request->getBasePath();
then in this case 'url.site' context should be added in that case. Does that sound right?Comment #86
Wim LeersSigh, you're right, that's simply something that's been forgotten all this time in HAL responses.
EDIT: IMO that's something that's out of scope for this issue though; we need a follow-up for that.
Comment #87
tedbowAll right updating \Drupal\Tests\hal\Functional\EntityResource\EntityTestLabel\EntityTestLabelHalJsonAnonTest::getExpectedCacheContexts to not return 'url.site'. Because 'entity_test_label' entity type doesn't provide a canonical link it currently should expect 'url.site' context.
Comment #88
tedbowCreated follow up issue #2864816: HAL LinkManager doesn't add 'url.site' cache context when needed
Comment #90
tedbow... and in the meantime #2843752: EntityResource: Provide comprehensive test coverage for Item entity
got committed.
Same problem except with \Drupal\aggregator\Entity\Item since it doesn't provide a canonical url.
I am assuming both these issues are because we changed \Drupal\rest\EventSubscriber\ResourceResponseSubscriber::renderResponseBody to not use executeInRenderContext().
Comment #91
Wim LeersI wanted to RTBC but …
Well, isn't that a problem then? That's a BC break!
This is not making any sense. This is popping the render context and adding its cacheability metadata to the response… but we never use the render context anymore in this new code!
I asked for this in #66. It makes normalizers fully unit testable (since you don't need to set up a global render context etc). It makes the code easier to follow, because less magic. @tedbow implemented it in #67.
However, what I didn't notice/realize, is that this suggestion of mine:
… is blatantly false. Doing that implies doing a BC break. Because until now, we explicitly supported this, and for good reason. Let me quote the docs of
\Drupal\rest\EventSubscriber\ResourceResponseSubscriber::renderResponseBody()
:This change makes that statement untrue! Which means this is a BC break!
So, I think we need to revert that change. I think we can and should still do the explicit cacheability metadata bubbling from normalizers by using
$serialization_context['cacheability']
. But we should also still continue to support the old mechanism. Not doing that implies a BC break.So, did that. And turns out @tedbow is right: that allows us to revert the changes in #87 + #90.
Also, this means that the existing documentation is wrong, and needed updating. Changed
to:
because now there is an API to explicitly bubble cacheability metadata!
This also means we'll need a change record for this.
Thoughts? Agreed with this direction?
Comment #92
tedbow@Wim Leers yes I think you change in #92 is correct to not break BC but also make it easier to add cacheability metadata.
Comment #93
Wim LeersI reviewed + RTBC'd @tedbow's
ImageItemNormalizer
code.@tedbow can reviewed + RTBC my changes in #91. I first need to add a CR though.
Comment #94
Wim LeersCR created: https://www.drupal.org/node/2865042.
Comment #95
tedbow#91 and the CR look good!
@wim leers thanks for the full explanation in #91.
Comment #96
alexpottI think we need to call \Drupal\image\ImageStyleInterface::supportsUri() to ensure that the style supports the image. And only then add the image style. See #2652138: Image styles do not play nicely with SVGs
Nicely done.
Comment #97
Wim Leers#96.1: that's a new API added in #2652138: Image styles do not play nicely with SVGs, so we couldn't have possibly done that until now!
But yay, that seems like an easy reroll :)
Comment #98
tedbowre #96.1 added call to \Drupal\image\ImageStyleInterface::supportsUri()
Comment #99
Wim LeersComment #100
alexpott... not going to be popular... but I think we need tests for the
if ($style->supportsUri($uri)) {
We should have a .svg uri in the test I guess
Comment #101
tedbowI guess i won't vote you down on mostpopulardrupalcorecommitter.com today ;)
No problem good thing to test for!!!!
Added a dataprovider that uses existing jpg test case and svg test case.
Comment #102
Wim Leers#100 hahahahah, I was struggling with that — was contemplating asking for it. I wasn't sure. It's definitely better to have it.
Nit: could use
setFileUri()
.I think
$styles_included
is a bit strange, but ok. Can't think of anything better atm.Nit: s/Datatprovider/Data provider/
Comment #103
tedbowI think this method might be overly complicated
See: #2871591: Allow ComplexData in TypedData to specify computed properties that should be exposed in normalization and other contexts
If that seems like good idea we should probably postpone this.
Comment #104
Wim LeersThis has effectively been postponed on that issue for >2 months now.
Comment #106
Wim Leers#2871591: Allow ComplexData in TypedData to specify computed properties that should be exposed in normalization and other contexts is in, #2910211: Allow computed exposed properties in ComplexData to support cacheability. is the last remaining blocker (was split off from #2871591 to make its scope narrower and help it land sooner), and that too is now RTBC!
Comment #107
Wim Leers#2910211: Allow computed exposed properties in ComplexData to support cacheability. also landed, this is now fully unblocked!
I've rerolled #101 entirely in the spirit of #2871591: Allow ComplexData in TypedData to specify computed properties that should be exposed in normalization and other contexts. I got some inspiration on how to add a computed property that contains a list of things from
\Drupal\entity_test\Plugin\Field\ComputedTestFieldItemList
.Rolling this patch took me more than 6 hours of work, because Typed Data is excruciatingly difficult to figure out. Hopefully once there's a bunch of examples, it'll become much simpler for others to do.
The result in the REST module:
And together with #2921257-6: On Drupal 8.5, JSON API should respect Typed Data's new ::isInternal(), and JSON API Extras should use ::setInternal() (to leverage #2871591: Allow ComplexData in TypedData to specify computed properties that should be exposed in normalization and other contexts), it even works automatically in the contrib JSON API module:
Comment #108
Wim LeersComment #110
Wim LeersHah, the
Media
entity has this base field:Which means this patch is automatically adding image styles for the thumbnail. Proving that it works beautifully everywhere where image fields are used!
Interesting fact: only the
?_format=json
tests are failing, the?_format=hal_json
tests are passing, because the "image_styles" computed property simply does not show up forhal_json
. This is becauseImageItem extends FileItem extends EntityReferenceItem
, and the HAL normalizers treat entity reference fields in a special way (and therefore also image fields).I'd say we have to fix that first, but … the HAL normalization intentionally chose to do this. In fact, for this same reason, the
hal_json
-formatted response also doesn't allow you to get thealt
,width
orheight
properties of image fields.image_styles
is merely another in that list.Comment #111
Wim LeersI think this should actually extend
Map
, notItemList
.Comment #113
Wim LeersI think that @e0ipso is implying at #2921257-15: On Drupal 8.5, JSON API should respect Typed Data's new ::isInternal(), and JSON API Extras should use ::setInternal() that
image_styles
is a bad name for this computed property, because it's very Drupal-y.derivatives
would be a better name. That also happens to be the name that is used in the codebase. "Image Styles" is kind of the human-readable name for the same concept.So, how do people feel about that? I personally think that probably makes more sense.
Comment #114
Wim Leers#110 was failing because for some reason, the
width
andheight
are strings for thelarge
andmedium
image styles, but integers for thethumbnail
styles.We can easily fix that: casting them all to integers.
But then the
test coverage fails. Because
\Drupal\image\Plugin\DataType\ComputedImageStyleList::computeImageStyleMetadata()
returns[string, int, int]
, not[StringData, IntegerData, IntegerData]
. Fixing that is for a next comment. For similar reasons, the XML test coverage is going to fail.So in this patch, I commented out the "primitives as strings" BC layer test coverage. I also disabled the XML "GET" test coverage. Just to prove the general approach.
This patch should be green, and hopefully this patch will finally start getting the reviews it needs to be able to move forward.
Comment #115
BerdirHm, \Drupal\image\Entity\ImageStyle/image_style config entity is as codebase as it gets and that definitely uses image styles, not derivates. Almost all code references to derivatives in image.module are related to the allow_insecure_derivatives setting, no idea why that doesn't use derivatives.
I'd say using a non-drupal term could in turn be confusing for anyone who actually knows Drupal :)
Also a bit worried about adding more computed properties. They aren't free and unlike non-computed properties are automatically created (not actually computed/accessed, but created) in the constructor of the FieldItemBase. There is an issue to try and optimize that but I couldn't make it work yet.
Comment #116
Wim LeersAnd this then implements #113.
Comment #117
tedbowre #115 @Berdir would know but better than what the performance it would be computed fields but as a counterpoint....
The reason we did #2871591: Allow ComplexData in TypedData to specify computed properties that should be exposed in normalization and other contexts was because if we expose extra metadata in through normalizers which this issue originally was going to do then from that issue summary:
I think we determined 3) was big reason that applies here we can't dynamically document our REST API(or JSON API in contrib) if this type of information is added in normalizers.
Comment #119
Wim LeersUgh, the #116 interdiff was correct, but the patch was not. It was missing one hunk of the interdiff.
Comment #120
Wim LeersDamn, #119's interdiff is wrong. Attached is the interdiff between #116 and #119. Sorry for the confusion!
Comment #121
e0ipsoI agree with this. However this term is going to be exposed through APIs to non-drupalers (iOS, Roku, React, …). In fact, they will be the main customers of this property. That's why I feel like @Wim Leers accurately describes in:
That being said, I don't feel strongly about this. I just have a preference.
Comment #122
damiankloip CreditAttribution: damiankloip at Acquia commentedThis is still looking good overall.
Should this just be "image_style"? I know it's mainly being used as a list implementation but this plural naming seems weird in this context.
This label should indicate we get more than just a URL maybe.
Is this because EntityResourceTestBase::castToString() needs more smarts? I guess the expected response we assert against thinks all the properties should be strings as it works recursively?
I wonder if it would help if we could use a MapDataDefinition type implementation instead, so we have actual typed data properties for the properties here. This would then fix the normalization case I think? As sites opting in to the BC behaviour would get all strings I think. Oh... hmm. That would mean we'd have to set the initial values as strings, and rely on casting in the primitive data normalizer...
Should we modify the ListNormalizerTest slightly to reflect this?
Comment #123
Wim LeersSo:
I see both points of view. But I think that any Drupalist will recognize image style URLs even if they're under the "derivatives" key. And "derivatives" makes more sense to the broader world. So I do tend to lean towards @e0ipso's preference/recommendation here.
Comment #124
Wim LeersComputedImageStyle
.ComputedImageStyle::getValue()
is hacky. It shouldn't return PHP primitives, it should returnTypedDataInterface
objects implementingPrimitiveInteface
.I literally can't figure out how to implement that, because I can't just do
new IntegerData(…)
, because a data definition must be passed.This patch needs review from a Typed Data expert I think.
Comment #125
BerdirOne thing to consider is that sites tend have a lot of image styles. Especially when using responsive image styles (see below).
I just looked at one example of a site that I know has a lot of image styles and I'm seeing a *pager* on the image style site, in total 61 image styles.
Unconditionally showing all of them really isn't an option IMHO.
If this would be done in context of REST/serializer, then I could imagine it being controlled by a query argument like ?include_image_styles=medium,thumbnail. But having this on the entity field level makes that more complicated.
The second thing to consider are responsive image styles, but I suppose logic for that will be implemented client-side?
Comment #126
e0ipsoI strongly +1 this. I tried to explain my reasons in this article. The main objective of https://www.drupal.org/project/consumer_image_styles is to mitigate this problem.
Comment #127
Wim LeersI think this needs something like the attached patch.
Comment #128
Wim LeersIn any case, this can be updated to use
ComputedItemListTrait
, introduced in #2392845: Add a trait to standardize handling of computed item lists, right? Well, it doesn't work, for some reason$this->valueComputed
starts of as TRUE! I suspectPathItemList::$valueComputed
's value is somehow being transfered toComputedImageStyleList
… :OComment #129
Wim Leers#125 + #126 I've already had this discussion with @e0ipso in #2921257-14: On Drupal 8.5, JSON API should respect Typed Data's new ::isInternal(), and JSON API Extras should use ::setInternal() through #2921257-17: On Drupal 8.5, JSON API should respect Typed Data's new ::isInternal(), and JSON API Extras should use ::setInternal(). Please read my arguments there too.
#2825814: [PP-1] Allow URL query argument to limit the image style URLs returned by ImageItemNormalizer exists for that (added in #2!). The default would still have to include all image styles. Because A) having dozens of image styles is not the norm, B) it ensures good discoverability.
Comment #130
e0ipsoNot to dwell on this, but it do think that dozens of image styles is indeed the norm. At least for the sites I am usually involved.
Comment #131
Wim LeersIf we're not going to expose this by default, then I don't see the point of doing this. If it's there, but so hidden that nobody will discover it (i.e. it's required to read docs first), then we might as well not do it.
Comment #132
Wim LeersTo be clear: #131 is not a knee-jerk reaction. I'm not mad or annoyed. I just am trying to ensure that we are working on higher impact issues first. And if this is not exposed by default, I don't believe this is high-impact anymore.
Comment #133
dawehnerHaha, websites are more complex than you imagine. Still, the strategy has been with Drupal core to always expose everything.
One example is to expose formatted text by default. The additional size of the response of adding formatted text easily outweights MANY image styles.
For me at least on the longrun jsonapi / the consumer module provides a better solution, but for the purpose of core itself exposing everything provides a reasonable solution.
Comment #134
BerdirGood to know about that issue, but that kind of underlines my point :)
We define a computed property that automatically exposes and generates* all image style URL's and then the follow-up will have to implement a custom serializer to then limit those options again, because we definitely can not somehow pass URL query arguments to a computed property (which has no concept of passing arguments).
So.. why not make it a serializer in the first place that only generates the actually requested** image styles?
It's great that we have a new hammer (ability to expose computed properties) but not every missing information in REST is a nail :)
* note that doing this is not cheap in some cases, for example, when hosting images on S3, the current implementation has to fetch the file, convert it, and then send the generated image back up to S3 *when* the url is built, because it can not create them on-deman.
** Yeah, also not convinced that we should send all by default, I'd also say that any non-trivial site quickly has a dozen or more image styles, you just need 3 responsive image styles to get to 9, then a few thumbnails and so on and you're at a dozen.
Comment #136
justafishThis patch is exactly what I needed for my current project 👍Attached patch is from #124 and makes outputting each derivative optional.
Comment #137
justafishAlso needed the ability to filter by entity/bundle
Comment #138
justafishComment #139
justafishA bit more progress, though MediaJsonAnonTest is still failing
Comment #140
alexpottThe patch attached makes the ComputedImageStyle a Map so its properties are typed which then allows the normalizers to do their magic. This exposes an interesting feature that this kinda expects all values to come in as strings because that's how the db would handle them and then types them using the TypedData primitive.
Left a few @todo's in the code for things I thought whilst trying to make the
core/modules/media/tests/src/Functional/Rest/MediaJsonAnonTest.php
test green.Comment #141
alexpottFixing some of the config schema related fails and protecting the new properties on the ImageStyle entity.
Comment #144
alexpottThere's a way we can do this with less change. We can use the image style config entity's third party settings and store stuff there when the serialization module is enabled.
There are some things we need to decide:
Comment #145
justafishNice 👍
> when the serialization module is installed do we need to update all the existing configuration entities to have the default values
If we include all by default, then no (if include_in_normalized_entity is missing instead of explicitly false, we assume we include it)
> do we need to provide a UI for this
Maybe some checkboxes on the image style configuration if serialisation is enabled? Might be better to discuss in a follow up though
> what are the defaults - atm all image styles will be included
+1 including all by default
Comment #146
alexpottI think it is okay to punt the UI and whether or not to add the defaults to image styles when serialization is enabled to a follow-up. We have the functionality for advanced use-cases and with the current approach the derivative info will be there for all image item / image style combos which is good.
Patch attached tries to use the ComputedItemListTrait which I definitely think we should use. I had a problem with the setValue() and the null situation. Plus we had to override the get because of the use of string keys here. I'm not sure how much the usage of string keys in a list item is going to continue to make troubles. I'm going to ping @amateescu since their knowledge of computed fields is second to none.
Comment #147
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedHere's an initial review:
Needs an empty line for better readability.
We should try to get the entity outside the foreach, and return early if we couldn't find it. This way we'll also remove the need for the try/catch block.
And we should use
$image_item->getEntity()
instead of manually going through the parents :)Missing a leading slash. Probably moot based on the point above.
We can't use string values as keys for
$this->list
, since that property should only contain a numerically indexed array, see\Drupal\Core\TypedData\Plugin\DataType\ItemList::$list
. Every part of the system works based on this definition of the list property, so I've no idea what other things might could break because of this..If we need the image style machine name, I would suggest to include it one level below, alongside url, width and height.
Shouldn't we use
\Drupal\Core\TypedData\PrimitiveInterface::getCastedValue()
instead?This seems to contain exactly the same logic as code>\Drupal\Core\TypedData\ComputedItemListTrait::get, so it shouldn't be needed.
When the point above on
$this->list
being numerically indexed is fixed, this change should not be needed anymore.Comment #148
alexpott@amateescu the problem with not using sting keys is that makes it way harder for someone to get the thumbnail or large image style of an image. If the image style machine names are keys this is simple.
Comment #149
amateescu CreditAttribution: amateescu for Pfizer, Inc. commented@alexpott, yes, I understood the reason why it's written like that, but if the goal is to use string keys for the
derivatives
property of the image field type, it can not use the default typed data item list (\Drupal\Core\TypedData\Plugin\DataType\ItemList
) and it would need a custom version of it with different implementations forrekey()
,first()
,appendItem()
and who knows how many other methods. Those are just the ones I found on a quick visual scan of that class..Comment #150
Wim LeersOMG I did not realize this had gotten so much attention/activity in the past week! (Nor Sally's first comment in #136.) Sorry, I've been deep down in JSON API land. I'll comment on this ASAP.
Comment #151
justafishThank you for the thorough review @amateescu! 👍
Big +1 on #148 - not having string keys massively reduces the usability of this
Comment #152
Wim Leers❤️
See #124.3 and #114 for my previous observations and attempts. I also had to fight the string handling.
FieldItemList
, but even\Drupal\Core\TypedData\ListInterface::set()
says this is not allowed :(So I think all of this needs to change? It sounds like rather than a list (numerical keys), this should become a map (string keys)?
Comment #153
alexpottIn an conversation today @justafish suggested that maybe we could use a normalizer to add this information to an ImageItem instead of using TypedData and a computed field. What do people think?
Comment #154
amateescu CreditAttribution: amateescu for Pfizer, Inc. commentedSince the main (only?) use-case for this feature seems to be REST API calls, I'd say that it makes sense for this code to live in a normalizer.
Comment #155
BerdirYes, that's also what I wondered in #115. I believe that goes against Wim's plan (#2926507: Discourage @FieldType-level normalizers, encourage @DataType-level normalizers, to strengthen the API-First ecosystem), but as i pointed out here and there, I'm not happy about putting everything into typed data, for performance and complexity reasons (things like string vs integer keys that is complex with typed data is a non-issue with a normalizer that can return arbitrary read-only data.
It also means that we might need to duplicate it into multiple normalizers because they return different structures, but that does not seem like a reason against doing that IMHO but more likely indicates that the architecture we have for the whole normalizer stuff isn't really such a great fit.
Comment #156
alexpottHere's a version of the patch still using typed data but computing the map and not using the item list stuff.
Regarding the normalizer discussion - if we're going to go that way how can we ensure that we don't get into priority problems?
Comment #157
Wim LeersExtremely strong -1.
See #2926507: Discourage @FieldType-level normalizers, encourage @DataType-level normalizers, to strengthen the API-First ecosystem.
We should NOT add more
@FieldType
-specific normalizers that only work for particular formats. Because that then won't work for JSON API or GraphQL. It means we'll have to implement the same logic three times.Can you explain this? I don't remember you bringing this up before?
#156 looks great!
Comment #158
Wim LeersIf we can agree to postpone configurability/tweakability to a follow-up, then this is RTBC as far as I'm concerned. Then it could ship with Drupal 8.6!
Comment #159
Wim LeersThis already has test coverage, so removing
.Comment #160
BerdirI know you are against that :)
Performance: Yes, I did, in #115 for example:
Also a bit in #125, simply because building a list of 20 or so image styles in typed data structure is far more expensive than just building a plain array structure.
Comment #161
alexpottRe #158 well maybe we could start with only the include_in_normalized_entity setting since that does not have the complexity of specific bundle / entity type selecting and dependencies and goes a little bit of the way to addressing @Berdir's performance concerns if you have a gazillion images styles.
Comment #162
Wim Leers#160: sorry, I did not find #115 when searching the other day. How much of a performance problem is this? It doesn't seem like it has a massive performance impact, plus doesn't entity cache largely mitigate this?
#161: I think that Berdir is saying that doing this using computed properties at all impacts performance; I think he doesn't necessarily care about how many things there are to compute. (Because he's saying he's concerned about create cost, not a compute on access cost, because they're not actually computed until accessed.)
Comment #164
ndobromirov CreditAttribution: ndobromirov at FFW commented#123 - we should be able to accommodate both options. In the end it's just a property name. We should be able to put that in config, have the it defaulting to something and have a non-UI configuration to allow settings.php level overwrite, so people can tune it.
#160 - if you have that many stiles it's a design problem. Core can ship with this and have a follow-up to optimize. As it is it's unusable, so something slow that works is genuinely better than something fast that never comes. On top of that, there is page cache that will speed things up in the 90+% case.
Both of my points can be implemented in follow-up issues, so I will dare to put RTBC this (#156), because it:
- Has tests.
- Solves a real issue in using Drupal 8 in any decoupled scenario that has images in it.
- Works!!!
Comment #167
Wim Leers@ndobromirov came here because I pointed him here from #2992822: Image styles, which I now marked as a duplicate.
#164:
RE #123: WFM!
RE #160: I agree :)
However, I think we should remove the configurability, like I said in #158. What do you think?
Comment #168
ndobromirov CreditAttribution: ndobromirov at FFW commentedThere is no UI for changing that configuration, so using it is going to be tricky.
I think that we should ship with some way to disable items in the list, so contrib can make UIs and stuff.
As I see it patch is good to go because:
- If I have to pick one it should be derivatives as it currently is..
- Only on install everything is enabled.
- You can disable whatever is not needed at later stage, so that will reduce the performance issue that @Berdir was mentioning.
- I am OK with both options with or without the config.
To make things simpler - drop it out and have a follow-up.
Comment #169
BR0kENThe
Exception
here cannot be caught since current namespace hasn't such class. Looks like a typo and should be\Exception
.PHPCS: Missing an empty line after description.
We don't need these variables unless
$include_image_style
is TRUE.Non-existing class. Should be
/** @var \Drupal\Core\Entity\EntityInterface $entity */
The result of
$image_item->getParent()->getParent()->getValue()
should never change and it looks like a good candidate to move out of the loop.It's also good to have commented what
->getParent()->getParent()
means.Should be a method call -
$bundle = $entity->bundle();
Looks like this line can be simply replaced by the
if (empty($granularity[$entity_type]) || empty($granularity[$entity_type][$bundle])) {
.Comment #170
BR0kENThis variant reduces methods calls and allows to simply extend the
ComputedImageStyleDerivatives
for implementing custom rules inisImageStyleAllowed()
.Also, I removed the use of
file_url_transform_relative()
because the relative URL is less useful in decoupled architecture due to the need to somewhere have the URL of the resource to which an image relates.Comment #172
BR0kENComment #173
BR0kENComment #176
BR0kENComment #177
BR0kENPrevent recursion.
Comment #179
BR0kENHm, the
$normalization[$field_name][$i]['derivatives']
is tested byis_array()
twice.Comment #180
BR0kENWhy the upload of ~15 kb takes around 2 minutes? Started experiencing this on D.org since yesterday.
Comment #181
Wim Leers@ndobromirov:
The configurability that this patch is introducing (and which I'm opposing) does not address @Berdir's performance concern as far as I know, because computed values are always computed, see #162.
+1
@BR0kEN:
This is inconsistent with how the file URL is normalized for
File
entities, since #2825487: Fix normalization of File entities: file entities should expose the file URL as a computed property on the 'uri' base field. Please restore this.I've proposed a way forward almost two months ago, in #158. An MVP. Contrib can handle the configurability (and accompanying complexity) of which image styles should show up. I'd love to see this land, but configurability of core REST is already painful enough (it's practically impossible without https://www.drupal.org/project/restui). This would make that considerably more painful. IMHO a contrib module like https://www.drupal.org/project/better_normalizers can decorate the normalizer that's being added here to add configurability. Then only sites that actually observe a performance problem with listing every available image style need this additional complexity.
So, this is what I'm proposing. @alexpott's #156 minus the configurability.
Comment #182
Wim LeersThis ports @BR0kEN's changes, plus CS fixes and minor cleanup.
Comment #185
BR0kENWhere this namespace/class exists?
What about overridden entity class and "loadMultiple" method of it?
Why do we need to call $this->getTypedDataManager() in a loop?
@Wim Leers, what is the idea of having relative URLs?
Comment #186
Wim LeersI shouldn't have reverted this hunk.
Comment #187
Wim LeersThis was discussed in detail in #2825487: Fix normalization of File entities: file entities should expose the file URL as a computed property on the 'uri' base field, and consensus was reached.
Comment #188
Wim LeersOh and rather than configuration, we could also make this controllable through the URL, like I suggested two years ago in #2: #2825814: [PP-1] Allow URL query argument to limit the image style URLs returned by ImageItemNormalizer. I propose we use that follow-up issue to make it controllable, be it through a URL query arg, through configuration, something else, or all of them.
Let's get this foundation in.
Comment #189
hamrant CreditAttribution: hamrant at Five Jars, Drupal Ukraine Community, Open Y for Drupal Ukraine Community commentedI have tested last patch with JSON API, works great, thanks @Wim Leers
Some test results:
I think better to use uri and url instead just url that was changed by `file_url_transform_relative()` function.
Now this used in file entity and looks like this:
This is useful for internal use and for external (for example by vue or react app). I suggest using the same structure in derivatives. As result it should looks like this:
Comment #190
Wim Leers@hamrant: Thanks for testing!
The top-level
url
property you quote only exists when using JSON API, not in Drupal core. It also has been removed from JSON API 2.x, because Drupal core added that root-relativeuri.url
property.Comment #191
BR0kENFound the issue when
\Drupal\serialization\Normalizer\ComplexDataNormalizer
got$object
transformed tonull
.Comment #192
Wim Leers@BR0kEN: wow, interesting! Can you also share steps to reproduce that? Ideally a failing test.
Comment #193
BR0kENHad no time for a test yet, but during debugging it turned out that it's due to a field with
svg
.Comment #194
Wim LeersThis came up again. This time in #3007268: Make Consumer Image Styles compatible with JSON API 2.0-beta2, which is blocking a stable release of JSON API 2.0. The idea of the https://www.drupal.org/project/consumer_image_styles module is to allow one to configure which consumers of the API exist, and which image styles those consumers care about, to then only get those image styles in the output.
Like I said in #188 two months ago (and many comments before it), I'm fine with supporting this. #3007268 implemented something like this already, but A) at the normalizer level, B) only for JSON API. It was modifying JSON API internals and hence it broke in the move from JSON API 1.x to 2.x. If it were implemented at the Typed Data level like this issue proposes, it wouldn't have been a problem at all.
So I checked what it would take to change that implementation, to instead build on top of this core patch.
I've confirmed it to be feasible, but one small change is necessary here: the patch here needs to respect the computed property definitions. Once that is done, it works fine.
Note: relative to #187, not #191, because #191 is not on top of #187.
Comment #195
Wim LeersHere's also initial cacheability support. In line with what we did in #2626924: Include processed text in normalizations: "text" field type's "processed" computed property should be non-internal and carry cacheability metadata.
That issue updated
\Drupal\serialization\Normalizer\TypedDataNormalizer
, but in this case, a more specific normalizer takes precedence (\Drupal\serialization\Normalizer\ComplexDataNormalizer
), which hasn't been updated yet.EDIT: note I specifically used
RefinableCacheableDependencyInterface
instead ofCacheableDependencyInterface
to make it simpler for contrib/custom modules to customize the list of computed image style derivatives based on configuration, request context, et cetera.Comment #197
Wim Leers#195 failed due to newly added cache tags — great, this means that things are working, and our tests are catching the changes in cacheability! 👍
What was sitll missing was the fact that this by default will result in the computing (and normalizing) of every image style, which means that when the list of image styles changes, so must any cached results. So let's update the code responsible for generating the definition (which will also affect OpenAPI docs for example) to associate the appropriate cache tag.
Comment #199
Wim LeersDown to 3 failures: the
hal_json
tests.Because
\Drupal\hal\Normalizer\EntityReferenceItemNormalizer
does not normalize all properties on the field, it explicitly ignores those and only normalizes the referenced entity. That's also why e.g.field_media_file
'sdescription
anddisplay
properties, andthumbnail
'salt
,width
,height
andtitle
properties are not normalized inhal_json
.And because it doesn't normalize any properties, it also doesn't get the cacheability associated with them. And hence the 3 failures here.
Comment #200
e0ipsoWhat do you think about:
That will help ease the pain when creating an image style URL has performance implications. It will also simplify
consumer_image_styles
a lot.Then one can do:
Comment #201
e0ipsoThis is the idea I'm proposing above.
Comment #203
e0ipsoUgh, my patch above is broken due to a blunt attempt to use D8.6.3 as a base install. Hopefully, the idea I'm proposing is clear enough.
Comment #204
Wim LeersI missed your comments until now, sorry!
Introducing more alter hooks is problematic IMHO. We want fewer hooks, not more. Having alter hooks for just about anything is largely why Drupal has as much technical debt and complexity as it does.
This would make
consumer_image_styles
simpler, at the cost of makingdrupal
more complex. The patch I provided at #3007268-18: Make Consumer Image Styles compatible with JSON API 2.0-beta2 already shows howconsumer_image_styles
can achieve the same with minimal code, without introducing more APIs.If everybody else feels this is the way to go, then I'm fine with it. But I'd be concerned about the direction we're going with Drupal core.
Comment #205
jofitz CreditAttribution: jofitz at jofitz commentedCorrecting the patch in #201.
Leaving as NW to address @Wim Leers comments in #204.
Comment #206
BerdirSee #2975722: Many slow queries for lookup up crop of a image_style + file for an issue that this caused. If you use crop.module, it has to check each generated image style url for a crop configuration using an SQL query and add a query parameter so that we can invalidate caches if the crop changes.
Another example would be if you use amazon S3 to store images, many implementations then already check and generate the image styles when generating the URL's as they can't do it on-demand, so the first request to a node with a few images multiplied by bunch of image styles could take like a minute to generate.
So I still think that by default returning all styles is the wrong thing to do and I'm still unhappy about having all this exposed through entity field properties because generating/maintaining those is expensive and needs to be done every time you use that entity, not just on serialization.
Just yesterday I saw an example from a Drupal GraphQL project where the client could request the image styles he needs, I still believe that is the approach that makes the most sense because I'm pretty sure it's very common that different requests need different styles, e.g. when you fetch a list of articles for a list of teasers you need the teaser image style and when you fetch the information for the detail page, you need the large ones. I'm also aware that this means that we likely have to duplicate at least part of the logic for each API/serializer format :(
Comment #207
Wim LeersActually, #2975722: Many slow queries for lookup up crop of a image_style + file is a performance issue in the Crop module regardless of this.
I think you meant to link to #3014232: [regression] ResourceTypeRepository is significantly slower in JSON:API 2, becomes noticeable when handling hundreds of interlinked resources, where a site applied this core patch, and it is causing ~10% of the total response time (see #3014232-18: [regression] ResourceTypeRepository is significantly slower in JSON:API 2, becomes noticeable when handling hundreds of interlinked resources.3). Although to be fair, in that case we're computing all 22 (!!!) image style derivatives for 54 image fields. Having 22 image style derivatives is pretty exceptional, and questionable (the reporter acknowledged this, and said they could easily cut it in half over at #2975722-4: Many slow queries for lookup up crop of a image_style + file).
The Crop module overall seems to have some architectural problems: #2975722-7: Many slow queries for lookup up crop of a image_style + file.
Excellent point! Arguably this should happen during the saving of the node that references these images though, since that's already a slow operation. Lazily generating them the first time they're accessed is going to result in noticeable slowness for end users.
Can you think of a counterproposal?
Yeah, so that is the alternative to the configuration-based proposal above. And like you say, that also comes with serious downsides.
I really want to address your concerns, but I also really don't want configuration in Drupal core that's pretty much impossible to discover. For Drupal to be actually API-First, all data needs to be accessible via its (HTTP) APIs.
Very rough idea: Is there perhaps something we could do like a
generate-then-redirect
link relation for each of the image style derivatives? That'd mean generating just a bunch of links, which an API client would have to follow in order to get to the actual data.Comment #208
e0ipso#205 thanks for fixing that!
Just to re-state it, I agree with two points @Berdir brings again in #206:
The patch in #205 will address the first concern, but not the second.
The major friction on this issue has always been performance. There was some hesitation in comments above that this could lead to performance issues, but #3014232: [regression] ResourceTypeRepository is significantly slower in JSON:API 2, becomes noticeable when handling hundreds of interlinked resources proves that the performance problem is real during serialization. It is probably real during entity loads as well, meaning that the performance degradation is even noticeable in non-decoupled projects.
A typical project will have many image styles (I don't think the number of image styles in #3014232: [regression] ResourceTypeRepository is significantly slower in JSON:API 2, becomes noticeable when handling hundreds of interlinked resources is unreasonable), and you have to multiply that by the number of different designs for different consumers.
I don't think this is actually a problem. Every project has specific serialization needs. We could try to find some common ground around how to normalize typed data but even then there is no guarantee that all the projects will want the same result. This largely happens today, and will continue to happen regardless of the outcome of the resolution of this issue. For instance, GraphQL will allow the consumer to select an image style (or even generate one on the fly) so switching to this may be a step back. Maybe we can have @pmelab or other GraphQL devs confirm this.
I wouldn't make this a hard requirement for this feature.
Comment #209
e0ipsoIn order to unblock this issue we met in a hangout.
Participants: Wim Leers, justafish, Berdir and e0ipso. Baby cameos happened but they were not of relevance for this issue.
Meeting conclusions:
There is one key remaining question that we did not discuss:
What should be the default behavior? (a) do not generate image style URLs unless explicitly requested because they are expensive, or (b) generate all the all the image style URLs because the PHP API is hard to discover?
Comment #210
e0ipsoThe patch in #205 may tick all boxes. It uses approach (a) to the default behavior. However there may be a problem with entity cache since whatever image styles were selected on a cold entity load will remain there until entity cache is invalidated.
Additionally we'll be adding another cache tag to our entities
image_style.list
, but I think that's OK.Comment #211
e0ipsoComment #212
miiimoooRe-rolled for last nights security release 8.6.10.. couldn't get the interdiff done.. sorry
Comment #214
vtcore CreditAttribution: vtcore at FFW commentedRe-rolled patch for 8.7.x
Comment #215
Wim LeersTaking another fresh look at this :)
By the way, with 42 followers, this is one of the most-followed remaining API-First Initiative issues.
#208:
vs
#209:
That seems contradictory?
Quoting @Berdir in #206:
Thinking about this again, here's one crazy idea (that I have concerns about too, but I figured I'd at least leave it as a suggestion). What if we make
'derivatives' => []
by default, but add'derivatives_instructions' => 'Add a`derivatives=style1,style2` query string parameter to get derivatives, valid derivative styles are: `thumbnail`, `medium` and `hero`.
. Then when?derivatives=thumbnail,medium
appears in the URL, you'd get'derivatives' => ['thumbnail' => …, 'medium' => …]
, and'derivatives_instructions'
would disappear.This would work in JSON:API, REST and GraphQL.
It'd be a first time that we have request context-dependent computed data but … that's exactly what the
url.query_args:derivatives
cache context describes!After having written this, I scanned the issue, and found @Berdir proposing the same in December 2017 in #125:
and this in #135:
I'm proposing we do do that, despite this being new territory.
Thoughts?
Comment #216
ndobromirov CreditAttribution: ndobromirov at FFW commented+1. Having a solution in core for decoupled image styles is highly important.
As I see it a fast hack should be fairly easy to do on top of the existing patch, so we can have a working PoC to have discussions on.
Comment #217
e0ipsoWe established that the image style URL generation needs to be treated as a resource intensive operation in the call referenced in #209.
Having anonymous users trigger resource intensive operations may be dangerous. I think the appropriate approach is to have a setting server-side that gates the image styles that may be used.
Comment #218
garphy CreditAttribution: garphy at ICI LA LUNE commented@e0ipso,
Image styles aren't generated until there actually requested : listing image style URLs in the response body doesn't actually generates the derivative. Putting the URLs in the response isn't intensive pre-se.
But maybe you care that the URLs are disclosed, then maliciously used to DoS the infra ?
Comment #219
Wim LeersThanks for chiming in, all! I was hoping for more responses. Hopefully this response from me results in more community members who previously spoke up to speak up again :)
#216: 👍 🙂
#218: it's not just computing the image style URL though, it's also instantiating typed data properties, and computing the values for the
width
andheight
typed data properties, and hence loading theFile
entity.#217: Anonymous users can already trigger resource-intensive operations. It's already possible to bypass Page Cache by appending a random query string. Having a malicious user do that on the most expensive page on a site would cause a load similar to that of a malicious user requesting a lot of unneeded image styles.
Comment #220
e0ipso#218 there is a whole discussion in this thread (I know... it's loooong) clarifying that point and building consensus on that statement.
#219 I don't think this is necessarily the same case. It certainly is from the point of view of the URL creation. It being a problem in other systems doesn't necessarily mean that we want to have another instance of the problem.
I'm sure you remember we had a security release specifically on the issue of image styles (leading to server side "rendered" image style URLs containing the famous #itok). I see where you are coming from though. However unless we limit the derivatives out of the box we'll be giving out *many* #itok which may defeat the point.
Let's try to unlock this again. What do you think it needs to happen for that? Should we have a recap summary of the current positions? This is an outstanding gap in the API First capabilities of core, let's fix it!
Comment #221
Wim LeersFirst:
💪🥳👍 :)
Great point. The goal of that
?itok
query string is to ensure that only the server can choose which image styles to generate, not the client. If anonymous users can specify?derivatives=medium,thumbnail,…
, then it's effectively still user-controlled. You've convinced me that this is indeed a regression, an increase in risk. 😔An obvious yet naïve way to mitigate that would be … to require a
specify image styles
permission, otherwise users wouldn't be able to specify?derivatives
. I haven't seen that proposed yet. However, perhaps that wasn't proposed precisely because it is naïve: that still means the anonymous user would not be able to get any image styles at all! We could choose to add agenerate $image_style image style
permission, to only allow a particular user role (especiallyanonymous
) to generate particular image styles.Then instead of my proposal in #215 which resulted in
this would result in
(Note "allowed" instead of "valid".)
What do you think?
Comment #222
ndobromirov CreditAttribution: ndobromirov at FFW commentedThe added security will be OK, but if anonymous needs all the images it will cause maintenance overhead.
If we introduce permissions for this there should be a master permission for
allow all
.Comment #223
smithmilner CreditAttribution: smithmilner at Myplanet commentedQuoting @Wim Leers in #207
Just wanted to add that If the site uses responsive image styles this is very realistic. Each responsive style can use many regular image styles. For example, we have 164 regular image styles for the needs of one of our builds which has 22 responsive image styles.
That said, have we considered support for responsive image styles? Or would that be completely up to the client?
Comment #224
ndobromirov CreditAttribution: ndobromirov at FFW commentedI am still running on 8.6 and managed to hit another edge case - media referencing a missing / deleted file.
Here is patch that resolved it for me.
The patch is against 8.6.16, based on the one from #212.
Comment #225
jibranThis is awefully similar to #2997123-89: Cacheability of normalized computed fields' properties is not captured during serialization.
Comment #227
ndobromirov CreditAttribution: ndobromirov at FFW commentedHere is a re-roll against the latest 8.7 of #214 incorporating the changes from #224.
Comment #229
vsujeetkumar CreditAttribution: vsujeetkumar at Srijan | A Material+ Company for Drupal India Association commentedRe-roll patch created for 9.1.x
Comment #232
iivanov CreditAttribution: iivanov commentedHere is a re-roll against the latest 9.1.4. I was't able to apply the latest patch - 2825812_229.patch
Comment #233
Vinay15Re-roll for 9.1.x, created from #229 as the patch from #232 isn't applying.
Comment #236
joachim CreditAttribution: joachim at Factorial GmbH commentedPatch works well, but a few things need tidying up or changing:
This line isn't very descriptive. Something like 'A data type for image derivatives.' would be better.
This docblock isn't formatted correctly.
Also, is the TODO something that could be done now? If not, file a follow-up issue and explain there why it's blocked or delayed.
This looks like it's in the wrong namespace, as it's not a plugin.
Maybe put it in Drupal\Image\TypedData, since the parent class is in TypedData too?
This should match the other related classes' first lines, which all start with 'A typed data definition class ...'
This is inventing a hook. Do we want or need that here?
Also, hooks need to be documented.
Comment #237
vsujeetkumar CreditAttribution: vsujeetkumar at Srijan | A Material+ Company for Drupal India Association commentedRe-roll patch created for 9.3.x
Comment #239
vsujeetkumar CreditAttribution: vsujeetkumar at Srijan | A Material+ Company for Drupal India Association commentedWorked on #236, Please have a look.
#236.1: Done
#236.2: Done with dockblock formatting only.
#236.3: Done
#236.4: Done
#236.5: Needs to Work.
Comment #240
vsujeetkumar CreditAttribution: vsujeetkumar at Srijan | A Material+ Company for Drupal India Association commentedFixed the fail tests.
Comment #244
cweiske CreditAttribution: cweiske at Mogic GmbH commented#240 works fine here on Drupal 9.4.2. It allows me to index image variants into elasticsearch.
Comment #245
ravi.shankar CreditAttribution: ravi.shankar at OpenSense Labs commentedTrying to fix failed tests of patch #240.
Comment #247
RassoniFix patch failed 10.1.x branch (not include test cases issues)
Comment #248
RassoniFixed CC issue