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

Use Laravel UploadedFile class for requests #3417

Closed

Conversation

torkiljohnsen
Copy link

Using Symfony’s UploadedFile class has the effect that when Laravel’s Request class does convertUploadedFiles(), all files are converted to Laravel’s UploadedFile class, but with the $test set to false.

This, in turn, makes it difficult to use the class in a test, because the class then must pass the is_uploaded_file() test in UploadedFile::isValid().

This is just a proposal, I have no tests to go with the code, as this repo is missing some basic requirements for this class to even be instantiable, like Laravel's Eloquent and Symfony's HttpFoundation component. Please have a look @janhenkgerritsen.

Using Symfony’s UploadedFile has the effect that when Laravel’s Request class does convertUploadedFiles, all files are converted to Laravel’s UploadedFile class, but with the test flag set to false.

This, in turn, makes it difficult to use the class in a test, because the class then must pass the is_uploaded_file test in UploadedFile::isValid().
@janhenkgerritsen
Copy link
Contributor

Can you show me some pseudo code of a test that fails due to this problem? That way I can play around with it a bit. I think this PR will not cause any problems, but I'd like to look into it myself a bit better before I merge it.

Tests for this sort of problem should be added to the Laravel 5 sample application, but I can do that myself.

@torkiljohnsen
Copy link
Author

Sure. Here is a CEST method and the corresponding controller endpoint. This uses the REST module too obviously.

// CEST test
public function createMedia(ApiTester $i)
{
    $i->wantTo('create media');
    $i->sendPOST('media', [], ['file' => codecept_data_dir('cat1.jpg')]);
    $i->seeRecord('media', [
        'path' => public_path('images/cat1.jpg')
    ]);
}

// Controller method
public function store(Request $request)
{
    $uploadedFile = $request->file('file');
    $file = $uploadedFile->move(public_path('images'), $uploadedFile->getClientOriginalName());
    Media::create(['path' => $file->getRealPath()]);

    return response(null, 201);
}

Without my patch, this will fail, because $uploadedFile->move() will test for isValid(), which will return false, since $uploadedFile->test is set to false when Symfony UploadedFile is converted to Laravel UploadedFile. So $uploadedFile->move() will not work at all in the test.

@torkiljohnsen
Copy link
Author

To elaborate: When the POST request is made, Laravel converts files to its native UploadedFile class in Illuminate\Http\Request->convertUploadedFiles(): It calls UploadedFile::createFromBase($file);, which in turn has $test hardcoded to false, probably because there is no public getter for getting the test parameter from Symfony's UploadedFile.

@torkiljohnsen
Copy link
Author

When an instance of Laravel's UploadedFile is passed to UploadedFile::createFromBase(), it just returns the instance directly, so the test flag is kept at true.

@janhenkgerritsen
Copy link
Contributor

I created a test in the Laravel 5 sample application that reproduces your issue. The fix you propose is also correct, only you forgot to add the import for the UploadedFile class. That's why I created a new pull request #3429.

After the PR is merged I will push the test to the Laravel 5 sample application, because it will break the build if I do that right away.

Thanks for the help!

@torkiljohnsen
Copy link
Author

Ouch. Good call on the missing import and thanks for helping out :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants