7
7
8
8
namespace Magento \Framework \App \Response ;
9
9
10
+ use InvalidArgumentException ;
10
11
use Magento \Framework \App \Filesystem \DirectoryList ;
11
12
use Magento \Framework \App \Http \Context ;
13
+ use Magento \Framework \App \PageCache \NotCacheableInterface ;
12
14
use Magento \Framework \App \Request \Http as HttpRequest ;
15
+ use Magento \Framework \Exception \FileSystemException ;
13
16
use Magento \Framework \Filesystem ;
14
17
use Magento \Framework \Filesystem \Driver \File \Mime ;
15
18
use Magento \Framework \Session \Config \ConfigInterface ;
20
23
/**
21
24
* @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
22
25
*/
23
- class File extends Http
26
+ class File extends Http implements NotCacheableInterface
24
27
{
25
28
/**
26
29
* @var Http
@@ -63,6 +66,7 @@ class File extends Http
63
66
* @param Mime $mime
64
67
* @param array $fileOptions
65
68
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
69
+ * @throws FileSystemException
66
70
*/
67
71
public function __construct (
68
72
HttpRequest $ request ,
@@ -81,45 +85,36 @@ public function __construct(
81
85
$ this ->response = $ response ;
82
86
$ this ->mime = $ mime ;
83
87
$ this ->fileOptions = array_merge ($ this ->fileOptions , $ fileOptions );
88
+ if (!isset ($ this ->fileOptions ['filePath ' ])) {
89
+ throw new InvalidArgumentException ("File path is required " );
90
+ }
91
+ $ dir = $ this ->filesystem ->getDirectoryRead ($ this ->fileOptions ['directoryCode ' ]);
92
+ if (!$ dir ->isExist ($ this ->fileOptions ['filePath ' ])) {
93
+ throw new InvalidArgumentException ("File ' {$ this ->fileOptions ['filePath ' ]}' does not exists. " );
94
+ }
95
+ $ this ->setFileHeaders ();
84
96
}
85
97
86
98
/**
87
99
* @inheritDoc
88
100
*/
89
101
public function sendResponse ()
90
102
{
91
- if ($ this ->fileOptions ['filePath ' ]) {
103
+ $ this ->response ->sendHeaders ();
104
+
105
+ if (!$ this ->request ->isHead ()) {
92
106
$ dir = $ this ->filesystem ->getDirectoryWrite ($ this ->fileOptions ['directoryCode ' ]);
93
107
$ filePath = $ this ->fileOptions ['filePath ' ];
94
- $ contentType = $ this ->fileOptions ['contentType ' ]
95
- ?? $ dir ->stat ($ filePath )['mimeType ' ]
96
- ?? $ this ->mime ->getMimeType ($ dir ->getAbsolutePath ($ filePath ));
97
- $ contentLength = $ this ->fileOptions ['contentLength ' ]
98
- ?? $ dir ->stat ($ filePath )['size ' ];
99
- $ fileName = $ this ->fileOptions ['fileName ' ]
100
- ?? basename ($ filePath );
101
- $ this ->response ->setHttpResponseCode (200 );
102
- $ this ->response ->setHeader ('Content-type ' , $ contentType , true )
103
- ->setHeader ('Content-Length ' , $ contentLength )
104
- ->setHeader ('Content-Disposition ' , 'attachment; filename=" ' . $ fileName . '" ' , true )
105
- ->setHeader ('Pragma ' , 'public ' , true )
106
- ->setHeader ('Cache-Control ' , 'must-revalidate, post-check=0, pre-check=0 ' , true )
107
- ->setHeader ('Last-Modified ' , date ('r ' ), true );
108
-
109
- $ this ->response ->sendHeaders ();
110
-
111
- if (!$ this ->request ->isHead ()) {
112
- $ stream = $ dir ->openFile ($ filePath , 'r ' );
113
- while (!$ stream ->eof ()) {
114
- // phpcs:ignore Magento2.Security.LanguageConstruct.DirectOutput
115
- echo $ stream ->read (1024 );
116
- }
117
- $ stream ->close ();
118
- if ($ this ->fileOptions ['remove ' ]) {
119
- $ dir ->delete ($ filePath );
120
- }
121
- $ this ->response ->clearBody ();
108
+ $ stream = $ dir ->openFile ($ filePath , 'r ' );
109
+ while (!$ stream ->eof ()) {
110
+ // phpcs:ignore Magento2.Security.LanguageConstruct.DirectOutput
111
+ echo $ stream ->read (1024 );
112
+ }
113
+ $ stream ->close ();
114
+ if ($ this ->fileOptions ['remove ' ]) {
115
+ $ dir ->delete ($ filePath );
122
116
}
117
+ $ this ->response ->clearBody ();
123
118
}
124
119
return $ this ;
125
120
}
@@ -148,4 +143,30 @@ public function clearHeader($name)
148
143
{
149
144
return $ this ->response ->clearHeader ($ name );
150
145
}
146
+
147
+ /**
148
+ * Set appropriate headers for the file attachment
149
+ *
150
+ * @return void
151
+ * @throws \Magento\Framework\Exception\FileSystemException
152
+ */
153
+ private function setFileHeaders (): void
154
+ {
155
+ $ dir = $ this ->filesystem ->getDirectoryWrite ($ this ->fileOptions ['directoryCode ' ]);
156
+ $ filePath = $ this ->fileOptions ['filePath ' ];
157
+ $ contentType = $ this ->fileOptions ['contentType ' ]
158
+ ?? $ dir ->stat ($ filePath )['mimeType ' ]
159
+ ?? $ this ->mime ->getMimeType ($ dir ->getAbsolutePath ($ filePath ));
160
+ $ contentLength = $ this ->fileOptions ['contentLength ' ]
161
+ ?? $ dir ->stat ($ filePath )['size ' ];
162
+ $ fileName = $ this ->fileOptions ['fileName ' ]
163
+ ?? basename ($ filePath );
164
+ $ this ->response ->setHttpResponseCode (200 );
165
+ $ this ->response ->setHeader ('Content-type ' , $ contentType , true )
166
+ ->setHeader ('Content-Length ' , $ contentLength )
167
+ ->setHeader ('Content-Disposition ' , 'attachment; filename=" ' . $ fileName . '" ' , true )
168
+ ->setHeader ('Pragma ' , 'public ' , true )
169
+ ->setHeader ('Cache-Control ' , 'must-revalidate, post-check=0, pre-check=0 ' , true )
170
+ ->setHeader ('Last-Modified ' , date ('r ' ), true );
171
+ }
151
172
}
0 commit comments