PluginProbe
WPIDE – File Manager & Code Editor / 3.1
WPIDE – File Manager & Code Editor v3.1
3.5.8 3.5.7 2.0.14 2.0.15 2.0.16 2.0.2 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1 2.2 2.3 2.3.1 2.3.2 2.4.0 2.5 2.6 3.0 3.1 3.2 3.3 3.4 All 54 releases
wpide / App / Controllers / FileManager / DownloadController.php

DownloadController.php in WPIDE – File Manager & Code Editor 3.1, at App/Controllers/FileManager/DownloadController.php

283 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPIDE\App\Controllers\FileManager;
4
5 use WPIDE\App\Config\Config;
6 use WPIDE\App\Helpers\ImageStateData;
7 use WPIDE\App\Kernel\Request;
8 use WPIDE\App\Kernel\Response;
9 use WPIDE\App\Kernel\StreamedResponse;
10 use WPIDE\App\Services\Archiver\ArchiverInterface;
11 use WPIDE\App\Services\Auth\AuthInterface;
12 use WPIDE\App\Services\Session\SessionStorageInterface as Session;
13 use WPIDE\App\Services\Storage\Filesystem;
14 use WPIDE\App\Services\Tmpfs\TmpfsInterface;
15 use Symfony\Component\HttpFoundation\HeaderUtils;
16 use Symfony\Component\Mime\MimeTypes;
17
18 /**
19 *
20 */
21 class DownloadController
22 {
23 /**
24 * @var AuthInterface
25 */
26 protected $auth;
27
28 /**
29 * @var Mixed
30 */
31 protected $user;
32
33 /**
34 * @var Session
35 */
36 protected $session;
37
38 /**
39 * @var Config
40 */
41 protected $config;
42
43 /**
44 * @var Filesystem
45 */
46 protected $storage;
47
48 /**
49 * @param Config $config
50 * @param Session $session
51 * @param AuthInterface $auth
52 * @param Filesystem $storage
53 */
54 public function __construct(Config $config, Session $session, AuthInterface $auth, Filesystem $storage)
55 {
56 $this->session = $session;
57 $this->config = $config;
58 $this->auth = $auth;
59
60 $this->user = $this->auth->user() ?: $this->auth->getGuest();
61
62 $this->storage = $storage;
63 $this->storage->setPathPrefix($this->user->getHomeDir());
64 }
65
66 /**
67 * @param Request $request
68 * @param Response $response
69 * @param StreamedResponse $streamedResponse
70 * @return void
71 */
72 public function download(Request $request, Response $response, StreamedResponse $streamedResponse)
73 {
74
75 $path = (string) base64_decode($request->input('path'));
76
77 if(!$this->storage->fileExists($path)) {
78 return $response->json(__('Requested file does not exist', 'wpide'), 404);
79 }
80
81 try {
82 $file = $this->storage->readStream($path);
83 } catch (\Exception $e) {
84 return $response->redirect('/');
85 }
86
87 $this->downloadFile($file, $request, $streamedResponse);
88 }
89
90 /**
91 * @param $file array
92 * @param Request $request
93 * @param StreamedResponse $streamedResponse
94 * @return void
95 */
96 public function downloadFile(array $file, Request $request, StreamedResponse $streamedResponse)
97 {
98
99 $streamedResponse->setCallback(function () use ($file) {
100 // @codeCoverageIgnoreStart
101 set_time_limit(0);
102 if ($file['stream']) {
103 while (! feof($file['stream'])) {
104 echo fread($file['stream'], 1024 * 8);
105 ob_flush();
106 flush();
107 }
108 fclose($file['stream']);
109 }
110 // @codeCoverageIgnoreEnd
111 });
112
113 $disposition = HeaderUtils::DISPOSITION_ATTACHMENT;
114 $extension = pathinfo($file['filename'], PATHINFO_EXTENSION);
115 $mimes = (new MimeTypes())->getMimeTypes($extension);
116 $contentType = !empty($mimes) ? $mimes[0] : 'application/octet-stream';
117
118 $download_inline = ['pdf'];
119 if (in_array($extension, $download_inline) || in_array('*', $download_inline)) {
120 $disposition = HeaderUtils::DISPOSITION_INLINE;
121 }
122
123 $contentDisposition = HeaderUtils::makeDisposition($disposition, $file['filename'], 'file');
124
125 $streamedResponse->headers->set(
126 'Content-Disposition',
127 $contentDisposition
128 );
129 $streamedResponse->headers->set(
130 'Content-Type',
131 $contentType
132 );
133 $streamedResponse->headers->set(
134 'Content-Transfer-Encoding',
135 'binary'
136 );
137 if (isset($file['filesize'])) {
138 $streamedResponse->headers->set(
139 'Content-Length',
140 $file['filesize']
141 );
142 }
143 // @codeCoverageIgnoreStart
144 if (defined('WP_DEBUG') && WP_DEBUG) {
145 $streamedResponse->headers->set(
146 'Access-Control-Allow-Origin',
147 $request->headers->get('Origin')
148 );
149 $streamedResponse->headers->set(
150 'Access-Control-Allow-Credentials',
151 'true'
152 );
153 }
154 // @codeCoverageIgnoreEnd
155
156 // close session, so we can continue streaming, note: dev is single-threaded
157 $this->session->save();
158
159 $streamedResponse->send();
160 }
161
162 /**
163 * @param Request $request
164 * @param Response $response
165 * @param ArchiverInterface $archiver
166 * @return void
167 */
168 public function batchDownloadChunks(Request $request, Response $response, ArchiverInterface $archiver)
169 {
170 $items = $request->input('items', []);
171 $recursive = (bool) $request->input('recursive', false);
172 $zipaction = $request->input('zipaction', 'create');
173
174 $destination = $request->input('destination', $this->separator);
175 $name = $request->input('name', $this->config->get('file.default_archive_name'));
176
177 if($zipaction === 'create') {
178 $uniqid = $archiver->createArchive($this->storage);
179 }else {
180 $uniqid = $request->input('uniqid');
181 $archiver->setArchive($this->storage, $uniqid);
182 }
183
184 // close session
185 $this->session->save();
186
187 foreach ($items as $item) {
188 if ($item->type == 'dir') {
189 if($recursive) {
190 $archiver->addDirectoryFromStorage($item->path, $destination);
191 }else{
192 $archiver->addEmptyDirectory($item->path, $destination);
193 }
194 }
195 if ($item->type == 'file') {
196 $archiver->addFileFromStorage($item->path, $destination);
197 }
198 }
199
200 if($zipaction === 'store') {
201
202 $archiver->storeArchive($destination, $name);
203
204 }else{
205
206 $archiver->closeArchive();
207 }
208
209 return $response->json(['uniqid' => $uniqid]);
210 }
211
212 /**
213 * @param Request $request
214 * @param StreamedResponse $streamedResponse
215 * @param TmpfsInterface $tmpfs
216 * @return void
217 */
218 public function batchDownloadStart(Request $request, StreamedResponse $streamedResponse, TmpfsInterface $tmpfs)
219 {
220
221
222 $uniqid = (string) preg_replace('/[^0-9a-zA-Z_]/', '', (string) $request->input('uniqid'));
223 $file = $tmpfs->readStream($uniqid);
224
225 $streamedResponse->setCallback(function () use ($file, $tmpfs, $uniqid) {
226 // @codeCoverageIgnoreStart
227 set_time_limit(0);
228 if ($file['stream']) {
229 while (! feof($file['stream'])) {
230 echo fread($file['stream'], 1024 * 8);
231 ob_flush();
232 flush();
233 }
234 fclose($file['stream']);
235 }
236 $tmpfs->remove($uniqid);
237 // @codeCoverageIgnoreEnd
238 });
239
240 $streamedResponse->headers->set(
241 'Content-Disposition',
242 HeaderUtils::makeDisposition(
243 HeaderUtils::DISPOSITION_ATTACHMENT,
244 $this->config->get('file.default_archive_name'),
245 'archive.zip'
246 )
247 );
248 $streamedResponse->headers->set(
249 'Content-Type',
250 'application/octet-stream'
251 );
252 $streamedResponse->headers->set(
253 'Content-Transfer-Encoding',
254 'binary'
255 );
256 if (isset($file['filesize'])) {
257 $streamedResponse->headers->set(
258 'Content-Length',
259 $file['filesize']
260 );
261 }
262 // close session, so we can continue streaming, note: dev is single-threaded
263 $this->session->save();
264
265 $streamedResponse->send();
266 }
267
268 /**
269 * @param Request $request
270 * @param Response $response
271 * @param TmpfsInterface $tmpfs
272 * @return void
273 */
274 public function batchDownloadCancelled(Request $request, Response $response, TmpfsInterface $tmpfs)
275 {
276
277 $uniqid = (string) preg_replace('/[^0-9a-zA-Z_]/', '', (string) $request->input('uniqid'));
278 $tmpfs->remove($uniqid);
279
280 return $response->json('Deleted');
281 }
282 }
283