Problem/Motivation
If you have a media type that uses an image field as it source, and that field has a minimum/maximum resolution defined, the media library will completely ignore those constraints when uploading a new image into that media type.
Steps to reproduce
- Install the Standard profile, and the Media Library module.
- Add a media field to a content type, referencing the Image media type.
- Edit the Image media type's source field ("Image") and set a maximum resolution of, say, 16x16.
- Start creating some content, and open the media library.
- Upload an image, bigger than the maximum allowed resolution, into the library.
- You'll see that the upload proceeds without a hitch, even though the image is bigger than what's allowed.
Proposed resolution
The media library defers to the field's getUploadValidators() method to determine how to validated uploaded files. As per the discussion between @phenaproxima and @alexpott in #33-35, it makes sense for the ImageItem field type to override this method and provide validators that are specific to images, including resolution constraints, and have Media Library defer to that. This will provide a consistent API to determine image validation. While we're at it, we should also try to clean up other places that have had to manually set the validation, such as the Image module's integration with Quick Edit, REST's FileUploadResource, and JSON:API's TemporaryJsonApiFileFieldUploader.
Remaining tasks
Address feedback on merge request, and commit.
API changes
None, really; ImageItem::getUploadValidators() -- which it inherits from FileItem -- will provide more specific validators, but this does not change the public API.
Data model changes
None.
UI changes
None.
Release notes snippet
TBD
| Comment | File | Size | Author |
|---|
Issue fork drupal-3008292
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
stefan.kornComment #3
stefan.kornComment #8
phenaproximaTransferring credit from #3016649: Image minimum and maximum resolutions should be configurable per field instance (for fields of Reference type Media with Media type Image) and these should be honored when uploading new images or selecting existing ones from the media library, which I closed as a duplicate of this one.
Also tagging this for test coverage.
Comment #10
phenaproximaThis is going to need a reroll; the patch refers to code which no longer exists.
Comment #11
strykaizer@phenaproxima patch from #3016649: Image minimum and maximum resolutions should be configurable per field instance (for fields of Reference type Media with Media type Image) and these should be honored when uploading new images or selecting existing ones from the media library still applies and fixes the issue. Not sure if reroll is required?
Still needs tests though
Comment #12
phenaproxima@StryKaizer, can you repost that patch in here? When you do, you can remove the "needs reroll" tag. :)
Comment #13
strykaizerMoving patch from #3016649: Image minimum and maximum resolutions should be configurable per field instance (for fields of Reference type Media with Media type Image) and these should be honored when uploading new images or selecting existing ones from the media library (#13) by jaskaran.nagra to this issue
Comment #14
strykaizerComment #15
slv_ commented#14 is working for me without issues so far.
Comment #17
jamesini commented#14 applied cleanly and seems to have resolved the issue by applying the image dimension validation as configured on the image. Thanks so much @StryKaizer I was beginning to think I was going crazy 8^)
Comment #18
liliancatanoi90 commented#14 works fine.
#2 Tried to apply the patch on 8.9.0, failed.
Here is the full log.
Comment #19
awolfey commented#14 is working, even on 8.8.8. Thanks.
Comment #20
slv_ commentedComment #21
slv_ commentedLooks like this only needs tests before merging.
Comment #22
phenaproximaThis is a fairly major bug, so I'm bumping priority.
Comment #23
anushrikumari commentedRerolled patch for 9.1.x
Comment #25
nikkrop commented#14 Works good for me.
Comment #26
r_h-l commentedBoth patches throw warnings on the if statement for non-image media types. Recommend using isset or !empty instead of just looking directly at those array keys.
You also need to make the code more robust in case one is set and the other isn't. I am attaching versions that build in these fixes.
Comment #27
kclarkson commentedWow! This is super important. If just had a project where the images were all off wack and I couldn't figure out why that was happening. Well they were uploading an image that was too small. Great job Drupal community!
I just applied the 9.2 patch for drupal 9.1.5 and everything applied cleanly and works great.
Comment #28
darvanenAgree with @R-H-L that checks are needed to see if settings exists before attempting to reference them.
This code needs to be moved to \Drupal\file\Plugin\Field\FieldType\FileItem::getUploadValidators instead of its current location as that is where upload validators are built for this field type.
Comment #29
dwwThanks for working on this! Agreed with @kclarkson this is super important. Per #21, this still 'Needs tests' before it can be RTBC, so back to NW.
Cheers,
-Derek
Comment #30
dwwLooking more closely at the patch, a few other points that need work:
Don't we always want this added, even if (max|min)_resolution isn't set?
These can be simplified via the null coalesce operator:
Thanks again,
-Derek
Comment #31
kishor_kolekar commentedHey, I have tried to cover the points mentioned in #30
Please review
Comment #32
spokjeI think #30.1 was addressed incorrectly in patch #31.
Attached a new patch that (I hope) a addresses it correctly.
Pondering creating a test for this one, let's see if I can manage to get some spare time for that.
Comment #33
phenaproximaI definitely agree we need to fix this. However, I'm not super comfortable with the current direction of the patch. Right now, it requires Media Library to know internal details about how image uploads are meant to be handled. Since the media system is meant to operate more generically, I'm not sure that's something we want to do. I'd much prefer if we could simply modify FileUploadForm::createFileItem() so that it would ask the source field itself what upload validators it should use, and let it call the shots.
So I gave that a try on my local installation. But I ran into a problem: the ImageItem class (the field type associated with image fields) doesn't ever bring in
file_validate_image_resolution()as an upload validator! As far as I can tell, that's done specifically in ImageWidget::formElement(), as well in the Image module's Quick Edit integration and in the File module'stemplate_preprocess_file_upload_help(). So to me, this looks like a leaky API in the Image module.On the one hand, there is precedent for having code outside of the Image module refer to that upload validator, so it makes sense to copy that pattern. On the other hand, by following that precedent, we're exacerbating an existing problem.
In the name of getting this fixed rather than blocking on clean API design, my preference is for us to stick with the current fix (maybe with a few relatively minor changes), but open a follow-up issue, and add a
@todocomment in the code linking to that issue, to correct the API leak and ideally make ImageItem::getUploadValidators() returnfile_validate_image_resolution().I'm tagging this for framework manager review so I can get a second, more expert opinion about this discovery and how I propose we move forward. Framework managers: is this truly a leaky thing that should be refactored, or am I just being persnickety? Do we consider upload validators to be part of our API?
Comment #34
alexpottI think @phenaproxima's idea might work.
Looking at ImageWidget...
Much of that looks like it belongs in ImageItem::getUploadValidators() - it would lead to a more coherent and less surprising API - as well as making it easier to build alternate widgets for images.
Comment #35
alexpottI think given ImageWidget should still have the same validators and this will fix ImageItem::getUploadValidators() to return the correct list I think addressing ImageWidget, FileUploadForm and quickedit in the same patch makes sense. We should probably re-scope the issue to be about fixing
ImageItem::getUploadValidators()Doing it this way will also fix the fact that FileUploadForm is not ensuring that the format is supported by the image factory.
Comment #36
phenaproximaOK, tagging for a rescope, issue summary rewrite, and re-titling.
Comment #37
phenaproximaComment #38
phenaproximaComment #40
effulgentsia commentedThis is great! I think this issue's scope should include making this the source of truth for REST and JSON:API uploads as well, which I suspect currently also skip validating the image resolution.
Comment #41
phenaproximaThanks for the suggestion, @effulgentsia. I agree with you, and I added REST and JSON:API to the issue summary.
Comment #42
wim leers🙏😊
#40:
Indeed. REST & JSON:API had to copy logic, so they must suffer from the same flaws.
We already have explicit tests at
\Drupal\Tests\rest\Functional\FileUploadResourceTestBase::testFileUploadLargerFileSize()and\Drupal\Tests\jsonapi\Functional\FileUploadTest::testFileUploadLargerFileSize()for REST and JSON:API respectively — we should to add sibling test methods to ensure image upload validators run! 🤞 I see that you already addedImageItemTest::testUploadValidators()— that'll be a great starting point! :)Comment #43
alexpott@phenaproxima how come
from ImageWidget is not also moving to getUploadValidators()?
Comment #44
phenaproxima🤔 The reason I left that part alone is because it's specifically filtering the allowed extensions against what's supported by the image factory. I could do the same thing in ImageItem::getUploadValidators(), but it's not clear that a) I'd be able to inject the image factory as a dependency, or b) whether it would even be desirable to filter that way.
But I'm open to doing that if you think it would be useful when validating any image item.
Comment #45
alexpottIf we're going to use image styles on it in any way that we need to have that validation. It's a very tricky issue but in general Drupal and its users expect image styles to work on image fields. The problem is if we don't do this then it is very possible that someone could upload an image via an API that is not then savable via the UI - and that's a problem.
Comment #46
mohit_aghera commentedComment #47
phenaproximaThis still needs tests, to cover the changes in REST and JSON:API.
Comment #49
steveoriolThe patch https://git.drupalcode.org/project/drupal/-/merge_requests/553.diff from the Merge requests !553 works very well on my D9.1.8
Thanks you @phenaproxima !
>> But, It is not working with the new version of D9.1.9 ...
Comment #50
camslice commentedNothing to contribute, just wanted to cheer you all on because I would love to be able to set minimum dimensions for Media images
Comment #51
phenaproximaHiding patches in favor of the merge request.
Comment #52
steveoriolHello,
How to apply a patch on the latest stable version of Drupal, currently D9.2.5?
I tried adding the following in the "patches" section of composer.json, but it failed:
Comment #53
suresh prabhu parkala commented@steveoriol The image says you have added a link to a diff file instead of a patch file. Please have a look.
Comment #54
darvanenThe MR is behind 9.3.x so it probably won't provide a working patch. I think it needs rebasing.
Comment #55
steveoriolI think darvanen is right, but i don't see how to do this. can someone redo a patch for the latest stable core version (D9.2.5 by now)?
Comment #56
darvanenAfter much wrangling I was able to generate this patch that represents the state of play at #46.
For posterity (i.e. the next time I try to do this) and anyone playing at home, the method was:
The second line is vitally important, don't checkout the main 9.2.x branch, it has progressed and diffs against it are huge.
This patch may not solve your problem @steveoriol, it is just a step in the direction of bringing this issue back in line with the current dev branch (end goal: 9.3.x)
Comment #57
darvanenWow... I didn't think I was going to be allowed to --force push onto a branch here, but it allowed me.
I reset the branch to 9.3.x and applied the patch from #56 which I will now hide.
This has removed the thousands of irrelevant changes from the MR. I do apologise that I effectively had to squash the commits to get this done.
This leaves us at (per #47)
Comment #58
darvanenStill looking for feedback regarding https://git.drupalcode.org/project/drupal/-/merge_requests/553#note_20234
Comment #63
akalam commentedI'm uploading the latest version of the MR as a patch for reference.
Comment #64
ameymudras commentedFixed issues with the above patch, couldn't generate interdiff since the above patch doesn't apply
Comment #65
ameymudras commentedFixing the above issue
Comment #66
mukhtarm commentedThe patch on #65is working fine in 10.1.0-dev. The resizing according to the dimension given in the media library configuration is working fine. Attaching the screenshots for reference.
Comment #67
phenaproximaHiding patches in favor of continuing with the merge request. It's best to just pick one way and stick with it, to avoid confusion.
Comment #68
gaurav-mathur commentedComment #69
gaurav-mathur commentedHi applied patch #65 on drupal version 10.1.x it works. Resizing according to the dimension given in the media library configuration is working fine.
adding screenshot for the reference.
Thank You
Comment #70
smustgrave commentedThink a change record will be needed since a new function is added to ImageItem.php
Comment #71
smustgrave commentedFor the change record and left a VERY small change in the MR.
Comment #73
thierry.beeckmans commentedWe noticed an issue when this patch has been applied by an update of an install profile where the site does not use media library.
When GD2 image manipulation toolkit is used, the only supported types are png, jpeg, gif and webp.
An image field configured to allow only svg uploads ends up with an empty list of supported types, the validator prevents the content editors to be able to upload the svg image.
Comment #74
darvanen@thierry.beeckmans I think out of the box Drupal doesn't support svgs in image fields, are you mixing contrib with this?
Comment #75
arantxioI've rerolled the MR to work on D10.2.
Comment #76
orakili commentedUpdated patch for 10.2.x using the new validation constraints from https://www.drupal.org/node/3363700
Comment #77
orakili commentedSorry the patch in #76 was not replacing the
file_validate_image_resolutionvalidator properly. Fixed in this new patch.Comment #78
darvanenWhy have we reverted from MR to patches? If you're providing patches to assist with patching via composer only please note that, and if you're making updates to the code please do that on the MR so the changes can be reviewed effectively :)
Comment #82
dimitriskr commentedI've rebased the branch to latest 11.x and incorporated some changes from the latest patches, so that someone else can work on this easily and to have automatic tests (which currently pass)
Leaving at NW due to some open comments by @wimleers, @phenaproxima and @smustgrave in the MR + no CR yet
Comment #83
nicoschi commentedHi there,
how can we apply the patch from merge request in Drupal 10.2.x? At this moment the plain diff doesn't apply while the patch in #77 yes
Comment #84
nicoschi commentedI'll clarify the question, the only solution to continue to use the merge request commits is the application of the procedure in Creating a patch file of a Merge Request for an older stable release?
Thanks
Comment #85
scott_euser commentedIn case an MR targeting 11x is not compatible with 10x branch, you can follow the steps here: https://www.drupal.org/docs/develop/git/using-gitlab-to-contribute-to-dr...
Comment #86
nicoschi commented@scott_euser thanks, maybe we were writing at the same time the comment, it is the same link I posted in #84.
So after that procedure should I use that as my local patch and is it useless to publish it somewhere, for example in the list of patches in this post or produce a new issue fork?
Comment #87
scott_euser commentedIf you create a new MR branch via the issue but set to the 10.x branch, you can then subsequently hide the branch to avoid confusion, but note it in a comment. Other users can then get the patch from the MR 10.x branch (issue UI let's you show hidden branches) and download to their local project. Better not to post the actual patch here or it can become confusing about what is the latest/under active development version of the work.
Comment #91
nicoschi commentedI did it a new branch and MR which applies to 10.2.x cherry picking commits in the 11.x, but maybe I did something wrong also with branch visibility
Comment #94
james.williamsI've opened MR !8484 in an attempt to get something usable with Drupal 10.3. Work from #3389447: Provide a trait to create file upload validators from file field settings is in 10.3, but conflicts with this issue's work; I'm not entirely sure whether my attempt has resolved that satisfactorily. It looks to me a bit like these two issues have gone in divergent directions; at the least because
FileValidatorSettingsTrait::getFileUploadValidators()only takes$field_definition->getSettings()as input, whereas this issue requires the whole field definition to be passed around.I had a look at !7021, but that was missing changes to ImageWidget.php which seemed wrong to me. Sorry if opening yet another MR is unhelpful! It's only really to help those of us that need to be able to work with 10.3. The ideal is to get a correct MR against 11.x still.
Comment #95
james.williamsComment #101
james.williams!MR553 (which is the one for 11.x) now shows tests passing as they should, and the test-only feature failing as expected. Since the file upload in the test was switched to use the public stream, it needed a slight adjustment to take into account user access.
Comment #102
james.williamsAh sorry, this should have been left at needs work, as per comment 82:
Comment #104
jorgik commentedRe-roll for 10.3.1
Comment #105
orakili commentedPatch from #104 didn't apply cleanly on 10.3.1. Here's an updated patch for this version back-ported from MR 553.
Comment #108
nginex commentedRe-roll for 10.5.1
Comment #109
matia.ward commentedIs there any intention on getting this re-rolled for D11.2? !553 doesn't seem to apply.
Comment #110
alexortega_98 commented#108 works for 10.6.1 still
Comment #113
grv0077 commentedTill the time MR is not merging, please use attached patch for Drupal 11.x
Comment #114
grv0077 commentedComment #115
matia.ward commentedUpdated patch failed on 11.2.10, but works on 11.3.1, so it works for me! Thank you!
Comment #116
johnatas commentedHello,
Patch #113 works on my project on Drupal 11.3.2.
Thanks,
Comment #117
smustgrave commentedMR appears to have pipeline issues that need to be resolved
Comment #118
grv0077 commentedHi smustgrave,
Resolved pipeline issue. Now, it is ready to merge.
Comment #119
smustgrave commentedGoing to leave in review for others but have concerns that the tests were updated to just pass. And I think they were also showing there’s no backwards compatibility and this could be a breaking change
Comment #121
smustgrave commentedConcern in #119 still stands but MR needs to be updated for main please.
Comment #122
smustgrave commented