PluginProbe
WPIDE – File Manager & Code Editor / 3.3
WPIDE – File Manager & Code Editor v3.3
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 / FileController.php

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

313 lines 8.4 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 Exception;
6 use PhpParser\Error;
7 use WPIDE\App\App;
8 use WPIDE\App\Config\Config;
9 use WPIDE\App\Helpers\FileBackup;
10 use WPIDE\App\Helpers\ImageStateData;
11 use WPIDE\App\Helpers\PhpValidator;
12 use WPIDE\App\Kernel\Request;
13 use WPIDE\App\Kernel\Response;
14 use WPIDE\App\Services\Archiver\ArchiverInterface;
15 use WPIDE\App\Services\Auth\AuthInterface;
16 use WPIDE\App\Services\Transient\Transient;
17 use WPIDE\App\Services\Storage\Filesystem;
18 use WPIDE\App\Services\Storage\LocalFileSystem;
19 use const WPIDE\Constants\CONTENT_DIR;
20
21
22 /**
23 *
24 */
25 class FileController
26 {
27 /**
28 *
29 */
30 const SESSION_CWD = 'current_path';
31
32 /**
33 * @var Transient
34 */
35 protected $transient;
36
37 /**
38 * @var AuthInterface
39 */
40 protected $auth;
41
42 /**
43 * @var Config
44 */
45 protected $config;
46
47 /**
48 * @var Filesystem
49 */
50 protected $storage;
51
52 /**
53 * @var
54 */
55 protected $separator;
56
57 /**
58 * @param Config $config
59 * @param Transient $transient
60 * @param AuthInterface $auth
61 * @param Filesystem $storage
62 */
63 public function __construct(Config $config, Transient $transient, AuthInterface $auth, Filesystem $storage)
64 {
65 $this->transient = $transient;
66 $this->config = $config;
67 $this->auth = $auth;
68
69 $user = $this->auth->user() ?: $this->auth->getGuest();
70
71 $this->storage = $storage;
72 $this->storage->setPathPrefix($user->getHomeDir());
73
74 $this->separator = $this->storage->getSeparator();
75 }
76
77 /**
78 * @param Request $request
79 * @param Response $response
80 * @return void
81 * @throws Exception
82 */
83 public function changeDirectory(Request $request, Response $response)
84 {
85 $path = $request->input('to', $this->separator);
86
87 $this->transient->set(self::SESSION_CWD, $path);
88
89 return $response->json($this->storage->getDirectoryCollection($path));
90 }
91
92 /**
93 * @param Request $request
94 * @param Response $response
95 * @return void
96 * @throws Exception
97 */
98 public function getDirectory(Request $request, Response $response)
99 {
100 $path = $request->input('dir', $this->transient->get(self::SESSION_CWD, $this->separator));
101 $root = $request->input('root', false);
102
103 $storage = $root ? LocalFileSystem::load(CONTENT_DIR) : $this->storage;
104
105 $content = $storage->getDirectoryCollection($path);
106
107 return $response->json($content);
108 }
109
110 /**
111 * @param Request $request
112 * @param Response $response
113 * @return void
114 * @throws Exception
115 */
116 public function getDirectorySize(Request $request, Response $response)
117 {
118 $path = $request->input('dir', $this->transient->get(self::SESSION_CWD, $this->separator));
119
120 $size = $this->storage->getDirSize($path);
121
122 return $response->json($size);
123 }
124
125 /**
126 * @param Request $request
127 * @param Response $response
128 * @return void
129 */
130 public function createNew(Request $request, Response $response)
131 {
132 $type = $request->input('type', 'file');
133 $name = $request->input('name');
134 $path = $this->transient->get(self::SESSION_CWD, $this->separator);
135
136 if(empty($name)) {
137 return $response->json(sprintf(__('%s name cannot be empty!', 'wpide'), ucfirst($type)), 422);
138 }
139
140 if ($type == 'dir') {
141 $this->storage->createDir($path, $name);
142 }
143 if ($type == 'file') {
144 $this->storage->createFile($path, $name);
145 }
146
147 return $response->json(true);
148 }
149
150 /**
151 * @param Request $request
152 * @param Response $response
153 * @return void
154 */
155 public function copyItems(Request $request, Response $response)
156 {
157 $items = $request->input('items', []);
158 $destination = $request->input('destination', $this->separator);
159
160 foreach ($items as $item) {
161 if ($item->type == 'dir') {
162 $this->storage->copyDir($item->path, $destination);
163 }
164 if ($item->type == 'file') {
165 $this->storage->copyFile($item->path, $destination);
166 }
167 }
168
169 return $response->json(true);
170 }
171
172 /**
173 * @param Request $request
174 * @param Response $response
175 * @return void
176 */
177 public function moveItems(Request $request, Response $response)
178 {
179 $items = $request->input('items', []);
180 $destination = $request->input('destination', $this->separator);
181
182 foreach ($items as $item) {
183 $full_destination = trim($destination, $this->separator)
184 . $this->separator
185 . ltrim($item->name, $this->separator);
186 $this->storage->move($item->path, $full_destination);
187 }
188
189 return $response->json(true);
190 }
191
192 /**
193 * @param Request $request
194 * @param Response $response
195 * @param ArchiverInterface $archiver
196 * @return void
197 */
198 public function zipItems(Request $request, Response $response, ArchiverInterface $archiver)
199 {
200
201 return App::instance()->call([DownloadController::class, 'batchDownloadChunks'], [$request, $response, $archiver]);
202 }
203
204 /**
205 * @param Request $request
206 * @param Response $response
207 * @param ArchiverInterface $archiver
208 * @return void
209 */
210 public function unzipItem(Request $request, Response $response, ArchiverInterface $archiver)
211 {
212 $source = $request->input('item');
213 $destination = $request->input('destination', $this->separator);
214
215 $archiver->uncompress($source, $destination, $this->storage);
216
217 return $response->json(true);
218 }
219
220 /**
221 * @param Request $request
222 * @param Response $response
223 * @return void
224 */
225 public function renameItem(Request $request, Response $response)
226 {
227 $destination = $request->input('destination', $this->separator);
228 $from = $request->input('from');
229 $to = $request->input('to');
230
231 $this->storage->rename($destination, $from, $to);
232
233 return $response->json(true);
234 }
235
236 /**
237 * @param Request $request
238 * @param Response $response
239 * @return void
240 */
241 public function deleteItems(Request $request, Response $response)
242 {
243 $items = $request->input('items', []);
244
245 foreach ($items as $item) {
246 if ($item->type == 'dir' && $this->storage->fileExists($item->path)) {
247 $this->storage->deleteDir($item->path);
248 }
249 if ($item->type == 'file' && $this->storage->fileExists($item->path)) {
250 $this->storage->deleteFile($item->path);
251 }
252 }
253
254 return $response->json(true);
255 }
256
257 /**
258 * @param Request $request
259 * @param Response $response
260 * @return void
261 * @throws Exception
262 */
263 public function saveContent(Request $request, Response $response)
264 {
265
266 $item = $request->input('item');
267 $content = $request->input('content');
268
269 $dir = !empty($item->dir) ? $item->dir : $this->transient->get(self::SESSION_CWD, $this->separator);
270
271 $isImage = false;
272
273 // Check if data uri encoded image
274 if (substr($content, 0, 11) === 'data:image/') {
275
276 $content = base64_decode(substr($content, strpos($content, ',') + 1));
277 $imageState = $request->input('state');
278 $isImage = true;
279 }
280
281 if ($item->ext === 'php') {
282 try {
283 PhpValidator::validate($content);
284 } catch (Error $error) {
285 $message = "Parse error: {$error->getMessage()}\n";
286 return $response->json($message, 422);
287 }
288 }
289
290 // Backup files before saving and keep copy of modified files
291 // For PHP files, in case of a fatal error after saving a file, our custom error handler drop-in will then take care of restoring files if a backup file is found.
292 if(!FileBackup::backup($item, $content)) {
293
294 return $response->json(__('Failed file backup!', 'wpide'), 422);
295 }
296
297 if($isImage && !empty($imageState)){
298
299 if(!ImageStateData::save($item, $imageState)) {
300
301 return $response->json(__('Failed saving image state!', 'wpide'), 422);
302 }
303 }
304
305 if(!$this->storage->storeStreamFromContent($dir, $item->name, $content, true)) {
306
307 return $response->json(__('Failed saving file!', 'wpide'), 422);
308 }
309
310 return $response->json(true);
311 }
312 }
313