FileManager::getActionsFileManager()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 0
1
<?php
2
3
/**
4
 * @package File manager
5
 * @author Iurii Makukh <[email protected]>
6
 * @copyright Copyright (c) 2017, Iurii Makukh <[email protected]>
7
 * @license https://www.gnu.org/licenses/gpl-3.0.en.html GPL-3.0+
8
 */
9
10
namespace gplcart\modules\file_manager\controllers;
11
12
use gplcart\core\controllers\backend\Controller;
13
use gplcart\modules\file_manager\models\Command;
14
use gplcart\modules\file_manager\models\Scanner;
15
use SplFileInfo;
16
17
/**
18
 * Handles incoming requests and outputs data related to File manager module
19
 */
20
class FileManager extends Controller
21
{
22
23
    /**
24
     * The current file manager command
25
     * @var array
26
     */
27
    protected $data_command;
28
29
    /**
30
     * The current absolute path
31
     * @var string
32
     */
33
    protected $data_absolute_path;
34
35
    /**
36
     * The current relative path
37
     * @var string
38
     */
39
    protected $data_path;
40
41
    /**
42
     * The current SplFileInfo file object
43
     * @var \SplFileInfo $data_file
44
     */
45
    protected $data_file;
46
47
    /**
48
     * An array of SplFileInfo objects of selected files
49
     * @var array
50
     */
51
    protected $data_selected = array();
52
53
    /**
54
     * The current access
55
     * @var bool
56
     */
57
    protected $data_access = true;
58
59
    /**
60
     * Command model class instance
61
     * @var \gplcart\modules\file_manager\models\Command $command
62
     */
63
    protected $command;
64
65
    /**
66
     * Scanner model class instance
67
     * @var \gplcart\modules\file_manager\models\Scanner $scanner
68
     */
69
    protected $scanner;
70
71
    /**
72
     * FileManager constructor.
73
     * @param Command $command
74
     * @param Scanner $scanner
75
     */
76
    public function __construct(Command $command, Scanner $scanner)
77
    {
78
        parent::__construct();
79
80
        $this->command = $command;
81
        $this->scanner = $scanner;
82
    }
83
84
    /**
85
     * Sets the current working file path
86
     */
87
    protected function setFileFileManager()
88
    {
89
        $initial_path = $this->scanner->getInitialPath();
90
        $initial_absolute_path = $this->scanner->getInitialPath(true);
91
        $this->data_path = $this->getQuery('path', $initial_path);
92
93
        if (empty($this->data_path)) {
94
            $this->data_path = $initial_path;
95
        }
96
97
        $this->data_absolute_path = gplcart_file_absolute($this->data_path);
98
99
        if (gplcart_path_starts($this->data_absolute_path, $initial_absolute_path) && file_exists($this->data_absolute_path)) {
100
            $this->data_access = true;
101
            $this->data_file = new SplFileInfo($this->data_absolute_path);
102
        } else {
103
            $this->data_access = false;
104
        }
105
106
        $this->setSelectedFileManager();
107
    }
108
109
    /**
110
     * Prepare and set selected files
111
     */
112
    protected function setSelectedFileManager()
113
    {
114
        foreach ($this->session->get('file_manager_selected', array()) as $path) {
115
            $file = new SplFileInfo(gplcart_file_absolute($path));
116
            if (is_object($file)) {
117
                $this->data_selected[$path] = $file;
118
            }
119
        }
120
    }
121
122
    /**
123
     * Displays the file manager page
124
     */
125
    public function viewFileManager()
126
    {
127
        $this->setFileFileManager();
128
        $this->setAccessFileManager();
129
        $this->setDataMessagesFileManager();
130
131
        $this->setData('access', $this->data_access);
132
        $this->setData('command', $this->data_command);
133
        $this->setData('selected', $this->data_selected);
134
        $this->setData('tabs', $this->getTabsFileManager());
135
        $this->setData('actions', $this->getActionsFileManager());
136
        $this->setData('process_selected', $this->isQuery('selected'));
137
138
        $this->submitFileManager();
139
        $this->setDataContendFileManager();
140
141
        $rendered = $this->render('file_manager|filemanager', $this->data);
142
143
        if ($this->isQuery('output')) {
144
            $this->response->outputHtml($rendered);
145
        }
146
147
        $this->setJsFileManager();
148
        $this->setCssFileManager();
149
150
        $this->setTitleFileManager();
151
        $this->setBreadcrumbFileManager();
152
153
        $this->setData('rendered_filemanager', $rendered);
154
        $this->outputViewFileManager();
155
    }
156
157
    /**
158
     * Sets rendered HTML for the current command
159
     */
160
    protected function setDataContendFileManager()
161
    {
162
        if ($this->data_access) {
163
164
            $data = $this->command->getView($this->data_command, array($this->data_file, $this));
165
166
            if (is_string($data)) {
167
                $this->setMessageFileManager($data, 'warning');
168
            } else {
169
170
                settype($data, 'array');
171
172
                $template_data = reset($data);
173
                $template = key($data);
174
                $template_data['file'] = $this->data_file;
175
                $template_data['breadcrumbs'] = $this->getPathBreadcrumbsFileManager();
176
                $rendered = $this->render($template, array_merge($template_data, $this->data));
177
178
                $this->setData('content', $rendered);
179
            }
180
        }
181
    }
182
183
    /**
184
     * Sets messages
185
     */
186
    protected function setDataMessagesFileManager()
187
    {
188
        $existing_messages = $this->getData('messages', array());
189
        $session_messages = (array) $this->session->getMessage(null, 'file_manager_messages');
190
        $messages = array_merge_recursive($session_messages, $existing_messages);
191
        $this->setData('messages', $messages);
192
    }
193
194
    /**
195
     * Sets CSS files
196
     */
197
    protected function setCssFileManager()
198
    {
199
        $this->setCss('system/modules/file_manager/css/common.css');
200
    }
201
202
    /**
203
     * Sets JS files
204
     */
205
    protected function setJsFileManager()
206
    {
207
        $this->setJsSettings('file_manager', array('upload_limit' => ini_get('max_file_uploads')));
208
        $this->setJs('system/modules/file_manager/js/common.js');
209
    }
210
211
    /**
212
     * Sets access to the current path
213
     * @return bool
214
     */
215
    protected function setAccessFileManager()
216
    {
217
        $path_from_query = $this->getQuery('cmd', 'list');
218
        $this->data_command = $this->command->get($path_from_query);
219
220
        if (empty($this->data_command['command_id'])) {
221
            return $this->data_access = false;
222
        }
223
224
        if (!$this->access("module_file_manager_{$this->data_command['command_id']}")) {
225
            return $this->data_access = false;
226
        }
227
228
        if (!empty($this->data_selected) && $this->isQuery('selected')) {
229
            return $this->data_access = true;
230
        }
231
232
        if (!$this->command->isAllowed($this->data_command, $this->data_file)) {
233
            return $this->data_access = false;
234
        }
235
236
        if ($this->accessPathAccessFileManager($this->data_path)) {
237
            return $this->data_access = true;
238
        }
239
240
        return $this->data_access = $this->access('module_file_manager');
241
    }
242
243
    /**
244
     * Whether the current user has access to the file
245
     * @param string $path
246
     * @return boolean
247
     */
248
    protected function accessPathAccessFileManager($path)
249
    {
250
        $role_id = $this->getUser('role_id');
251
        $settings = $this->module->getSettings('file_manager');
252
253
        if (empty($settings['access'][$role_id])) {
254
            return true;
255
        }
256
257
        foreach ($settings['access'][$role_id] as $pattern) {
258
            if (gplcart_path_match($path, $pattern)) {
259
                return true;
260
            }
261
        }
262
263
        return false;
264
    }
265
266
    /**
267
     * Returns an array of path breadcrumbs
268
     * @return array
269
     */
270
    protected function getPathBreadcrumbsFileManager()
271
    {
272
        $initial_path = $this->scanner->getInitialPath();
273
        $breadcrumbs = array(array('text' => $this->text('Home'), 'path' => $initial_path));
274
275
        $path = '';
276
277
        foreach (explode('/', $this->data_path) as $folder) {
278
            $path .= "$folder/";
279
            $trimmed_path = trim($path, '/');
280
            if ($trimmed_path !== $initial_path && $this->accessPathAccessFileManager($trimmed_path)) {
281
                $breadcrumbs[] = array('text' => $folder, 'path' => $trimmed_path);
282
            }
283
        }
284
285
        $breadcrumbs[count($breadcrumbs) - 1]['path'] = null;
286
        return $breadcrumbs;
287
    }
288
289
    /**
290
     * Sets file manager messages
291
     * @param string $message
292
     * @param string $severity
293
     * @param bool $once
294
     */
295
    protected function setMessageFileManager($message, $severity, $once = false)
296
    {
297
        if ($once) {
298
            $this->session->setMessage($message, $severity, 'file_manager_messages');
299
        } else {
300
            $messages = $this->getData("messages.$severity", array());
301
            $messages[] = $message;
302
            $this->setData("messages.$severity", $messages);
303
        }
304
    }
305
306
    /**
307
     * Handles a submitted data
308
     */
309
    protected function submitFileManager()
310
    {
311
        if ($this->data_access) {
312
            if ($this->isPosted('process_selected')) {
313
                $this->submitSelectedFileManager();
314
            } else if ($this->isPosted('submit') && $this->validateFileManager()) {
315
                $this->submitCommandFileManager();
316
            }
317
        }
318
    }
319
320
    /**
321
     * Handles submitted selected items
322
     */
323
    protected function submitSelectedFileManager()
324
    {
325
        $command_id = $this->getPosted('command_id');
326
        $selected = $this->getPosted('selected', array(), false, 'array');
327
328
        if ($command_id && $selected) {
329
            $limit = 100; // Max number of items to keep in the session
330
            $save = array_slice(array_unique($selected), 0, $limit);
331
            $this->session->set('file_manager_selected', $save);
332
            $query = array('cmd' => $command_id, 'path' => $this->data_path, 'selected' => true);
333
            $this->url->redirect('', $query);
334
        }
335
336
        $this->redirect();
337
    }
338
339
    /**
340
     * Process the current command
341
     */
342
    protected function submitCommandFileManager()
343
    {
344
        $result = $this->command->submit($this->data_command, array($this));
345
        $this->setMessageFileManager($result['message'], $result['severity'], true);
346
        $this->session->delete('file_manager_selected');
347
        $this->redirect($result['redirect']);
348
    }
349
350
    /**
351
     * Validates a submitted data
352
     * @return bool
353
     */
354
    protected function validateFileManager()
355
    {
356
        $selected = $this->isQuery('selected');
357
        $files = $selected ? $this->data_selected : array($this->data_file);
358
359
        $this->setSubmitted('filemanager');
360
        $this->setSubmitted('files', $files);
361
        $this->setSubmitted('command', $this->data_command);
362
363
        $this->validateComponent("file_manager_{$this->data_command['command_id']}");
364
        return !$this->hasErrors(false);
365
    }
366
367
    /**
368
     * Returns an array of allowed tabs for the current command
369
     * @return array
370
     */
371
    protected function getTabsFileManager()
372
    {
373
        $commands = $this->command->getAllowed($this->data_file);
374
375
        if (!empty($this->data_selected) && $this->isQuery('selected')) {
376
            $commands[$this->data_command['command_id']] = $this->data_command;
377
        }
378
379
        $tabs = array();
380
        foreach ($commands as $command_id => $command) {
381
382
            if (!isset($command['tab']) || !$this->access("module_file_manager_$command_id")) {
383
                continue;
384
            }
385
386
            $tabs[$command['tab']] = array(
387
                'text' => $this->text($command['tab']),
388
                'url' => $this->url('', array('path' => $this->data_path, 'cmd' => $command_id)),
389
            );
390
        }
391
392
        return $tabs;
393
    }
394
395
    /**
396
     * Returns an array of commands that support multiple selection
397
     * @return array
398
     */
399
    protected function getActionsFileManager()
400
    {
401
        $commands = $this->command->getHandlers();
402
403
        foreach ($commands as $command_id => $command) {
404
            if (empty($command['multiple'])) {
405
                unset($commands[$command_id]);
406
            }
407
        }
408
409
        return $commands;
410
    }
411
412
    /**
413
     * Sets titles on the file manager page
414
     */
415
    protected function setTitleFileManager()
416
    {
417
        $this->setTitle($this->text('File manager'));
418
    }
419
420
    /**
421
     * Sets breadcrumbs on the file manager page
422
     */
423
    protected function setBreadcrumbFileManager()
424
    {
425
        $breadcrumbs = array();
426
427
        $breadcrumbs[] = array(
428
            'url' => $this->url('admin'),
429
            'text' => $this->text('Dashboard')
430
        );
431
432
        $breadcrumbs[] = array(
433
            'url' => $this->url('admin/tool'),
434
            'text' => $this->text('Tools')
435
        );
436
437
        $this->setBreadcrumbs($breadcrumbs);
438
    }
439
440
    /**
441
     * Render and display the file manager page
442
     */
443
    protected function outputViewFileManager()
444
    {
445
        $this->output('file_manager|layout');
446
    }
447
448
}
449