Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interface for classes that handle file uploads #3514

Closed

Conversation

nicolasbrossard
Copy link
Contributor

@nicolasbrossard nicolasbrossard commented Feb 27, 2018

This PR is the result of a request to break #3476 in two. The first part (this PR) is a proposal for an interface that could be used by all classes handling files uploaded on a server. I'll leave #3476 open for now but close it once we merge this.

@driusan
Copy link
Collaborator

driusan commented Feb 27, 2018

I think your PR reference #3428 is wrong, that's @ridz1208's PR to add new database functions..

@nicolasbrossard
Copy link
Contributor Author

You are right: it should be #3476. Corrected.

Copy link
Collaborator

@driusan driusan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feedback

*/

/**
* Handles file uploads from a client to a server. The methods listed in this
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor grammatical nits/editing: The first sentence is missing a noun (should be "FilesUploadHandler handles files uploads [...]", and the second sentence has a lot of superfluous wording. It can just be something like "The interface encapsulates the usual things that happen when a set of files is uploaded to a server, namely [...]", though "the usual things" seems a little informal for a class doc, so maybe just: "The interface encapsulates the following behaviours that happen when a set of files is uploaded: [...]" would be even better.

But like I said, that's nitpicking. (Maybe @PapillonMcGill has thoughts on a good way to word it. Her reviews of the spec/README PRs generally had good technical writing suggestions.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would go with @driusan suggestions: "The interface encapsulates the following behaviours that happen when a set of files is uploaded: [...]" for the second phrase.

Suggestion for the first phrase is also good or "The FilesUploadHandler interface handles ..." but my first choice would be "This interface handles ..."

*
* 1. Validation of all uploaded files
* 2. Transfer of all files to a designated (permanent) location on the
* server.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do these need to be all files and not (potentially) some files?

Copy link
Contributor

@PapillonMcGill PapillonMcGill Feb 28, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would effectively remove the "all"

Also, if you put an ending . at the end of point 2, it would also require ending . at the end of other points

* @return array the properties for each file uploaded (one array for
* each uploaded file, see $_FILES).
*/
public function getFiles() : array;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made this comment on the other PR, but I think an iterable of PSR7 UploadedFileInterface's is better than an array of _FILES (most of the other comments on this review build on reasons why), but in addition to that, I'm not sure if this is even required, since once the transition to a PSR7/15 based router is finished, this will essentially just be a duplicate of ServerRequestInterface->getUploadedFiles() in a different format.

What I think the interface itself needs is a way to inject which files it's handling (ie either an immutable withFiles or a mutable setFiles, my preference would be the former), rather than making assumptions about the execution environment.

* @return bool true if the set of files is valid and should be processed, false
* otherwise.
*/
public function isValid() : bool;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the function should take what it's validating as a parameter rather than depending on implicit state. I wanted to suggest isFileValid(UploadedFileInterface) : bool, but potentially there might be interactions between files affecting validity, so maybe isFileSetValid(UploadedFileInterface[]) : bool (or whatever the type ends up being based on above..)

*
* @return array list of error messages for each uploaded file.
*/
public function getErrors() : array;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if process or validate is called multiple times? Does one error list get lost? And how do you know if it's a processing or validation error? At the very least, this should be getLastErrors(), but to make things more atomic maybe the validation should return an error list rather than a bool and the process should return a (potentially different) error list rather than null.

Also, this should specify if it's talking about a numeric or associative array of error messages (and if the latter, what the key is)


/**
* Main entry point for classes implementing this interface. Processes all
* uploaded files.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it required that a processAll implementation calls isValid, or is it required that a user manually call isValid before they call processAll?

(If it's the former, I don't think isValid even needs to be in this interface, the processAll function just needs to document that it must validate the files before moving them.)

*
* @return NULL.
*/
public function move(string $tmpFileName);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UploadedFileInterface would be better than a string here too, I think, since then you have more metadata than the file name to make your decisions on (and the moveTo() function that's already part of the PSR7 interface would be helpful for implementations.)


/**
* Handles the exception that was thrown when processing an upload file with a
* given temporary path.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exception? The process function doesn't say anything about exceptions.. and who's responsibility is it to call this?

* file.
* @param string $newPath new (permanent) path for the uploaded file. If
* the file could not actually be moved to this new location, the
* value of this parameter will be null.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the string type hint won't allow you to pass a null in this parameter, it needs to be the empty string.

* value of this parameter will be null.
* @param string $errorMsg the error that occured during the move operation. If
* the file was successfully moved to its new location, the value
* for this parameter will be null.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter makes me confused about the interaction/chronology between move and onFileMoveEvent. Has the file already been moved? Is it about to be moved? What is someone going to do with a string error message in this handler?

@ridz1208
Copy link
Collaborator

closed in favour of linked PR

@ridz1208 ridz1208 closed this Dec 18, 2018
@driusan
Copy link
Collaborator

driusan commented Dec 18, 2018

You forgot to link it.. closed in favour of #4181

ridz1208 pushed a commit that referenced this pull request Aug 23, 2019
…loads in LORIS (#4181)

This PR picks up on #3514 and introduces an attempt at creating a generic File Upload (Validator) class for use in LORIS file uploads. See attached issue for more details.

The newly Reactified instrument_manager is used as an example to demonstrate how this class should be used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
State: Needs work PR awaiting additional work by the author to proceed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants