Problem/Motivation

In #2940383: [META] Unify file upload logic of REST and JSON:API we are wanting to upload files directly via octet-stream and Content-Disposition header, and because it doesn't use $_POST variables we can't use Symfony UploadedFile object. However, in \Drupal\file\Upload\FileUploadHandler::handleFileUpload() we call isValid() and assume we have an instance of UploadedFile.

This is most likely due to copying existing code.

Steps to reproduce

Proposed resolution

  • Deprecate \Drupal\file\Upload\UploadedFileInterface::isValid() ::getError() and ::getErrorMessage()
  • Add an \Drupal\file\Validation\UploadedFileValidator that validates uploaded files using \Drupal\file\Validation\Constraint\UploadedFileConstraint and \Drupal\file\Validation\Constraint\UploadedFileConstraintValidator
  • Remove the checks for isValid() and throwing exceptions in FileUploadHandler::handleFileUpload()
  • Call UploadedFileValidator::validate() and check for constraint violations instead

Remaining tasks

Do it.

User interface changes

API changes

\Drupal\file\Upload\UploadedFileInterface::isValid() ::getError() and ::getErrorMessage() are deprecated
A new UploadedFileInterface::validate() method is added, that throws \Symfony\Component\HttpFoundation\File\Exception\FileException and sub-classes.

Data model changes

Release notes snippet

CommentFileSizeAuthor
#13 3375447-nr-bot.txt90 bytesneeds-review-queue-bot

Issue fork drupal-3375447

Command icon 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

kim.pepper created an issue. See original summary.

kim.pepper’s picture

Status: Active » Needs review
andypost’s picture

looks good idea!

kim.pepper’s picture

My only other thought is to not throw exceptions but to use Symfony validators some how. Not sure how this would work. 🤔

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Seems like a perfectly reasonable cleanup.

kim.pepper’s picture

Status: Reviewed & tested by the community » Needs work

Going to think about the best approach before we commit.

kim.pepper’s picture

kim.pepper’s picture

Status: Needs work » Needs review

This approach uses a symfony validator that is not coupled with TypeData. It makes use of DrupalTranslator so we still get TranslatableMarkup objects returned from the constraint violation getMessage() method.

I had a go at re-using \Symfony\Component\Validator\Constraints\File and \Symfony\Component\Validator\Constraints\FileValidator but couldn't get the messages to match up due to missing the %file param.

kim.pepper’s picture

Issue summary: View changes

Updated IS with current implementation.

kim.pepper’s picture

Title: FileUploadHandler::handleFileUpload() assumes an UploadedFile object » Create an UploadedFile validator and deprecate error checking methods on UploadedFileInterface
needs-review-queue-bot’s picture

Status: Needs review » Needs work
StatusFileSize
new90 bytes

The Needs Review Queue Bot tested this issue. It no longer applies to Drupal core. Therefore, this issue status is now "Needs work".

This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

kim.pepper’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

So reading the IS and CR can't think of a reason not to do this. Going to mark it.

kim.pepper’s picture

Priority: Normal » Critical

Blocking a critical #2940383: [META] Unify file upload logic of REST and JSON:API therefore this is also critical.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work

Looking good, left some comments on the MR about a possible extra method and some BC issues.

kim.pepper’s picture

Status: Needs work » Needs review

Added a deprecation test for the $throw arg.

All other feedback has been addressed.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

All threads have been addressed.

larowlan’s picture

Status: Reviewed & tested by the community » Needs work

Can we update the change record to add examples for how to fix the deprecation for the $throws param on handleFileUpload and how that works for calling code.

I.e pass FALSE and inspect the errors on the return instead of expecting an exception?

Left a review on the MR too

kim.pepper’s picture

Status: Needs work » Needs review

Resolved all feedback

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Appears all threads have been resolved.

wim leers’s picture

Issue tags: +blocker
larowlan’s picture

Status: Reviewed & tested by the community » Needs work

Discussed with @catch and @kim.pepper

Because there are still a few moving parts here, I think it makes sense to put this into 11 only, with a goal of it making it into 10.3 with all of the other issues that relate to it (this currently blocks 4 other issues that refactor file upload handling).

Because those 4 issues might require more changes to this, rather than lock ourselves into an API for 10.2, this gives us a chance to get the API right before 10.3

Marking as needs work to re-roll with the deprecations saying 10.3 instead of 10.2. But then I'm keen to get this into 11 and get onto the other issues.

Thanks for your understanding!

kim.pepper’s picture

Status: Needs work » Reviewed & tested by the community

Updated all deprecation messages from 10.2 to 10.3.

Moving back to RTBC.

larowlan’s picture

Can we get a second change record for the new basic validator? Thanks

kim.pepper’s picture

Done ✅

  • larowlan committed 6bd3ad84 on 11.x
    Issue #3375447 by kim.pepper, larowlan: Create an UploadedFile validator...
larowlan’s picture

Status: Reviewed & tested by the community » Fixed

Committed to 11.x and unpostponed the 4 issues.
Published the 2 CRs

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.