-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[FrameworkBundle] Add file helper to Controller #18502
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
Conversation
|
@dfridrich thanks for sending this contribution to improve Symfony (and its associated docs too). Just a comment for your next contributions: it's always better to open an issue to propose new features without sending the PR to implement them. That allows the community to review your idea and propose changes to it. Besides, if the idea is ultimately rejected, creating a PR will make you waste your time whereas creating an issue is quick and easy. Thanks! |
|
@javiereguiluz thanks for information, I'll remember next time. |
| $response = new BinaryFileResponse($file); | ||
| $mimeType = $file->getMimeType(); | ||
| } elseif (is_string($file)) { | ||
| if ($mimeType === null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could use the MimeTypeGuesser here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Nicofuma thx, MimeTypeGuesser is now implemented (using BinaryFileResponse class)
|
I think this my PR is really very useful, what do you think @symfony/deciders? |
| /** | ||
| * Returns a BinaryFileResponse object with original or customized file name and disposition header. | ||
| * | ||
| * @param File|string $file File object, path to file or string with content to be sent as response |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be @param string|null
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@HeahDude you are right, thx
|
Besides my minor comments, I think this is a nice addition. Thanks :) |
|
@HeahDude Thanks for your feedback, I really appreciate it! I just commited fixed version of this great feature 👻 |
| } else { | ||
| throw new \InvalidArgumentException( | ||
| sprintf( | ||
| '"%s" can\'t be passed as parameter to "%s" method of "%s" class.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've no strong opinion about this either, it just seems to me (IIUC) that at this point $file as string has been transformed to a File object, so it means if you got something else and you cannot be sure it's a scalar.
One other way would be to throw an \InvalidArgumentException when not string or File at the very beginning of the method.
|
I don't think allowing to pass a string containing the file contents is a good idea. If you already have the content of the response, why storing it in a temporary file to then read back from it ? Plus this means passing a string as a first argument can mean two totally different things, which means if for example you make a typo in the name of the file you want to send you will get this name as a file instead of an error. |
|
I agree with @jvasseur. We had something similar in the YAML parser in the past which was not a good idea (we cleared things in 3.0). We should simply not support passing file contents here. |
| $mimeType = $file->getMimeType(); | ||
|
|
||
| $response->headers->set('Content-Type', $mimeType); | ||
| $disposition = $response->headers->makeDisposition($disposition, $fileName === null ? $file->getFileName() : $fileName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be better to use the setContentDisposition() of BinaryFileResponse:
$response->setContentDisposition($disposition, $fileName === null ? $file->getFileName() : $fileName);| if (!$file instanceof File) { | ||
| $file = new File($file); | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I commented after your changes, the content-type logic is already done in BinaryFileResponse, so this can be removed.
| } | ||
|
|
||
| $response = new BinaryFileResponse($file, 200, ['Content-type' => $file->getMimeType()]); | ||
| $response->setContentDisposition($disposition, $fileName === null ? $file->getFileName() : $fileName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line should be removed.
|
The method should read as follows: protected function file($file, $fileName = null, $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT)
{
$response = new BinaryFileResponse($file);
$response->setContentDisposition($disposition, null === $fileName ? $file->getFileName() : $fileName);
return $response;
} |
|
@fabpot your version doesn't work if Maybe something like this: protected function file($file, $fileName = '', $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT)
{
$response = new BinaryFileResponse($file);
$response->setContentDisposition($disposition, $fileName);
return $response;
} |
| $this->assertSame('text/x-php', $response->headers->get('content-type')); | ||
| } | ||
| $this->assertContains(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $response->headers->get('content-disposition')); | ||
| $this->assertContains(pathinfo(__FILE__, PATHINFO_BASENAME), $response->headers->get('content-disposition')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function basename is simpler than pathinfofor such thing.
|
Thank you @dfridrich. |
|
|
||
| /** | ||
| * Returns a BinaryFileResponse object with original or customized file name and disposition header. | ||
| * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be \SplFileInfo|string to be equal to BinaryFileResponse?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch, see #19115
This PR was merged into the 3.2-dev branch. Discussion ---------- [FrameworkBundle] fix argument type docblock | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #18502 (comment) | License | MIT | Doc PR | Commits ------- c4e440c [FrameworkBundle] fix argument type docblock
| * @param string $disposition Disposition of response ("attachment" is default, other type is "inline") | ||
| * | ||
| * @return BinaryFileResponse | ||
| */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesnt this new method manifest as a BC break when the subclassing controller already contains a file method?
I think it would be more "sexy" to serve files from controller easier (like
json()helper does).This Controller helper allows user to serve files to Response in these ways:
Symfony\Component\HttpFoundation\File(orSymfony\Component\HttpFoundation\UploadedFile) instancestringand specify file name (mime type will be auto recognized)Examples