Completed
Push — master ( 4c3f4f...d9f8b0 )
by Julito
10:54
created

CourseDriver::getCourseDocumentRelativeWebPath()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 9
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CoreBundle\Component\Editor\Driver;
5
6
use Chamilo\CoreBundle\Framework\Container;
7
use Symfony\Component\HttpFoundation\File\UploadedFile;
8
9
/**
10
 * Class CourseDriver.
11
 *
12
 * @package Chamilo\CoreBundle\Component\Editor\Driver
13
 */
14
class CourseDriver extends Driver implements DriverInterface
15
{
16
    public $name = 'CourseDriver';
17
    public $visibleFiles = [];
18
    private $coursePath;
19
20
    /**
21
     * Setups the folder.
22
     */
23
    public function setup()
24
    {
25
        $userId = api_get_user_id();
26
        $userInfo = api_get_user_info();
27
        $sessionId = api_get_session_id();
28
        $course = $this->connector->course;
29
30
        if (!empty($course)) {
31
            $coursePath = api_get_path(SYS_COURSE_PATH);
32
            $courseDir = $course->getDirectory().'/document';
33
            $baseDir = $coursePath.$courseDir;
34
            $this->coursePath = $baseDir;
35
            $courseInfo = $this->getCourseInfoArray();
36
37
            // Creates shared folder
38
            if (!file_exists($baseDir.'/shared_folder')) {
39
                $title = get_lang('UserFolders');
40
                $folderName = '/shared_folder';
41
                $visibility = 0;
42
                create_unexisting_directory(
43
                    $courseInfo,
44
                    $userId,
45
                    $sessionId,
46
                    0,
47
                    null,
48
                    $baseDir,
49
                    $folderName,
50
                    $title,
51
                    $visibility
52
                );
53
            }
54
55
            // Creates user-course folder
56
            if (!file_exists($baseDir.'/shared_folder/sf_user_'.$userId)) {
57
                $title = $userInfo['complete_name'];
58
                $folderName = '/shared_folder/sf_user_'.$userId;
59
                $visibility = 1;
60
                create_unexisting_directory(
61
                    $courseInfo,
62
                    $userId,
63
                    $sessionId,
64
                    0,
65
                    null,
66
                    $baseDir,
67
                    $folderName,
68
                    $title,
69
                    $visibility
70
                );
71
            }
72
        }
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78
    public function getConfiguration()
79
    {
80
        if ($this->connector->course && $this->allow()) {
81
            $courseCode = $this->connector->course->getCode();
82
            $alias = $courseCode.' '.get_lang('Documents');
83
            $userId = $this->connector->user->getId();
84
85
            $config = [
86
                'driver' => 'CourseDriver',
87
                'path' => $this->getCourseDocumentSysPath(),
88
                'URL' => $this->getCourseDocumentRelativeWebPath(),
89
                'accessControl' => [$this, 'access'],
90
                'alias' => $alias,
91
                'attributes' => [
92
                    // Hide shared_folder
93
                    [
94
                        'pattern' => '/shared_folder/',
95
                        'read' => false,
96
                        'write' => false,
97
                        'hidden' => true,
98
                        'locked' => false,
99
                    ],
100
                    [
101
                        'pattern' => '/^\/index.html$/',
102
                        'read' => false,
103
                        'write' => false,
104
                        'hidden' => true,
105
                        'locked' => false,
106
                    ],
107
                ],
108
            ];
109
110
            // admin/teachers can create dirs from ckeditor
111
            if ($this->allowToEdit()) {
112
                $config['attributes'][] = [
113
                    'pattern' => '/^\/learning_path$/', // block delete learning_path
114
                    'read' => true,
115
                    'write' => false,
116
                    'hidden' => false,
117
                    'locked' => true,
118
                ];
119
                $config['attributes'][] = [
120
                    'pattern' => '/learning_path\/(.*)/', // allow edit/delete inside learning_path
121
                    'read' => true,
122
                    'write' => true,
123
                    'hidden' => false,
124
                    'locked' => false,
125
                ];
126
127
                $defaultDisabled = $this->connector->getDefaultDriverSettings()['disabled'];
128
                $defaultDisabled = array_flip($defaultDisabled);
129
                unset($defaultDisabled['mkdir']);
130
                $defaultDisabled = array_flip($defaultDisabled);
131
                $config['disabled'] = $defaultDisabled;
132
            } else {
133
                $protectedFolders = \DocumentManager::getProtectedFolderFromStudent();
134
                foreach ($protectedFolders as $folder) {
135
                    $config['attributes'][] = [
136
                        'pattern' => $folder.'/',
137
                        'read' => false,
138
                        'write' => false,
139
                        'hidden' => true,
140
                        'locked' => false,
141
                    ];
142
                }
143
            }
144
145
            $courseInfo = $this->getCourseInfoArray();
146
147
            $foldersToHide = \DocumentManager::get_all_document_folders(
148
                $courseInfo,
149
                null,
150
                false,
151
                true
152
            );
153
154
            // Teachers can see all files and folders see #1425
155
            if ($this->allowToEdit()) {
156
                $foldersToHide = [];
157
            }
158
159
            if (!empty($foldersToHide)) {
160
                foreach ($foldersToHide as $folder) {
161
                    $config['attributes'][] = [
162
                        'pattern' => '!'.$folder.'!',
163
                        'read' => false,
164
                        'write' => false,
165
                        'hidden' => true,
166
                        'locked' => false,
167
                    ];
168
                }
169
            }
170
171
            // Hide all groups folders
172
            $config['attributes'][] = [
173
                'pattern' => '!_groupdocs_!',
174
                'read' => false,
175
                'write' => false,
176
                'hidden' => true,
177
                'locked' => false,
178
            ];
179
180
            // Allow only the groups I have access
181
            $allGroups = \GroupManager::getAllGroupPerUserSubscription($userId);
182
            if (!empty($allGroups)) {
183
                foreach ($allGroups as $groupInfo) {
184
                    $groupId = $groupInfo['iid'];
185
                    if (\GroupManager::user_has_access(
186
                        $userId,
187
                        $groupId,
188
                        \GroupManager::GROUP_TOOL_DOCUMENTS
189
                    )) {
190
                        $config['attributes'][] = [
191
                            'pattern' => '!'.$groupInfo['secret_directory'].'!',
192
                            'read' => true,
193
                            'write' => false,
194
                            'hidden' => false,
195
                            'locked' => false,
196
                        ];
197
                    }
198
                }
199
            }
200
201
            return $config;
202
        }
203
204
        return [];
205
    }
206
207
    /**
208
     * This is the absolute document course path like
209
     * /var/www/portal/data/courses/XXX/document/.
210
     *
211
     * @return string
212
     */
213
    public function getCourseDocumentSysPath()
214
    {
215
        $url = '';
216
        if ($this->allow()) {
217
            $directory = $this->getCourseDirectory();
218
            $coursePath = $this->connector->paths['sys_course_path'];
219
            $url = $coursePath.$directory.'/document/';
220
        }
221
222
        return $url;
223
    }
224
225
    /**
226
     * @return string
227
     */
228
    public function getCourseDocumentRelativeWebPath()
229
    {
230
        $url = null;
231
        if ($this->allow()) {
232
            $directory = $this->getCourseDirectory();
233
            $url = api_get_path(REL_COURSE_PATH).$directory.'/document/';
234
        }
235
236
        return $url;
237
    }
238
239
    /**
240
     * @return string
241
     */
242
    public function getCourseDocumentWebPath()
243
    {
244
        $url = null;
245
        if ($this->allow()) {
246
            $directory = $this->getCourseDirectory();
247
            $url = api_get_path(WEB_COURSE_PATH).$directory.'/document/';
248
        }
249
250
        return $url;
251
    }
252
253
    /**
254
     * @return string
255
     */
256
    public function getCourseDirectory(): string
257
    {
258
        return $this->connector->course->getDirectory();
259
    }
260
261
    /**
262
     * {@inheritdoc}
263
     */
264
    public function upload($fp, $dst, $name, $tmpname, $hashes = [])
265
    {
266
        // Needed to load course information in elfinder
267
        $this->setConnectorFromPlugin();
268
269
        if ($this->allowToEdit()) {
270
            $directoryParentId = isset($_REQUEST['directory_parent_id']) ? $_REQUEST['directory_parent_id'] : 0;
271
            $currentDirectory = '';
272
            if (empty($directoryParentId)) {
273
                $currentDirectory = isset($_REQUEST['curdirpath']) ? $_REQUEST['curdirpath'] : '';
274
            } else {
275
                $documentData = \DocumentManager::get_document_data_by_id($directoryParentId, api_get_course_id());
276
                if ($documentData) {
277
                    $currentDirectory = $documentData['path'];
278
                }
279
            }
280
281
            if (!empty($_FILES)) {
282
                $request = Container::getRequest();
283
                $fileList = $request->files->get('upload');
284
                /** @var UploadedFile $file */
285
                foreach ($fileList as $file) {
286
                    $fileInfo = $file->getFileInfo();
287
                    $item = [
288
                        'files' => [
289
                            'tmp_name' => $fileInfo->getPathname(),
290
                            'error' => $file->getError(),
291
                            'size' => $file->getSize(),
292
                        ],
293
                    ];
294
                    \DocumentManager::upload_document(
295
                        $item,
296
                        $currentDirectory,
297
                        '',
298
                        '', // comment
299
                        false,
300
                        'rename',
301
                        false,
302
                        false,
303
                        'files',
304
                        true,
305
                        $directoryParentId,
306
                        $file
307
                    );
308
                }
309
            }
310
        }
311
312
        return false;
313
    }
314
315
    /**
316
     * {@inheritdoc}
317
     */
318
    public function rm($hash)
319
    {
320
        $this->setConnectorFromPlugin();
321
322
        if ($this->allowToEdit()) {
323
            $path = $this->decode($hash);
324
            $stat = $this->stat($path);
325
            $stat['realpath'] = $path;
326
            $this->removed[] = $stat;
327
328
            $realFilePath = $path;
329
            $coursePath = $this->getCourseDocumentSysPath();
330
            $filePath = str_replace($coursePath, '/', $realFilePath);
331
            $courseInfo = $this->getCourseInfoArray();
332
333
            \DocumentManager::delete_document(
334
                $courseInfo,
335
                $filePath,
336
                $coursePath
337
            );
338
339
            return true;
340
        }
341
342
        return false;
343
    }
344
345
    /**
346
     * @return array
347
     */
348
    public function getCourseInfoArray(): array
349
    {
350
        $courseInfo = [
351
            'real_id' => $this->connector->course->getId(),
352
            'code' => $this->connector->course->getCode(),
353
        ];
354
355
        return $courseInfo;
356
    }
357
358
    /**
359
     * @return bool
360
     */
361
    public function allow()
362
    {
363
        //if ($this->connector->security->isGranted('ROLE_ADMIN')) {
364
        if (api_is_anonymous()) {
365
            return false;
366
        }
367
368
        $block = api_get_configuration_value('block_editor_file_manager_for_students');
369
        if ($block && !api_is_allowed_to_edit()) {
370
            return false;
371
        }
372
373
        if (isset($this->connector->course) && !empty($this->connector->course)) {
374
            return true;
375
        }
376
377
        return false;
378
    }
379
380
    /**
381
     * Allow to upload/delete folder or files.
382
     *
383
     * @return bool
384
     */
385
    public function allowToEdit()
386
    {
387
        $allow = $this->allow();
388
389
        return $allow && api_is_allowed_to_edit(null, true);
390
    }
391
392
    /**
393
     * {@inheritdoc}
394
     */
395
    public function mkdir($path, $name)
396
    {
397
        // Needed to load course information in elfinder
398
        $this->setConnectorFromPlugin();
399
400
        if ($this->allowToEdit() === false) {
401
            return false;
402
        }
403
404
        $result = parent::mkdir($path, $name);
405
406
        if ($result && isset($result['hash'])) {
407
            $realPathRoot = $this->getCourseDocumentSysPath();
408
            $realPath = $this->realpath($result['hash']);
409
410
            // Removing course path
411
            $newPath = str_replace($realPathRoot, '/', $realPath);
412
            $documentId = \DocumentManager::addDocument(
413
                $this->getCourseInfoArray(),
414
                $newPath,
415
                'folder',
416
                0,
417
                $name,
418
                null,
419
                0,
420
                true,
421
                api_get_group_id(),
422
                api_get_session_id(),
423
                api_get_user_id()
424
            );
425
426
            if (empty($documentId)) {
427
                $this->rm($result['hash']);
428
429
                return false;
430
            }
431
432
            return $result;
433
        }
434
435
        return false;
436
    }
437
438
    protected function getParents($path)
439
    {
440
        $parents = array();
441
442
        while ($path) {
443
            if ($file = $this->stat($path)) {
444
                array_unshift($parents, $path);
445
                $path = isset($file['phash']) ? $this->decode($file['phash']) : false;
446
            }
447
        }
448
449
        if (count($parents)) {
450
            array_pop($parents);
451
        }
452
        return $parents;
453
    }
454
455
    protected function _path($path)
456
    {
457
        if (($file = $this->stat($path)) == false) {
458
            return '';
459
        }
460
461
        $parentsIds = $this->getParents($path);
462
        $path = '';
463
        foreach ($parentsIds as $id) {
464
            $dir = $this->stat($id);
465
            $path .= $dir['name'] . $this->separator;
466
        }
467
        return $path . $file['name'];
468
    }
469
470
471
    public function mount(array $opts)
472
    {
473
474
    }
475
476
    /**
477
     * @param string $attr
478
     * @param string $path
479
     * @param $data
480
     * @param CourseDriver $volume
481
     */
482
    /*public function access($attr, $path, $data, $volume)
483
    {
484
        if ($path == $this->coursePath) {
485
486
            return true;
487
        }
488
489
        $allowToEdit = $this->allowToEdit();
490
        if ($allowToEdit) {
491
            return true;
492
        }
493
494
        $path = str_replace($this->coursePath, '', $path);
495
        $documentId = \DocumentManager::get_document_id($this->connector->course, $path);
496
497
        if ($documentId) {
498
499
            $result = \DocumentManager::is_visible_by_id(
500
                $documentId,
501
                $this->connector->course,
502
                api_get_session_id(),
503
                api_get_user_id()
504
            );
505
            return false;
506
        }
507
508
        return false;
509
510
    }*/
511
}
512