PluginProbe
WPIDE – File Manager & Code Editor / trunk
WPIDE – File Manager & Code Editor vtrunk
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 trunk, at App/Controllers/FileManager/FileController.php

320 lines 8.6 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\WP_PATH;
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 $filter = $request->enumInput('filter', ['image']);
103
104 if($root) {
105 $storage = LocalFileSystem::load(WP_PATH);
106 }else{
107 $storage = $this->storage;
108 }
109
110 $content = $storage->getDirectoryCollection($path, false, $filter);
111
112 return $response->json($content);
113 }
114
115 /**
116 * @param Request $request
117 * @param Response $response
118 * @return void
119 * @throws Exception
120 */
121 public function getDirectorySize(Request $request, Response $response)
122 {
123 $path = $request->input('dir', $this->transient->get(self::SESSION_CWD, $this->separator));
124
125 $size = $this->storage->getDirSize($path);
126
127 return $response->json($size);
128 }
129
130 /**
131 * @param Request $request
132 * @param Response $response
133 * @return void
134 */
135 public function createNew(Request $request, Response $response)
136 {
137 $type = $request->input('type', 'file');
138 $name = $request->input('name');
139 $path = $request->input('destination', $this->transient->get(self::SESSION_CWD, $this->separator));
140
141 if(empty($name)) {
142 return $response->json(sprintf(__('%s name cannot be empty!', 'wpide'), ucfirst($type)), 422);
143 }
144
145 if ($type == 'dir') {
146 $this->storage->createDir($path, $name);
147 }
148 if ($type == 'file') {
149 $this->storage->createFile($path, $name);
150 }
151
152 return $response->json(true);
153 }
154
155 /**
156 * @param Request $request
157 * @param Response $response
158 * @return void
159 */
160 public function copyItems(Request $request, Response $response)
161 {
162 $items = $request->input('items', []);
163 $destination = $request->input('destination', $this->separator);
164
165 foreach ($items as $item) {
166 if ($item->type == 'dir') {
167 $this->storage->copyDir($item->path, $destination);
168 }
169 if ($item->type == 'file') {
170 $this->storage->copyFile($item->path, $destination);
171 }
172 }
173
174 return $response->json(true);
175 }
176
177 /**
178 * @param Request $request
179 * @param Response $response
180 * @return void
181 */
182 public function moveItems(Request $request, Response $response)
183 {
184 $items = $request->input('items', []);
185 $destination = $request->input('destination', $this->separator);
186
187 foreach ($items as $item) {
188 $full_destination = trim($destination, $this->separator)
189 . $this->separator
190 . ltrim($item->name, $this->separator);
191 $this->storage->move($item->path, $full_destination);
192 }
193
194 return $response->json(true);
195 }
196
197 /**
198 * @param Request $request
199 * @param Response $response
200 * @param ArchiverInterface $archiver
201 * @return void
202 */
203 public function zipItems(Request $request, Response $response, ArchiverInterface $archiver)
204 {
205
206 return App::instance()->call([DownloadController::class, 'batchDownloadChunks'], [$request, $response, $archiver]);
207 }
208
209 /**
210 * @param Request $request
211 * @param Response $response
212 * @param ArchiverInterface $archiver
213 * @return void
214 */
215 public function unzipItem(Request $request, Response $response, ArchiverInterface $archiver)
216 {
217 $source = $request->input('item');
218 $destination = $request->input('destination', $this->separator);
219 $archiver->uncompress($source, $destination, $this->storage);
220
221 return $response->json(true);
222 }
223
224 /**
225 * @param Request $request
226 * @param Response $response
227 * @return void
228 */
229 public function renameItem(Request $request, Response $response)
230 {
231 $destination = $request->input('destination', $this->separator);
232 $from = $request->input('from');
233 $to = $request->input('to');
234
235 $this->storage->rename($destination, $from, $to);
236
237 return $response->json(true);
238 }
239
240 /**
241 * @param Request $request
242 * @param Response $response
243 * @return void
244 */
245 public function deleteItems(Request $request, Response $response)
246 {
247 $items = $request->input('items', []);
248
249 foreach ($items as $item) {
250 if ($item->type == 'dir' && $this->storage->fileExists($item->path)) {
251 $this->storage->deleteDir($item->path);
252 }
253 if ($item->type == 'file' && $this->storage->fileExists($item->path)) {
254 $this->storage->deleteFile($item->path);
255 }
256 }
257
258 return $response->json(true);
259 }
260
261 /**
262 * @param Request $request
263 * @param Response $response
264 * @return void
265 * @throws Exception
266 */
267 public function saveContent(Request $request, Response $response)
268 {
269
270 $item = $request->input('item');
271 $content = $request->input('content');
272
273 $dir = !empty($item->dir) ? $item->dir : $this->transient->get(self::SESSION_CWD, $this->separator);
274
275 $isImage = false;
276
277 // Check if data uri encoded image
278 if (substr($content, 0, 11) === 'data:image/') {
279
280 $content = base64_decode(substr($content, strpos($content, ',') + 1));
281 $imageState = $request->input('state');
282 $isImage = true;
283 }
284
285 if ($item->ext === 'php') {
286 try {
287 PhpValidator::validate($content);
288 } catch (Error |Exception $error) {
289
290 $message = "Parse error: {$error->getMessage()}\n";
291 return $response->json($message, 422);
292 }
293 }
294
295 // Backup files before saving and keep copy of modified files
296 // 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.
297 if(!FileBackup::backup($item, $content)) {
298
299 return $response->json(__('Failed file backup!', 'wpide'), 422);
300 }
301
302 if($isImage && !empty($imageState)){
303
304 if(!ImageStateData::save($item, $imageState)) {
305
306 return $response->json(__('Failed saving image state!', 'wpide'), 422);
307 }
308 }
309
310 if(!$this->storage->storeStreamFromContent($dir, $item->name, $content, true)) {
311
312 return $response->json(__('Failed saving file!', 'wpide'), 422);
313 }
314
315 return $response->json([
316 'success' => true
317 ]);
318 }
319 }
320