Skip to content
This repository was archived by the owner on Jan 29, 2020. It is now read-only.

Commit 5854462

Browse files
committed
Set the content-type and -disposition headers from constructor arguments
After thinking about this at some length, it makes sense to me (at least at this stage) to set the content-type and content-disposition headers from values supplied ($contentType and $filename values respectively) to the constructor. This, I think, will be cleaner and more maintainable.
1 parent d55873a commit 5854462

File tree

2 files changed

+65
-17
lines changed

2 files changed

+65
-17
lines changed

src/Response/DownloadResponse.php

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
*/
2727
class DownloadResponse extends Response
2828
{
29+
const DEFAULT_CONTENT_TYPE = 'application/octet-stream';
30+
const DEFAULT_DOWNLOAD_FILENAME = 'download';
31+
2932
/**
3033
* A list of header keys required to be sent with a download response
3134
*
@@ -40,36 +43,52 @@ class DownloadResponse extends Response
4043
'pragma'
4144
];
4245

46+
/**
47+
* @var string The filename to be sent with the response
48+
*/
49+
private $filename;
50+
51+
/**
52+
* @var string The content type to be sent with the response
53+
*/
54+
private $contentType;
55+
4356
/**
4457
* DownloadResponse constructor.
58+
*
4559
* @param string|StreamInterface $body String or stream for the message body.
4660
* @param int $status Integer status code for the response; 200 by default.
47-
* @param string $filename The name of the file to be downloaded
48-
* @param array $headers Array of headers to use at initialization.
49-
* @throws InvalidArgumentException if $text is neither a string or stream.
50-
* @param array $headers
51-
*/
52-
public function __construct($body, int $status = 200, string $filename = 'download', array $headers = [])
53-
{
61+
* @param string $filename The file name to be sent with the response
62+
* @param string $contentType The content type to be sent with the response
63+
* @param array $headers An array of optional headers. These cannot override those set in getDownloadHeaders */
64+
public function __construct(
65+
$body,
66+
int $status = 200,
67+
string $filename = self::DEFAULT_DOWNLOAD_FILENAME,
68+
string $contentType = self::DEFAULT_CONTENT_TYPE,
69+
array $headers = []
70+
) {
71+
$this->filename = $filename;
72+
$this->contentType = $contentType;
73+
5474
parent::__construct(
5575
$this->createBody($body),
5676
$status,
57-
$this->prepareDownloadHeaders($filename, $headers)
77+
$this->prepareDownloadHeaders($headers)
5878
);
5979
}
6080

6181
/**
6282
* Get download headers
6383
*
64-
* @param string $filename
6584
* @return array
6685
*/
67-
private function getDownloadHeaders(string $filename): array
86+
private function getDownloadHeaders(): array
6887
{
6988
$headers = [];
7089
$headers['cache-control'] = 'must-revalidate';
7190
$headers['content-description'] = 'File Transfer';
72-
$headers['content-disposition'] = sprintf('attachment; filename=%s', $filename);
91+
$headers['content-disposition'] = sprintf('attachment; filename=%s', self::DEFAULT_DOWNLOAD_FILENAME);
7392
$headers['content-transfer-encoding'] = 'Binary';
7493
$headers['content-type'] = 'application/octet-stream';
7594
$headers['expires'] = '0';
@@ -104,11 +123,16 @@ public function overridesDownloadHeaders(array $downloadHeaders, array $headers
104123
/**
105124
* Prepare download response headers
106125
*
107-
* @param string $filename
126+
* This function prepares the download response headers. It does so by:
127+
* - Merging the optional with over the default ones (the default ones cannot be overridden)
128+
* - Set the content-type and content-disposition headers from $filename and $contentType passed
129+
* to the constructor.
130+
*
108131
* @param array $headers
109132
* @return array
133+
* @throws InvalidArgumentException if an attempt is made to override a default header
110134
*/
111-
private function prepareDownloadHeaders(string $filename, array $headers = []) : array
135+
private function prepareDownloadHeaders(array $headers = []) : array
112136
{
113137
if ($this->overridesDownloadHeaders($this->downloadResponseHeaders, $headers)) {
114138
throw new InvalidArgumentException(
@@ -119,7 +143,14 @@ private function prepareDownloadHeaders(string $filename, array $headers = []) :
119143
);
120144
}
121145

122-
return array_merge($headers, $this->getDownloadHeaders($filename));
146+
return array_merge(
147+
$headers,
148+
$this->getDownloadHeaders(),
149+
[
150+
'content-disposition' => sprintf('attachment; filename=%s', $this->filename),
151+
'content-type' => $this->contentType,
152+
]
153+
);
123154
}
124155

125156
/**

test/Response/DownloadResponseTest.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,35 @@ public function testCanSendResponseWithCustomFilename()
8383
$this->assertSame('attachment; filename=valid.csv', $response->getHeaderLine('content-disposition'));
8484
}
8585

86+
public function testCanSendResponseWithCustomContentType()
87+
{
88+
$body = new Stream($this->root->url() . '/files/valid.csv');
89+
$response = new DownloadResponse($body, 200, 'valid.csv', 'text/csv');
90+
$this->assertInstanceOf(Response::class, $response);
91+
$this->assertEquals(
92+
file_get_contents($this->root->url() . '/files/valid.csv'),
93+
(string) $response->getBody()
94+
);
95+
$this->assertHasValidResponseHeaders($response, 'valid.csv', 'text/csv');
96+
$this->assertSame('attachment; filename=valid.csv', $response->getHeaderLine('content-disposition'));
97+
}
98+
8699
/**
87100
* @param DownloadResponse $response
88101
* @param string $filename
102+
* @param string $contentType
89103
*/
90-
private function assertHasValidResponseHeaders(DownloadResponse $response, $filename = 'download'): void
91-
{
104+
private function assertHasValidResponseHeaders(
105+
DownloadResponse $response,
106+
$filename = 'download',
107+
$contentType = 'application/octet-stream'
108+
) : void {
92109
$requiredHeaders = [
93110
'cache-control' => 'must-revalidate',
94111
'content-description' => 'File Transfer',
95112
'content-disposition' => sprintf('attachment; filename=%s', $filename),
96113
'content-transfer-encoding' => 'Binary',
97-
'content-type' => 'application/octet-stream',
114+
'content-type' => $contentType,
98115
'expires' => '0',
99116
'pragma' => 'Public'
100117
];

0 commit comments

Comments
 (0)