Passed
Push — master ( 83aef6...b86f20 )
by Julito
10:30
created

add_document()   F

Complexity

Conditions 16
Paths 1920

Size

Total Lines 180
Code Lines 106

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 0
Metric Value
cc 16
eloc 106
nc 1920
nop 14
dl 0
loc 180
rs 1.1198
c 5
b 1
f 0

How to fix   Long Method    Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CoreBundle\Entity\Resource\ResourceFile;
5
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
6
use Chamilo\CoreBundle\Entity\Resource\ResourceRight;
7
use Chamilo\CourseBundle\Entity\CDocument;
8
use Symfony\Component\HttpFoundation\File\UploadedFile;
9
use Chamilo\CoreBundle\Framework\Container;
10
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
11
12
/**
13
 * FILE UPLOAD LIBRARY.
14
 *
15
 * This is the file upload library for Chamilo.
16
 * Include/require it in your code to use its functionality.
17
 *
18
 * @package chamilo.library
19
 *
20
 * @todo test and reorganise
21
 */
22
23
/**
24
 * Changes the file name extension from .php to .phps
25
 * Useful for securing a site.
26
 *
27
 * @author Hugues Peeters <[email protected]>
28
 *
29
 * @param string $file_name Name of a file
30
 *
31
 * @return string the filename phps'ized
32
 */
33
function php2phps($file_name)
34
{
35
    return preg_replace('/\.(php.?|phtml.?)(\.){0,1}.*$/i', '.phps', $file_name);
36
}
37
38
/**
39
 * Renames .htaccess & .HTACCESS to htaccess.txt.
40
 *
41
 * @param string $filename
42
 *
43
 * @return string
44
 */
45
function htaccess2txt($filename)
46
{
47
    return str_replace(['.htaccess', '.HTACCESS'], ['htaccess.txt', 'htaccess.txt'], $filename);
48
}
49
50
/**
51
 * This function executes our safety precautions
52
 * more functions can be added.
53
 *
54
 * @param string $filename
55
 *
56
 * @return string
57
 *
58
 * @see php2phps()
59
 * @see htaccess2txt()
60
 */
61
function disable_dangerous_file($filename)
62
{
63
    return htaccess2txt(php2phps($filename));
64
}
65
66
/**
67
 * Returns the name without extension, used for the title.
68
 *
69
 * @param string $name
70
 *
71
 * @return name without the extension
72
 */
73
function get_document_title($name)
74
{
75
    // If they upload .htaccess...
76
    $name = disable_dangerous_file($name);
77
    $ext = substr(strrchr($name, '.'), 0);
78
79
    return substr($name, 0, strlen($name) - strlen(strstr($name, $ext)));
80
}
81
82
/**
83
 * This function checks if the upload succeeded.
84
 *
85
 * @param array $uploaded_file ($_FILES)
86
 *
87
 * @return true if upload succeeded
88
 */
89
function process_uploaded_file($uploaded_file, $show_output = true)
90
{
91
    // Checking the error code sent with the file upload.
92
    if (isset($uploaded_file['error'])) {
93
        switch ($uploaded_file['error']) {
94
            case 1:
95
                // The uploaded file exceeds the upload_max_filesize directive in php.ini.
96
                if ($show_output) {
97
                    Display::addFlash(
98
                        Display::return_message(
99
                            get_lang('UplExceedMaxServerUpload').ini_get('upload_max_filesize'),
100
                            'error'
101
                        )
102
                    );
103
                }
104
105
                return false;
106
            case 2:
107
                // The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
108
                // Not used at the moment, but could be handy if we want to limit the size of an upload
109
                // (e.g. image upload in html editor).
110
                $max_file_size = intval($_POST['MAX_FILE_SIZE']);
111
                if ($show_output) {
112
                    Display::addFlash(
113
                        Display::return_message(
114
                            get_lang('UplExceedMaxPostSize').format_file_size($max_file_size),
115
                            'error'
116
                        )
117
                    );
118
                }
119
120
                return false;
121
            case 3:
122
                // The uploaded file was only partially uploaded.
123
                if ($show_output) {
124
                    Display::addFlash(
125
                        Display::return_message(
126
                            get_lang('UplPartialUpload').' '.get_lang('PleaseTryAgain'),
127
                            'error'
128
                        )
129
                    );
130
                }
131
132
                return false;
133
            case 4:
134
                // No file was uploaded.
135
                if ($show_output) {
136
                    Display::addFlash(
137
                        Display::return_message(
138
                            get_lang('UplNoFileUploaded').' '.get_lang('UplSelectFileFirst'),
139
                            'error'
140
                        )
141
                    );
142
                }
143
144
                return false;
145
        }
146
    }
147
148
    if (!file_exists($uploaded_file['tmp_name'])) {
149
        // No file was uploaded.
150
        if ($show_output) {
151
            Display::addFlash(Display::return_message(get_lang('UplUploadFailed'), 'error'));
152
        }
153
154
        return false;
155
    }
156
157
    if (file_exists($uploaded_file['tmp_name'])) {
158
        $filesize = filesize($uploaded_file['tmp_name']);
159
        if (empty($filesize)) {
160
            // No file was uploaded.
161
            if ($show_output) {
162
                Display::addFlash(
163
                    Display::return_message(
164
                        get_lang('UplUploadFailedSizeIsZero'),
165
                        'error'
166
                    )
167
                );
168
            }
169
170
            return false;
171
        }
172
    }
173
174
    $course_id = api_get_course_id();
175
176
    //Checking course quota if we are in a course
177
    if (!empty($course_id)) {
178
        $max_filled_space = DocumentManager::get_course_quota();
179
        // Check if there is enough space to save the file
180
        if (!DocumentManager::enough_space($uploaded_file['size'], $max_filled_space)) {
181
            if ($show_output) {
182
                Display::addFlash(
183
                    Display::return_message(
184
                        get_lang('UplNotEnoughSpace'),
185
                        'error'
186
                    )
187
                );
188
            }
189
190
            return false;
191
        }
192
    }
193
194
    // case 0: default: We assume there is no error, the file uploaded with success.
195
    return true;
196
}
197
198
/**
199
 * This function does the save-work for the documents.
200
 * It handles the uploaded file and adds the properties to the database
201
 * If unzip=1 and the file is a zipfile, it is extracted
202
 * If we decide to save ALL kinds of documents in one database,
203
 * we could extend this with a $type='document', 'scormdocument',...
204
 *
205
 * @param array  $courseInfo
206
 * @param array  $uploadedFile            ($_FILES)
207
 *                                        array(
208
 *                                        'name' => 'picture.jpg',
209
 *                                        'tmp_name' => '...', // absolute path
210
 *                                        );
211
 * @param string $documentDir             Example: /var/www/chamilo/courses/ABC/document
212
 * @param string $uploadPath              Example: /folder1/folder2/
213
 * @param int    $userId
214
 * @param int    $groupId                 group.id
215
 * @param int    $toUserId                User ID, or NULL for everybody
216
 * @param int    $unzip                   1/0
217
 * @param string $whatIfFileExists        overwrite, rename or warn if exists (default)
218
 * @param bool   $output                  optional output parameter
219
 * @param bool   $onlyUploadFile
220
 * @param string $comment
221
 * @param int    $sessionId
222
 * @param bool   $treat_spaces_as_hyphens
223
 * @param string $uploadKey
224
 * @param int    $parentId
225
 *
226
 * So far only use for unzip_uploaded_document function.
227
 * If no output wanted on success, set to false.
228
 *
229
 * @return CDocument|false
230
 */
231
function handle_uploaded_document(
232
    $courseInfo,
233
    $uploadedFile,
234
    $documentDir,
235
    $uploadPath,
236
    $userId,
237
    $groupId = 0,
238
    $toUserId = null,
239
    $unzip = 0,
240
    $whatIfFileExists = '',
241
    $output = true,
242
    $onlyUploadFile = false,
243
    $comment = null,
244
    $sessionId = null,
245
    $treat_spaces_as_hyphens = true,
246
    $uploadKey = '',
247
    $parentId = 0
248
) {
249
    if (!$userId) {
250
        return false;
251
    }
252
253
    $userInfo = api_get_user_info();
254
    $uploadedFile['name'] = stripslashes($uploadedFile['name']);
255
    // Add extension to files without one (if possible)
256
    $uploadedFile['name'] = add_ext_on_mime($uploadedFile['name'], $uploadedFile['type']);
257
    $sessionId = (int) $sessionId;
258
    if (empty($sessionId)) {
259
        $sessionId = api_get_session_id();
260
    }
261
262
    $groupInfo = [];
263
    if (!empty($groupId)) {
264
        $groupInfo = GroupManager::get_group_properties($groupId);
265
    }
266
267
    // Just in case process_uploaded_file is not called
268
    $maxSpace = DocumentManager::get_course_quota();
269
270
    // Check if there is enough space to save the file
271
    if (!DocumentManager::enough_space($uploadedFile['size'], $maxSpace)) {
272
        if ($output) {
273
            Display::addFlash(Display::return_message(get_lang('UplNotEnoughSpace'), 'error'));
274
        }
275
276
        return false;
277
    }
278
279
    // If the want to unzip, check if the file has a .zip (or ZIP,Zip,ZiP,...) extension
280
    if ($unzip == 1 && preg_match('/.zip$/', strtolower($uploadedFile['name']))) {
281
        return unzip_uploaded_document(
282
            $courseInfo,
283
            $userInfo,
284
            $uploadedFile,
285
            $uploadPath,
286
            $documentDir,
287
            $maxSpace,
288
            $sessionId,
289
            $groupId,
290
            $output,
291
            $onlyUploadFile,
292
            $whatIfFileExists
293
        );
294
    } elseif ($unzip == 1 && !preg_match('/.zip$/', strtolower($uploadedFile['name']))) {
295
        // We can only unzip ZIP files (no gz, tar,...)
296
        if ($output) {
297
            Display::addFlash(
298
                Display::return_message(get_lang('UplNotAZip')." ".get_lang('PleaseTryAgain'), 'error')
299
            );
300
        }
301
302
        return false;
303
    } else {
304
        // Clean up the name, only ASCII characters should stay. (and strict)
305
        $cleanName = api_replace_dangerous_char($uploadedFile['name'], $treat_spaces_as_hyphens);
306
307
        // No "dangerous" files
308
        $cleanName = disable_dangerous_file($cleanName);
309
310
        // Checking file extension
311
        if (!filter_extension($cleanName)) {
312
            if ($output) {
313
                Display::addFlash(
314
                    Display::return_message(get_lang('UplUnableToSaveFileFilteredExtension'), 'error')
315
                );
316
            }
317
318
            return false;
319
        } else {
320
            // If the upload path differs from / (= root) it will need a slash at the end
321
            if ($uploadPath != '/') {
322
                $uploadPath = $uploadPath.'/';
323
            }
324
325
            // Full path to where we want to store the file with trailing slash
326
            $whereToSave = $documentDir.$uploadPath;
327
328
            // At least if the directory doesn't exist, tell so
329
            /*if (!is_dir($whereToSave)) {
330
                if (!mkdir($whereToSave, api_get_permissions_for_new_directories())) {
331
                    if ($output) {
332
                        Display::addFlash(
333
                            Display::return_message(
334
                                get_lang('DestDirectoryDoesntExist').' ('.$uploadPath.')',
335
                                'error'
336
                            )
337
                        );
338
                    }
339
340
                    return false;
341
                }
342
            }*/
343
344
            // Just upload the file "as is"
345
            if ($onlyUploadFile) {
346
                $errorResult = moveUploadedFile($uploadedFile, $whereToSave.$cleanName);
347
                if ($errorResult) {
348
                    return $whereToSave.$cleanName;
349
                } else {
350
                    return $errorResult;
351
                }
352
            }
353
354
            /*
355
                Based in the clean name we generate a new filesystem name
356
                Using the session_id and group_id if values are not empty
357
            */
358
            $fileSystemName = DocumentManager::fixDocumentName(
359
                $cleanName,
360
                'file',
361
                $courseInfo,
362
                $sessionId,
363
                $groupId
364
            );
365
366
            // Name of the document without the extension (for the title)
367
            $documentTitle = get_document_title($uploadedFile['name']);
368
369
            // Size of the uploaded file (in bytes)
370
            $fileSize = $uploadedFile['size'];
371
372
            // File permissions
373
            $filePermissions = api_get_permissions_for_new_files();
374
375
            // Example: /var/www/chamilo/courses/xxx/document/folder/picture.jpg
376
            $fullPath = $whereToSave.$fileSystemName;
377
378
            // Example: /folder/picture.jpg
379
            $filePath = $uploadPath.$fileSystemName;
380
381
            $docId = DocumentManager::get_document_id(
382
                $courseInfo,
383
                $filePath,
384
                $sessionId
385
            );
386
387
            // What to do if the target file exists
388
            switch ($whatIfFileExists) {
389
                // Overwrite the file if it exists
390
                case 'overwrite':
391
                    // Check if the target file exists, so we can give another message
392
                    $fileExists = file_exists($fullPath);
393
394
                    if (moveUploadedFile($uploadedFile, $fullPath)) {
395
                        chmod($fullPath, $filePermissions);
396
397
                        if ($fileExists && $docId) {
398
                            // UPDATE DATABASE
399
                            $documentId = DocumentManager::get_document_id(
400
                                $courseInfo,
401
                                $filePath
402
                            );
403
                            if (is_numeric($documentId)) {
404
                                // Update file size
405
                                update_existing_document(
406
                                    $courseInfo,
407
                                    $documentId,
408
                                    $uploadedFile['size']
409
                                );
410
411
                                // Update document item_property
412
                                api_item_property_update(
413
                                    $courseInfo,
414
                                    TOOL_DOCUMENT,
415
                                    $documentId,
416
                                    'DocumentUpdated',
417
                                    $userId,
418
                                    $groupInfo,
419
                                    $toUserId,
420
                                    null,
421
                                    null,
422
                                    $sessionId
423
                                );
424
425
                                // Redo visibility
426
                                api_set_default_visibility(
427
                                    $documentId,
428
                                    TOOL_DOCUMENT,
429
                                    null,
430
                                    $courseInfo
431
                                );
432
                            } else {
433
                                // There might be cases where the file exists on disk but there is no registration of
434
                                // that in the database
435
                                // In this case, and if we are in overwrite mode, overwrite and create the db record
436
                                $documentId = add_document(
437
                                    $courseInfo,
438
                                    $filePath,
439
                                    'file',
440
                                    $fileSize,
441
                                    $documentTitle,
442
                                    $comment,
443
                                    0,
444
                                    true,
445
                                    $groupId,
446
                                    $sessionId
447
                                );
448
449
                                if ($documentId) {
450
                                    // Put the document in item_property update
451
                                    api_item_property_update(
452
                                        $courseInfo,
453
                                        TOOL_DOCUMENT,
454
                                        $documentId,
455
                                        'DocumentAdded',
456
                                        $userId,
457
                                        $groupInfo,
458
                                        $toUserId,
459
                                        null,
460
                                        null,
461
                                        $sessionId
462
                                    );
463
464
                                    // Redo visibility
465
                                    api_set_default_visibility(
466
                                        $documentId,
467
                                        TOOL_DOCUMENT,
468
                                        null,
469
                                        $courseInfo
470
                                    );
471
                                }
472
                            }
473
474
                            // If the file is in a folder, we need to update all parent folders
475
                            item_property_update_on_folder($courseInfo, $uploadPath, $userId);
476
477
                            // Display success message with extra info to user
478
                            if ($output) {
479
                                Display::addFlash(
480
                                    Display::return_message(
481
                                        get_lang('UplUploadSucceeded').'<br /> '.
482
                                        $documentTitle.' '.get_lang('UplFileOverwritten'),
483
                                        'confirmation',
484
                                        false
485
                                    )
486
                                );
487
                            }
488
489
                            return $filePath;
490
                        } else {
491
                            // Put the document data in the database
492
                            $documentId = add_document(
493
                                $courseInfo,
494
                                $filePath,
495
                                'file',
496
                                $fileSize,
497
                                $documentTitle,
498
                                $comment,
499
                                0,
500
                                true,
501
                                $groupId,
502
                                $sessionId
503
                            );
504
505
                            if ($documentId) {
506
                                // Put the document in item_property update
507
                                api_item_property_update(
508
                                    $courseInfo,
509
                                    TOOL_DOCUMENT,
510
                                    $documentId,
511
                                    'DocumentAdded',
512
                                    $userId,
513
                                    $groupInfo,
514
                                    $toUserId,
515
                                    null,
516
                                    null,
517
                                    $sessionId
518
                                );
519
520
                                // Redo visibility
521
                                api_set_default_visibility($documentId, TOOL_DOCUMENT, null, $courseInfo);
522
                            }
523
524
                            // If the file is in a folder, we need to update all parent folders
525
                            item_property_update_on_folder($courseInfo, $uploadPath, $userId);
526
527
                            // Display success message to user
528
                            if ($output) {
529
                                Display::addFlash(
530
                                    Display::return_message(
531
                                        get_lang('UplUploadSucceeded').'<br /> '.$documentTitle,
532
                                        'confirmation',
533
                                        false
534
                                    )
535
                                );
536
                            }
537
538
                            return $filePath;
539
                        }
540
                    } else {
541
                        if ($output) {
542
                            Display::addFlash(
543
                                Display::return_message(
544
                                    get_lang('UplUnableToSaveFile'),
545
                                    'error',
546
                                    false
547
                                )
548
                            );
549
                        }
550
551
                        return false;
552
                    }
553
                    break;
554
                case 'rename':
555
                    // Rename the file if it exists
556
                    $cleanName = DocumentManager::getUniqueFileName(
557
                        $uploadPath,
558
                        $cleanName,
559
                        $courseInfo,
560
                        $sessionId,
561
                        $groupId
562
                    );
563
564
                    $fileSystemName = DocumentManager::fixDocumentName(
565
                        $cleanName,
566
                        'file',
567
                        $courseInfo,
568
                        $sessionId,
569
                        $groupId
570
                    );
571
572
                    $documentTitle = disable_dangerous_file($cleanName);
573
                    $filePath = $uploadPath.$fileSystemName;
574
575
                    $request = Container::getRequest();
576
                    $content = $request->files->get($uploadKey);
577
                    if (is_array($content)) {
578
                        $content = $content[0];
579
                    }
580
581
                    //if (moveUploadedFile($uploadedFile, $fullPath)) {
582
                    if (true) {
583
                        ///chmod($fullPath, $filePermissions);
584
                        // Put the document data in the database
585
                        $document = add_document(
586
                            $courseInfo,
587
                            $filePath,
588
                            'file',
589
                            $fileSize,
590
                            $documentTitle,
591
                            $comment, // comment
592
                            0, // read only
593
                            true, // save visibility
594
                            $groupId,
595
                            $sessionId,
596
                            0,
597
                            true,
598
                            $content,
599
                            $parentId
600
                        );
601
602
                        // Display success message to user
603
                        if ($output) {
604
                            Display::addFlash(
605
                                Display::return_message(
606
                                    get_lang('UplUploadSucceeded').'<br />'.
607
                                    get_lang('UplFileSavedAs').' '.$document->getTitle(),
608
                                    'success',
609
                                    false
610
                                )
611
                            );
612
                        }
613
614
                        return $document;
615
                    } else {
616
                        /*if ($output) {
617
                            Display::addFlash(
618
                                Display::return_message(
619
                                    get_lang('UplUnableToSaveFile'),
620
                                    'error',
621
                                    false
622
                                )
623
                            );
624
                        }
625
626
                        return false;*/
627
                    }
628
                    break;
629
                case 'nothing':
630
                    $fileExists = file_exists($fullPath);
631
                    if ($fileExists) {
632
                        if ($output) {
633
                            Display::addFlash(
634
                                Display::return_message(
635
                                    $uploadPath.$cleanName.' '.get_lang('UplAlreadyExists'),
636
                                    'warning',
637
                                    false
638
                                )
639
                            );
640
                        }
641
                        break;
642
                    }
643
                    // no break
644
                default:
645
                    // Only save the file if it doesn't exist or warn user if it does exist
646
                    if (file_exists($fullPath) && $docId) {
647
                        if ($output) {
648
                            Display::addFlash(
649
                                Display::return_message($cleanName.' '.get_lang('UplAlreadyExists'), 'warning', false)
650
                            );
651
                        }
652
                    } else {
653
                        if (moveUploadedFile($uploadedFile, $fullPath)) {
654
                            //chmod($fullPath, $filePermissions);
655
656
                            // Put the document data in the database
657
                            $documentId = add_document(
658
                                $courseInfo,
659
                                $filePath,
660
                                'file',
661
                                $fileSize,
662
                                $documentTitle,
663
                                $comment,
664
                                0,
665
                                true,
666
                                $groupId,
667
                                $sessionId
668
                            );
669
670
                            if ($documentId) {
671
                                // Update document item_property
672
                                api_item_property_update(
673
                                    $courseInfo,
674
                                    TOOL_DOCUMENT,
675
                                    $documentId,
676
                                    'DocumentAdded',
677
                                    $userId,
678
                                    $groupInfo,
679
                                    $toUserId,
680
                                    null,
681
                                    null,
682
                                    $sessionId
683
                                );
684
                                // Redo visibility
685
                                api_set_default_visibility($documentId, TOOL_DOCUMENT, null, $courseInfo);
686
                            }
687
688
                            // If the file is in a folder, we need to update all parent folders
689
                            item_property_update_on_folder(
690
                                $courseInfo,
691
                                $uploadPath,
692
                                $userId
693
                            );
694
695
                            // Display success message to user
696
                            if ($output) {
697
                                Display::addFlash(
698
                                    Display::return_message(
699
                                        get_lang('UplUploadSucceeded').'<br /> '.$documentTitle,
700
                                        'confirm',
701
                                        false
702
                                    )
703
                                );
704
                            }
705
706
                            return $filePath;
707
                        } else {
708
                            if ($output) {
709
                                Display::addFlash(
710
                                    Display::return_message(
711
                                        get_lang('UplUnableToSaveFile'),
712
                                        'error',
713
                                        false
714
                                    )
715
                                );
716
                            }
717
718
                            return false;
719
                        }
720
                    }
721
                    break;
722
            }
723
        }
724
    }
725
}
726
727
/**
728
 * @param string $file
729
 * @param string $storePath
730
 *
731
 * @return bool
732
 */
733
function moveUploadedFile($file, $storePath)
734
{
735
    $handleFromFile = isset($file['from_file']) && $file['from_file'] ? true : false;
736
    $moveFile = isset($file['move_file']) && $file['move_file'] ? true : false;
737
    if ($moveFile) {
738
        copy($file['tmp_name'], $storePath);
739
    }
740
    if ($handleFromFile) {
741
        return file_exists($file['tmp_name']);
742
    } else {
743
        return move_uploaded_file($file['tmp_name'], $storePath);
744
    }
745
}
746
747
/**
748
 * Checks if there is enough place to add a file on a directory
749
 * on the base of a maximum directory size allowed
750
 * deprecated: use enough_space instead!
751
 *
752
 * @author Hugues Peeters <[email protected]>
753
 *
754
 * @param int    $file_size     Size of the file in byte
755
 * @param string $dir           Path of the directory where the file should be added
756
 * @param int    $max_dir_space Maximum size of the diretory in byte
757
 *
758
 * @return bool true if there is enough space, false otherwise
759
 *
760
 * @see enough_size() uses  dir_total_space() function
761
 */
762
function enough_size($file_size, $dir, $max_dir_space)
763
{
764
    // If the directory is the archive directory, safely ignore the size limit
765
    if (api_get_path(SYS_ARCHIVE_PATH) == $dir) {
766
        return true;
767
    }
768
769
    if ($max_dir_space) {
770
        $already_filled_space = dir_total_space($dir);
771
        if (($file_size + $already_filled_space) > $max_dir_space) {
772
            return false;
773
        }
774
    }
775
776
    return true;
777
}
778
779
/**
780
 * Computes the size already occupied by a directory and is subdirectories.
781
 *
782
 * @author Hugues Peeters <[email protected]>
783
 *
784
 * @param string $dir_path Size of the file in byte
785
 *
786
 * @return int Return the directory size in bytes
787
 */
788
function dir_total_space($dir_path)
789
{
790
    $save_dir = getcwd();
791
    chdir($dir_path);
792
    $handle = opendir($dir_path);
793
    $sumSize = 0;
794
    $dirList = [];
795
    while ($element = readdir($handle)) {
796
        if ($element == '.' || $element == '..') {
797
            continue; // Skip the current and parent directories
798
        }
799
        if (is_file($element)) {
800
            $sumSize += filesize($element);
801
        }
802
        if (is_dir($element)) {
803
            $dirList[] = $dir_path.'/'.$element;
804
        }
805
    }
806
807
    closedir($handle);
808
809
    if (sizeof($dirList) > 0) {
810
        foreach ($dirList as $j) {
811
            $sizeDir = dir_total_space($j); // Recursivity
812
            $sumSize += $sizeDir;
813
        }
814
    }
815
    chdir($save_dir); // Return to initial position
816
817
    return $sumSize;
818
}
819
820
/**
821
 * Tries to add an extension to files without extension
822
 * Some applications on Macintosh computers don't add an extension to the files.
823
 * This subroutine try to fix this on the basis of the MIME type sent
824
 * by the browser.
825
 *
826
 * Note : some browsers don't send the MIME Type (e.g. Netscape 4).
827
 *        We don't have solution for this kind of situation
828
 *
829
 * @author Hugues Peeters <[email protected]>
830
 * @author Bert Vanderkimpen
831
 *
832
 * @param string $file_name Name of the file
833
 * @param string $file_type Type of the file
834
 *
835
 * @return string File name
836
 */
837
function add_ext_on_mime($file_name, $file_type)
838
{
839
    // Check whether the file has an extension AND whether the browser has sent a MIME Type
840
841
    if (!preg_match('/^.*\.[a-zA-Z_0-9]+$/', $file_name) && $file_type) {
842
        // Build a "MIME-types / extensions" connection table
843
        static $mime_type = [];
844
845
        $mime_type[] = 'application/msword';
846
        $extension[] = '.doc';
847
        $mime_type[] = 'application/rtf';
848
        $extension[] = '.rtf';
849
        $mime_type[] = 'application/vnd.ms-powerpoint';
850
        $extension[] = '.ppt';
851
        $mime_type[] = 'application/vnd.ms-excel';
852
        $extension[] = '.xls';
853
        $mime_type[] = 'application/pdf';
854
        $extension[] = '.pdf';
855
        $mime_type[] = 'application/postscript';
856
        $extension[] = '.ps';
857
        $mime_type[] = 'application/mac-binhex40';
858
        $extension[] = '.hqx';
859
        $mime_type[] = 'application/x-gzip';
860
        $extension[] = 'tar.gz';
861
        $mime_type[] = 'application/x-shockwave-flash';
862
        $extension[] = '.swf';
863
        $mime_type[] = 'application/x-stuffit';
864
        $extension[] = '.sit';
865
        $mime_type[] = 'application/x-tar';
866
        $extension[] = '.tar';
867
        $mime_type[] = 'application/zip';
868
        $extension[] = '.zip';
869
        $mime_type[] = 'application/x-tar';
870
        $extension[] = '.tar';
871
        $mime_type[] = 'text/html';
872
        $extension[] = '.html';
873
        $mime_type[] = 'text/plain';
874
        $extension[] = '.txt';
875
        $mime_type[] = 'text/rtf';
876
        $extension[] = '.rtf';
877
        $mime_type[] = 'img/gif';
878
        $extension[] = '.gif';
879
        $mime_type[] = 'img/jpeg';
880
        $extension[] = '.jpg';
881
        $mime_type[] = 'img/png';
882
        $extension[] = '.png';
883
        $mime_type[] = 'audio/midi';
884
        $extension[] = '.mid';
885
        $mime_type[] = 'audio/mpeg';
886
        $extension[] = '.mp3';
887
        $mime_type[] = 'audio/x-aiff';
888
        $extension[] = '.aif';
889
        $mime_type[] = 'audio/x-pn-realaudio';
890
        $extension[] = '.rm';
891
        $mime_type[] = 'audio/x-pn-realaudio-plugin';
892
        $extension[] = '.rpm';
893
        $mime_type[] = 'audio/x-wav';
894
        $extension[] = '.wav';
895
        $mime_type[] = 'video/mpeg';
896
        $extension[] = '.mpg';
897
        $mime_type[] = 'video/mpeg4-generic';
898
        $extension[] = '.mp4';
899
        $mime_type[] = 'video/quicktime';
900
        $extension[] = '.mov';
901
        $mime_type[] = 'video/x-msvideo';
902
        $extension[] = '.avi';
903
904
        $mime_type[] = 'video/x-ms-wmv';
905
        $extension[] = '.wmv';
906
        $mime_type[] = 'video/x-flv';
907
        $extension[] = '.flv';
908
        $mime_type[] = 'image/svg+xml';
909
        $extension[] = '.svg';
910
        $mime_type[] = 'image/svg+xml';
911
        $extension[] = '.svgz';
912
        $mime_type[] = 'video/ogg';
913
        $extension[] = '.ogv';
914
        $mime_type[] = 'audio/ogg';
915
        $extension[] = '.oga';
916
        $mime_type[] = 'application/ogg';
917
        $extension[] = '.ogg';
918
        $mime_type[] = 'application/ogg';
919
        $extension[] = '.ogx';
920
        $mime_type[] = 'application/x-freemind';
921
        $extension[] = '.mm';
922
923
        $mime_type[] = 'application/vnd.ms-word.document.macroEnabled.12';
924
        $extension[] = '.docm';
925
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
926
        $extension[] = '.docx';
927
        $mime_type[] = 'application/vnd.ms-word.template.macroEnabled.12';
928
        $extension[] = '.dotm';
929
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.template';
930
        $extension[] = '.dotx';
931
        $mime_type[] = 'application/vnd.ms-powerpoint.template.macroEnabled.12';
932
        $extension[] = '.potm';
933
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.template';
934
        $extension[] = '.potx';
935
        $mime_type[] = 'application/vnd.ms-powerpoint.addin.macroEnabled.12';
936
        $extension[] = '.ppam';
937
        $mime_type[] = 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12';
938
        $extension[] = '.ppsm';
939
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.slideshow';
940
        $extension[] = '.ppsx';
941
        $mime_type[] = 'application/vnd.ms-powerpoint.presentation.macroEnabled.12';
942
        $extension[] = '.pptm';
943
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
944
        $extension[] = '.pptx';
945
        $mime_type[] = 'application/vnd.ms-excel.addin.macroEnabled.12';
946
        $extension[] = '.xlam';
947
        $mime_type[] = 'application/vnd.ms-excel.sheet.binary.macroEnabled.12';
948
        $extension[] = '.xlsb';
949
        $mime_type[] = 'application/vnd.ms-excel.sheet.macroEnabled.12';
950
        $extension[] = '.xlsm';
951
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
952
        $extension[] = '.xlsx';
953
        $mime_type[] = 'application/vnd.ms-excel.template.macroEnabled.12';
954
        $extension[] = '.xltm';
955
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.template';
956
        $extension[] = '.xltx';
957
958
        // Test on PC (files with no extension get application/octet-stream)
959
        //$mime_type[] = 'application/octet-stream';      $extension[] = '.ext';
960
        // Check whether the MIME type sent by the browser is within the table
961
        foreach ($mime_type as $key => &$type) {
962
            if ($type == $file_type) {
963
                $file_name .= $extension[$key];
964
                break;
965
            }
966
        }
967
968
        unset($mime_type, $extension, $type, $key); // Delete to eschew possible collisions
969
    }
970
971
    return $file_name;
972
}
973
974
/**
975
 * Manages all the unzipping process of an uploaded file.
976
 *
977
 * @author Hugues Peeters <[email protected]>
978
 *
979
 * @param array  $uploaded_file    - follows the $_FILES Structure
980
 * @param string $upload_path      - destination of the upload.
981
 *                                 This path is to append to $base_work_dir
982
 * @param string $base_work_dir    - base working directory of the module
983
 * @param int    $max_filled_space - amount of bytes to not exceed in the base
984
 *                                 working directory
985
 *
986
 * @return bool true if it succeeds false otherwise
987
 */
988
function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_filled_space)
989
{
990
    $zip_file = new PclZip($uploaded_file['tmp_name']);
991
992
    // Check the zip content (real size and file extension)
993
    if (file_exists($uploaded_file['tmp_name'])) {
994
        $zip_content_array = $zip_file->listContent();
995
        $ok_scorm = false;
996
        $realFileSize = 0;
997
        foreach ($zip_content_array as &$this_content) {
998
            if (preg_match('~.(php.*|phtml)$~i', $this_content['filename'])) {
999
                Display::addFlash(
1000
                    Display::return_message(get_lang('ZipNoPhp'))
1001
                );
1002
1003
                return false;
1004
            } elseif (stristr($this_content['filename'], 'imsmanifest.xml')) {
1005
                $ok_scorm = true;
1006
            } elseif (stristr($this_content['filename'], 'LMS')) {
1007
                $ok_plantyn_scorm1 = true;
1008
            } elseif (stristr($this_content['filename'], 'REF')) {
1009
                $ok_plantyn_scorm2 = true;
1010
            } elseif (stristr($this_content['filename'], 'SCO')) {
1011
                $ok_plantyn_scorm3 = true;
1012
            } elseif (stristr($this_content['filename'], 'AICC')) {
1013
                $ok_aicc_scorm = true;
1014
            }
1015
            $realFileSize += $this_content['size'];
1016
        }
1017
1018
        if (($ok_plantyn_scorm1 && $ok_plantyn_scorm2 && $ok_plantyn_scorm3) || $ok_aicc_scorm) {
1019
            $ok_scorm = true;
1020
        }
1021
1022
        if (!$ok_scorm && defined('CHECK_FOR_SCORM') && CHECK_FOR_SCORM) {
1023
            Display::addFlash(
1024
                Display::return_message(get_lang('NotScormContent'))
1025
            );
1026
1027
            return false;
1028
        }
1029
1030
        if (!enough_size($realFileSize, $base_work_dir, $max_filled_space)) {
1031
            Display::addFlash(
1032
                Display::return_message(get_lang('NoSpace'))
1033
            );
1034
1035
            return false;
1036
        }
1037
1038
        // It happens on Linux that $upload_path sometimes doesn't start with '/'
1039
        if ($upload_path[0] != '/' && substr($base_work_dir, -1, 1) != '/') {
1040
            $upload_path = '/'.$upload_path;
1041
        }
1042
1043
        if ($upload_path[strlen($upload_path) - 1] == '/') {
1044
            $upload_path = substr($upload_path, 0, -1);
1045
        }
1046
1047
        /*	Uncompressing phase */
1048
1049
        /*
1050
            The first version, using OS unzip, is not used anymore
1051
            because it does not return enough information.
1052
            We need to process each individual file in the zip archive to
1053
            - add it to the database
1054
            - parse & change relative html links
1055
        */
1056
        if (PHP_OS == 'Linux' && !get_cfg_var('safe_mode') && false) { // *** UGent, changed by OC ***
1057
            // Shell Method - if this is possible, it gains some speed
1058
            exec("unzip -d \"".$base_work_dir.$upload_path."/\"".$uploaded_file['name']." ".$uploaded_file['tmp_name']);
1059
        } else {
1060
            // PHP method - slower...
1061
            $save_dir = getcwd();
1062
            chdir($base_work_dir.$upload_path);
1063
            $unzippingState = $zip_file->extract();
1064
            for ($j = 0; $j < count($unzippingState); $j++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
1065
                $state = $unzippingState[$j];
1066
1067
                // Fix relative links in html files
1068
                $extension = strrchr($state['stored_filename'], '.');
1069
            }
1070
            if ($dir = @opendir($base_work_dir.$upload_path)) {
1071
                while ($file = readdir($dir)) {
1072
                    if ($file != '.' && $file != '..') {
1073
                        $filetype = 'file';
1074
                        if (is_dir($base_work_dir.$upload_path.'/'.$file)) {
1075
                            $filetype = 'folder';
1076
                        }
1077
1078
                        $safe_file = api_replace_dangerous_char($file);
1079
                        @rename($base_work_dir.$upload_path.'/'.$file, $base_work_dir.$upload_path.'/'.$safe_file);
1080
                        set_default_settings($upload_path, $safe_file, $filetype);
1081
                    }
1082
                }
1083
1084
                closedir($dir);
1085
            } else {
1086
                error_log('Could not create directory '.$base_work_dir.$upload_path.' to unzip files');
1087
            }
1088
            chdir($save_dir); // Back to previous dir position
1089
        }
1090
    }
1091
1092
    return true;
1093
}
1094
1095
/**
1096
 * Manages all the unzipping process of an uploaded document
1097
 * This uses the item_property table for properties of documents.
1098
 *
1099
 * @author Hugues Peeters <[email protected]>
1100
 * @author Bert Vanderkimpen
1101
 *
1102
 * @param array  $courseInfo
1103
 * @param array  $userInfo
1104
 * @param array  $uploaded_file    - follows the $_FILES Structure
1105
 * @param string $uploadPath       - destination of the upload.
1106
 *                                 This path is to append to $base_work_dir
1107
 * @param string $base_work_dir    - base working directory of the module
1108
 * @param int    $maxFilledSpace   - amount of bytes to not exceed in the base
1109
 *                                 working directory
1110
 * @param int    $sessionId
1111
 * @param int    $groupId          group.id
1112
 * @param bool   $output           Optional. If no output not wanted on success, set to false.
1113
 * @param bool   $onlyUploadFile
1114
 * @param string $whatIfFileExists (only works if $onlyUploadFile is false)
1115
 *
1116
 * @return bool true if it succeeds false otherwise
1117
 */
1118
function unzip_uploaded_document(
1119
    $courseInfo,
1120
    $userInfo,
1121
    $uploaded_file,
1122
    $uploadPath,
1123
    $base_work_dir,
1124
    $maxFilledSpace,
1125
    $sessionId = 0,
1126
    $groupId = 0,
1127
    $output = true,
1128
    $onlyUploadFile = false,
1129
    $whatIfFileExists = 'overwrite'
1130
) {
1131
    $zip = new PclZip($uploaded_file['tmp_name']);
1132
1133
    // Check the zip content (real size and file extension)
1134
    $zip_content_array = (array) $zip->listContent();
1135
    $realSize = 0;
1136
    foreach ($zip_content_array as &$this_content) {
1137
        $realSize += $this_content['size'];
1138
    }
1139
1140
    if (!DocumentManager::enough_space($realSize, $maxFilledSpace)) {
1141
        echo Display::return_message(get_lang('UplNotEnoughSpace'), 'error');
1142
1143
        return false;
1144
    }
1145
1146
    $folder = api_get_unique_id();
1147
    $destinationDir = api_get_path(SYS_ARCHIVE_PATH).$folder;
1148
    mkdir($destinationDir, api_get_permissions_for_new_directories(), true);
1149
1150
    // Uncompress zip file
1151
    // We extract using a callback function that "cleans" the path
1152
    $zip->extract(
1153
        PCLZIP_OPT_PATH,
1154
        $destinationDir,
1155
        PCLZIP_CB_PRE_EXTRACT,
1156
        'clean_up_files_in_zip',
1157
        PCLZIP_OPT_REPLACE_NEWER
1158
    );
1159
1160
    if ($onlyUploadFile === false) {
1161
        // Add all documents in the unzipped folder to the database
1162
        add_all_documents_in_folder_to_database(
1163
            $courseInfo,
1164
            $userInfo,
1165
            $base_work_dir,
1166
            $destinationDir,
1167
            $sessionId,
1168
            $groupId,
1169
            $output,
1170
            ['path' => $uploadPath],
1171
            $whatIfFileExists
1172
        );
1173
    } else {
1174
        // Copy result
1175
        $fs = new \Symfony\Component\Filesystem\Filesystem();
1176
        $fs->mirror($destinationDir, $base_work_dir.$uploadPath, null, ['overwrite']);
1177
    }
1178
1179
    if (is_dir($destinationDir)) {
1180
        rmdirr($destinationDir);
1181
    }
1182
1183
    return true;
1184
}
1185
1186
/**
1187
 * This function is a callback function that is used while extracting a zipfile
1188
 * http://www.phpconcept.net/pclzip/man/en/index.php?options-pclzip_cb_pre_extract.
1189
 *
1190
 * @param array $p_event
1191
 * @param array $p_header
1192
 *
1193
 * @return int (If the function returns 1, then the extraction is resumed, if 0 the path was skipped)
1194
 */
1195
function clean_up_files_in_zip($p_event, &$p_header)
1196
{
1197
    $originalStoredFileName = $p_header['stored_filename'];
1198
    $baseName = basename($originalStoredFileName);
1199
    // Skip files
1200
    $skipFiles = [
1201
        '__MACOSX',
1202
        '.Thumbs.db',
1203
        'Thumbs.db',
1204
    ];
1205
    if (in_array($baseName, $skipFiles)) {
1206
        return 0;
1207
    }
1208
    $modifiedStoredFileName = clean_up_path($originalStoredFileName);
1209
    $p_header['filename'] = str_replace($originalStoredFileName, $modifiedStoredFileName, $p_header['filename']);
1210
1211
    return 1;
1212
}
1213
1214
/**
1215
 * This function cleans up a given path
1216
 * by eliminating dangerous file names and cleaning them.
1217
 *
1218
 * @param string $path
1219
 *
1220
 * @return string
1221
 *
1222
 * @see disable_dangerous_file()
1223
 * @see api_replace_dangerous_char()
1224
 */
1225
function clean_up_path($path)
1226
{
1227
    // Split the path in folders and files
1228
    $path_array = explode('/', $path);
1229
    // Clean up every folder and filename in the path
1230
    foreach ($path_array as $key => &$val) {
1231
        // We don't want to lose the dots in ././folder/file (cfr. zipfile)
1232
        if ($val != '.') {
1233
            $val = disable_dangerous_file(api_replace_dangerous_char($val));
1234
        }
1235
    }
1236
    // Join the "cleaned" path (modified in-place as passed by reference)
1237
    $path = implode('/', $path_array);
1238
    filter_extension($path);
1239
1240
    return $path;
1241
}
1242
1243
/**
1244
 * Checks if the file is dangerous, based on extension and/or mimetype.
1245
 * The list of extensions accepted/rejected can be found from
1246
 * api_get_setting('upload_extensions_exclude') and api_get_setting('upload_extensions_include').
1247
 *
1248
 * @param string $filename passed by reference. The filename will be modified
1249
 *                         if filter rules say so! (you can include path but the filename should look like 'abc.html')
1250
 *
1251
 * @return int 0 to skip file, 1 to keep file
1252
 */
1253
function filter_extension(&$filename)
1254
{
1255
    if (substr($filename, -1) == '/') {
1256
        return 1; // Authorize directories
1257
    }
1258
    $blacklist = api_get_setting('upload_extensions_list_type');
1259
    if ($blacklist != 'whitelist') { // if = blacklist
1260
        $extensions = explode(';', strtolower(api_get_setting('upload_extensions_blacklist')));
1261
1262
        $skip = api_get_setting('upload_extensions_skip');
1263
        $ext = strrchr($filename, '.');
1264
        $ext = substr($ext, 1);
1265
        if (empty($ext)) {
1266
            return 1; // We're in blacklist mode, so accept empty extensions
1267
        }
1268
        if (in_array(strtolower($ext), $extensions)) {
1269
            if ($skip == 'true') {
1270
                return 0;
1271
            } else {
1272
                $new_ext = api_get_setting('upload_extensions_replace_by');
1273
                $filename = str_replace('.'.$ext, '.'.$new_ext, $filename);
1274
1275
                return 1;
1276
            }
1277
        } else {
1278
            return 1;
1279
        }
1280
    } else {
1281
        $extensions = explode(';', strtolower(api_get_setting('upload_extensions_whitelist')));
1282
        $skip = api_get_setting('upload_extensions_skip');
1283
        $ext = strrchr($filename, '.');
1284
        $ext = substr($ext, 1);
1285
        if (empty($ext)) {
1286
            return 1; // Accept empty extensions
1287
        }
1288
        if (!in_array(strtolower($ext), $extensions)) {
1289
            if ($skip == 'true') {
1290
                return 0;
1291
            } else {
1292
                $new_ext = api_get_setting('upload_extensions_replace_by');
1293
                $filename = str_replace('.'.$ext, '.'.$new_ext, $filename);
1294
1295
                return 1;
1296
            }
1297
        } else {
1298
            return 1;
1299
        }
1300
    }
1301
}
1302
1303
/**
1304
 * Adds a new document to the database.
1305
 *
1306
 * @param array  $courseInfo
1307
 * @param string $path
1308
 * @param string $fileType
1309
 * @param int    $fileSize
1310
 * @param string $title
1311
 * @param string $comment
1312
 * @param int    $readonly
1313
 * @param int    $visibility see ResourceLink constants
1314
 * @param int    $group_id         group.id
1315
 * @param int    $sessionId        Session ID, if any
1316
 * @param int    $userId           creator user id
1317
 * @param bool   $sendNotification
1318
 * @param string $content
1319
 * @param int    $parentId
1320
 *
1321
 * @return CDocument|false
1322
 */
1323
function add_document(
1324
    $courseInfo,
1325
    $path,
1326
    $fileType,
1327
    $fileSize,
1328
    $title,
1329
    $comment = null,
1330
    $readonly = 0,
1331
    $visibility = null,
1332
    $group_id = 0,
1333
    $sessionId = 0,
1334
    $userId = 0,
1335
    $sendNotification = true,
1336
    $content = '',
1337
    $parentId = 0
1338
) {
1339
    $sessionId = empty($sessionId) ? api_get_session_id() : $sessionId;
1340
    $userId = empty($userId) ? api_get_user_id() : $userId;
1341
    $userEntity = api_get_user_entity($userId);
1342
    $courseEntity = api_get_course_entity(api_get_course_int_id());
1343
    $session = api_get_session_entity($sessionId);
1344
    $group = api_get_group_entity($group_id);
1345
    $readonly = (int) $readonly;
1346
1347
    $em = Database::getManager();
1348
    $documentRepo = $em->getRepository('ChamiloCourseBundle:CDocument');
1349
1350
    $parentNode = null;
1351
    if (!empty($parentId)) {
1352
        $parent = $documentRepo->find($parentId);
1353
        $parentNode = $parent->getResourceNode();
1354
    }
1355
1356
    $document = new CDocument();
1357
    $document
1358
        ->setCourse($courseEntity)
1359
        ->setPath($path)
1360
        ->setFiletype($fileType)
1361
        ->setSize($fileSize)
1362
        ->setTitle($title)
1363
        ->setComment($comment)
1364
        ->setReadonly($readonly)
1365
        ->setSession($session)
1366
    ;
1367
1368
    $em->persist($document);
1369
    $em->flush();
1370
1371
    $resourceNode = $documentRepo->addResourceNode($document, $userEntity);
1372
    $resourceNode->setParent($parentNode);
1373
    $document->setResourceNode($resourceNode);
1374
1375
    // Only create a ResourseFile and Media if there's a file involved
1376
    if ($fileType === 'file') {
1377
        $mediaManager = Container::$container->get('sonata.media.manager.media');
1378
        /** @var \Chamilo\MediaBundle\Entity\Media $media */
1379
        $media = $mediaManager->create();
1380
        $media->setName($title);
1381
1382
        $fileName = basename($path);
1383
        $extension = pathinfo($fileName, PATHINFO_EXTENSION);
1384
        $media->setContext('default');
1385
1386
        $provider = 'sonata.media.provider.image';
1387
        if (!in_array($extension, ['jpeg', 'jpg', 'gif', 'png'])) {
1388
            $provider = 'sonata.media.provider.file';
1389
        }
1390
1391
        $media->setProviderName($provider);
1392
        $media->setEnabled(true);
1393
1394
        if ($content instanceof UploadedFile) {
1395
            $file = $content;
1396
            $media->setSize($file->getSize());
1397
        } else {
1398
            $handle = tmpfile();
1399
            fwrite($handle, $content);
1400
            $file = new \Sonata\MediaBundle\Extra\ApiMediaFile($handle);
1401
            $file->setMimetype($media->getContentType());
1402
        }
1403
1404
        $media->setBinaryContent($file);
1405
        $mediaManager->save($media, true);
1406
1407
        $resourceFile = new ResourceFile();
1408
        $resourceFile->setMedia($media);
1409
        $resourceFile->setName($title);
1410
        $em->persist($resourceFile);
1411
1412
        $resourceNode->setResourceFile($resourceFile);
1413
        $em->persist($resourceNode);
1414
    }
1415
1416
    // By default visibility is published
1417
    // @todo change visibility
1418
    //$newVisibility = ResourceLink::VISIBILITY_PUBLISHED;
1419
1420
    if (is_null($visibility)) {
1421
        $visibility = ResourceLink::VISIBILITY_PUBLISHED;
1422
    }
1423
1424
    $link = new ResourceLink();
1425
    $link
1426
        ->setCourse($courseEntity)
1427
        ->setSession($session)
1428
        ->setGroup($group)
1429
        //->setUser($toUser)
1430
        ->setResourceNode($resourceNode)
1431
        ->setVisibility($visibility)
1432
    ;
1433
1434
    $rights = [];
1435
    switch ($visibility) {
1436
        case ResourceLink::VISIBILITY_PENDING:
1437
        case ResourceLink::VISIBILITY_DRAFT:
1438
            $editorMask = ResourceNodeVoter::getEditorMask();
1439
            $resourceRight = new ResourceRight();
1440
            $resourceRight
1441
                ->setMask($editorMask)
1442
                ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
1443
            ;
1444
            $rights[] = $resourceRight;
1445
1446
            break;
1447
    }
1448
1449
    if (!empty($rights)) {
1450
        foreach ($rights as $right) {
1451
            $link->addResourceRight($right);
1452
        }
1453
    }
1454
1455
    $em->persist($link);
1456
    $em->persist($document);
1457
    $em->flush();
1458
1459
    $documentId = $document->getIid();
1460
    if ($documentId) {
1461
        $table = Database::get_course_table(TABLE_DOCUMENT);
1462
        $sql = "UPDATE $table SET id = iid WHERE iid = $documentId";
1463
        Database::query($sql);
1464
1465
        /*if ($saveVisibility) {
1466
            api_set_default_visibility(
1467
                $documentId,
1468
                TOOL_DOCUMENT,
1469
                $group_id,
1470
                $courseInfo,
1471
                $sessionId,
1472
                $userId
1473
            );
1474
        }*/
1475
1476
        $allowNotification = api_get_configuration_value('send_notification_when_document_added');
1477
        if ($sendNotification && $allowNotification) {
1478
            $courseTitle = $courseInfo['title'];
1479
            if (!empty($sessionId)) {
1480
                $sessionInfo = api_get_session_info($sessionId);
1481
                $courseTitle .= ' ( '.$sessionInfo['name'].') ';
1482
            }
1483
1484
            $url = api_get_path(WEB_CODE_PATH).
1485
                'document/showinframes.php?cidReq='.$courseInfo['code'].'&id_session='.$sessionId.'&id='.$documentId;
1486
            $link = Display::url(basename($title), $url, ['target' => '_blank']);
1487
            $userInfo = api_get_user_info($userId);
1488
1489
            $message = sprintf(
1490
                get_lang('DocumentXHasBeenAddedToDocumentInYourCourseXByUserX'),
1491
                $link,
1492
                $courseTitle,
1493
                $userInfo['complete_name']
1494
            );
1495
            $subject = sprintf(get_lang('NewDocumentAddedToCourseX'), $courseTitle);
1496
            MessageManager::sendMessageToAllUsersInCourse($subject, $message, $courseInfo, $sessionId);
1497
        }
1498
1499
        return $document;
1500
    }
1501
1502
    return false;
1503
}
1504
1505
/**
1506
 * Updates an existing document in the database
1507
 * as the file exists, we only need to change the size.
1508
 *
1509
 * @param array $_course
1510
 * @param int   $documentId
1511
 * @param int   $filesize
1512
 * @param int   $readonly
1513
 *
1514
 * @return bool true /false
1515
 */
1516
function update_existing_document($_course, $documentId, $filesize, $readonly = 0)
1517
{
1518
    $document_table = Database::get_course_table(TABLE_DOCUMENT);
1519
    $documentId = intval($documentId);
1520
    $filesize = intval($filesize);
1521
    $readonly = intval($readonly);
1522
    $course_id = $_course['real_id'];
1523
1524
    $sql = "UPDATE $document_table SET
1525
            size = '$filesize',
1526
            readonly = '$readonly'
1527
			WHERE c_id = $course_id AND id = $documentId";
1528
    if (Database::query($sql)) {
1529
        return true;
1530
    } else {
1531
        return false;
1532
    }
1533
}
1534
1535
/**
1536
 * This function updates the last_edit_date, last edit user id on all folders in a given path.
1537
 *
1538
 * @param array  $_course
1539
 * @param string $path
1540
 * @param int    $user_id
1541
 */
1542
function item_property_update_on_folder($_course, $path, $user_id)
1543
{
1544
    // If we are in the root, just return... no need to update anything
1545
    if ($path == '/') {
1546
        return;
1547
    }
1548
1549
    $user_id = intval($user_id);
1550
1551
    // If the given path ends with a / we remove it
1552
    $endchar = substr($path, strlen($path) - 1, 1);
1553
    if ($endchar == '/') {
1554
        $path = substr($path, 0, strlen($path) - 1);
1555
    }
1556
1557
    $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1558
1559
    // Get the time
1560
    $time = api_get_utc_datetime();
1561
1562
    // Det all paths in the given path
1563
    // /folder/subfolder/subsubfolder/file
1564
    // if file is updated, subsubfolder, subfolder and folder are updated
1565
    $exploded_path = explode('/', $path);
1566
    $course_id = api_get_course_int_id();
1567
    $newpath = '';
1568
    foreach ($exploded_path as $key => &$value) {
1569
        // We don't want a slash before our first slash
1570
        if ($key != 0) {
1571
            $newpath .= '/'.$value;
1572
            // Select ID of given folder
1573
            $folder_id = DocumentManager::get_document_id($_course, $newpath);
1574
1575
            if ($folder_id) {
1576
                $sql = "UPDATE $table SET
1577
				        lastedit_date = '$time',
1578
				        lastedit_type = 'DocumentInFolderUpdated', 
1579
				        lastedit_user_id='$user_id'
1580
						WHERE 
1581
						    c_id = $course_id AND 
1582
						    tool='".TOOL_DOCUMENT."' AND 
1583
						    ref = '$folder_id'";
1584
                Database::query($sql);
1585
            }
1586
        }
1587
    }
1588
}
1589
1590
/**
1591
 * Adds file to document table in database
1592
 * deprecated: use file_set_default_settings instead.
1593
 *
1594
 * @author	Olivier Cauberghe <[email protected]>
1595
 *
1596
 * @param	path,filename
1597
 * action:	Adds an entry to the document table with the default settings
1598
 */
1599
function set_default_settings($upload_path, $filename, $filetype = 'file')
1600
{
1601
    $dbTable = Database::get_course_table(TABLE_DOCUMENT);
1602
    global $default_visibility;
1603
1604
    if (!$default_visibility) {
1605
        $default_visibility = 'v';
1606
    }
1607
    $filetype = Database::escape_string($filetype);
1608
1609
    $upload_path = str_replace('\\', '/', $upload_path);
1610
    $upload_path = str_replace('//', '/', $upload_path);
1611
1612
    if ($upload_path == '/') {
1613
        $upload_path = '';
1614
    } elseif (!empty($upload_path) && $upload_path[0] != '/') {
1615
        $upload_path = "/$upload_path";
1616
    }
1617
1618
    $endchar = substr($filename, strlen($filename) - 1, 1);
1619
1620
    if ($endchar == '/') {
1621
        $filename = substr($filename, 0, -1);
1622
    }
1623
    $filename = Database::escape_string($filename);
1624
    $query = "SELECT count(*) as bestaat FROM $dbTable
1625
              WHERE path='$upload_path/$filename'";
1626
    $result = Database::query($query);
1627
    $row = Database::fetch_array($result);
1628
    if ($row['bestaat'] > 0) {
1629
        $query = "UPDATE $dbTable SET
1630
		            path='$upload_path/$filename',
1631
		            visibility='$default_visibility',
1632
		            filetype='$filetype'
1633
		          WHERE path='$upload_path/$filename'";
1634
    } else {
1635
        $query = "INSERT INTO $dbTable (path,visibility,filetype)
1636
		          VALUES('$upload_path/$filename','$default_visibility','$filetype')";
1637
    }
1638
    Database::query($query);
1639
}
1640
1641
/**
1642
 * Retrieves the image path list in a html file.
1643
 *
1644
 * @author Hugues Peeters <[email protected]>
1645
 *
1646
 * @param string $html_file
1647
 *
1648
 * @return array -  images path list
1649
 */
1650
function search_img_from_html($html_file)
1651
{
1652
    $img_path_list = [];
1653
1654
    if (!$fp = fopen($html_file, 'r')) {
1655
        return;
1656
    }
1657
1658
    // Aearch and store occurences of the <img> tag in an array
1659
    $size_file = (filesize($html_file) === 0) ? 1 : filesize($html_file);
1660
    if (isset($fp) && $fp !== false) {
1661
        $buffer = fread($fp, $size_file);
1662
        if (strlen($buffer) >= 0 && $buffer !== false) {
1663
        } else {
1664
            die('<center>Can not read file.</center>');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1665
        }
1666
    } else {
1667
        die('<center>Can not read file.</center>');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
1668
    }
1669
    $matches = [];
1670
    if (preg_match_all('~<[[:space:]]*img[^>]*>~i', $buffer, $matches)) {
1671
        $img_tag_list = $matches[0];
1672
    }
1673
1674
    fclose($fp);
1675
    unset($buffer);
1676
1677
    // Search the image file path from all the <IMG> tag detected
1678
1679
    if (sizeof($img_tag_list) > 0) {
1680
        foreach ($img_tag_list as &$this_img_tag) {
1681
            if (preg_match('~src[[:space:]]*=[[:space:]]*[\"]{1}([^\"]+)[\"]{1}~i', $this_img_tag, $matches)) {
1682
                $img_path_list[] = $matches[1];
1683
            }
1684
        }
1685
        $img_path_list = array_unique($img_path_list); // Remove duplicate entries
1686
    }
1687
1688
    return $img_path_list;
1689
}
1690
1691
/**
1692
 * Creates a new directory trying to find a directory name
1693
 * that doesn't already exist.
1694
 *
1695
 * @author  Hugues Peeters <[email protected]>
1696
 * @author  Bert Vanderkimpen
1697
 *
1698
 * @param array  $_course                 current course information
1699
 * @param int    $user_id                 current user id
1700
 * @param int    $session_id
1701
 * @param int    $to_group_id             group.id
1702
 * @param int    $to_user_id
1703
 * @param string $base_work_dir           /var/www/chamilo/courses/ABC/document
1704
 * @param string $desired_dir_name        complete path of the desired name
1705
 *                                        Example: /folder1/folder2
1706
 * @param string $title                   "folder2"
1707
 * @param int    $visibility              (0 for invisible, 1 for visible, 2 for deleted)
1708
 * @param bool   $generateNewNameIfExists
1709
 * @param bool   $sendNotification        depends in conf setting "send_notification_when_document_added"
1710
 *
1711
 * @return string actual directory name if it succeeds,
1712
 *                boolean false otherwise
1713
 */
1714
function create_unexisting_directory(
1715
    $_course,
1716
    $user_id,
1717
    $session_id,
1718
    $to_group_id,
1719
    $to_user_id,
1720
    $base_work_dir,
1721
    $desired_dir_name,
1722
    $title = '',
1723
    $visibility = '',
1724
    $generateNewNameIfExists = false,
1725
    $sendNotification = true
1726
) {
1727
    $course_id = $_course['real_id'];
1728
    $session_id = (int) $session_id;
1729
1730
    $folderExists = DocumentManager::folderExists(
1731
        $desired_dir_name,
1732
        $_course,
1733
        $session_id,
1734
        $to_group_id
1735
    );
1736
1737
    if ($folderExists === true) {
1738
        if ($generateNewNameIfExists) {
1739
            $counter = 1;
1740
            while (1) {
1741
                $folderExists = DocumentManager::folderExists(
1742
                    $desired_dir_name.'_'.$counter,
1743
                    $_course,
1744
                    $session_id,
1745
                    $to_group_id
1746
                );
1747
1748
                if ($folderExists === false) {
1749
                    break;
1750
                }
1751
                $counter++;
1752
            }
1753
            $desired_dir_name = $desired_dir_name.'_'.$counter;
1754
        } else {
1755
            return false;
1756
        }
1757
    }
1758
1759
    $systemFolderName = $desired_dir_name;
1760
1761
    // Adding suffix
1762
    $suffix = DocumentManager::getDocumentSuffix(
1763
        $_course,
1764
        $session_id,
1765
        $to_group_id
1766
    );
1767
1768
    $systemFolderName .= $suffix;
1769
1770
    if ($title == null) {
1771
        $title = basename($desired_dir_name);
1772
    }
1773
1774
    if (!is_dir($base_work_dir.$systemFolderName)) {
1775
        $result = mkdir(
1776
            $base_work_dir.$systemFolderName,
1777
            api_get_permissions_for_new_directories(),
1778
            true
1779
        );
1780
1781
        if ($result) {
1782
            // Check if pathname already exists inside document table
1783
            $tbl_document = Database::get_course_table(TABLE_DOCUMENT);
1784
            $sql = "SELECT id, path FROM $tbl_document
1785
                    WHERE
1786
                        c_id = $course_id AND
1787
                        (
1788
                            path = '".Database::escape_string($systemFolderName)."'
1789
                        )
1790
            ";
1791
1792
            $groupInfo = [];
1793
            if (!empty($to_group_id)) {
1794
                $groupInfo = GroupManager::get_group_properties($to_group_id);
1795
            }
1796
1797
            $rs = Database::query($sql);
1798
            if (Database::num_rows($rs) == 0) {
1799
                $document = add_document(
1800
                    $_course,
1801
                    $systemFolderName,
1802
                    'folder',
1803
                    0,
1804
                    $title,
1805
                    null,
1806
                    0,
1807
                    true,
1808
                    $to_group_id,
1809
                    $session_id,
1810
                    $user_id,
1811
                    $sendNotification
1812
                );
1813
1814
                if ($document) {
1815
                    // Update document item_property
1816
                    /*if (!empty($visibility)) {
1817
                        $visibilities = [
1818
                            0 => 'invisible',
1819
                            1 => 'visible',
1820
                            2 => 'delete',
1821
                        ];
1822
                        api_item_property_update(
1823
                            $_course,
1824
                            TOOL_DOCUMENT,
1825
                            $document_id,
1826
                            $visibilities[$visibility],
1827
                            $user_id,
1828
                            $groupInfo,
1829
                            $to_user_id,
1830
                            null,
1831
                            null,
1832
                            $session_id
1833
                        );
1834
                    } else {
1835
                        api_item_property_update(
1836
                            $_course,
1837
                            TOOL_DOCUMENT,
1838
                            $document_id,
1839
                            'FolderCreated',
1840
                            $user_id,
1841
                            $groupInfo,
1842
                            $to_user_id,
1843
                            null,
1844
                            null,
1845
                            $session_id
1846
                        );
1847
                    }*/
1848
1849
                    return $document;
1850
                }
1851
            } else {
1852
                $document = Database::fetch_array($rs);
1853
                $documentData = DocumentManager::get_document_data_by_id(
1854
                    $document['id'],
1855
                    $_course['code'],
1856
                    false,
1857
                    $session_id
1858
                );
1859
1860
                /* This means the folder NOT exist in the filesystem
1861
                 (now this was created) but there is a record in the Database*/
1862
1863
                return $documentData;
1864
            }
1865
        }
1866
    }
1867
1868
    return false;
1869
}
1870
1871
/**
1872
 * Handles uploaded missing images.
1873
 *
1874
 * @author Hugues Peeters <[email protected]>
1875
 * @author Bert Vanderkimpen
1876
 *
1877
 * @param array  $_course
1878
 * @param array  $uploaded_file_collection - follows the $_FILES Structure
1879
 * @param string $base_work_dir
1880
 * @param string $missing_files_dir
1881
 * @param int    $user_id
1882
 * @param int    $to_group_id              group.id
1883
 */
1884
function move_uploaded_file_collection_into_directory(
1885
    $_course,
1886
    $uploaded_file_collection,
1887
    $base_work_dir,
1888
    $missing_files_dir,
1889
    $user_id,
1890
    $to_group_id,
1891
    $to_user_id,
1892
    $max_filled_space
1893
) {
1894
    $number_of_uploaded_images = count($uploaded_file_collection['name']);
1895
    $new_file_list = [];
1896
    for ($i = 0; $i < $number_of_uploaded_images; $i++) {
1897
        $missing_file['name'] = $uploaded_file_collection['name'][$i];
1898
        $missing_file['type'] = $uploaded_file_collection['type'][$i];
1899
        $missing_file['tmp_name'] = $uploaded_file_collection['tmp_name'][$i];
1900
        $missing_file['error'] = $uploaded_file_collection['error'][$i];
1901
        $missing_file['size'] = $uploaded_file_collection['size'][$i];
1902
1903
        $upload_ok = process_uploaded_file($missing_file);
1904
        if ($upload_ok) {
1905
            $new_file_list[] = handle_uploaded_document(
1906
                $_course,
1907
                $missing_file,
1908
                $base_work_dir,
1909
                $missing_files_dir,
1910
                $user_id,
1911
                $to_group_id,
1912
                $to_user_id,
1913
                $max_filled_space,
1914
                0,
1915
                'overwrite'
1916
            );
1917
        }
1918
        unset($missing_file);
1919
    }
1920
1921
    return $new_file_list;
1922
}
1923
1924
/**
1925
 * Opens the old html file and replace the src path into the img tag
1926
 * This also works for files in subdirectories.
1927
 *
1928
 * @param $original_img_path is an array
1929
 * @param $new_img_path is an array
1930
 */
1931
function replace_img_path_in_html_file($original_img_path, $new_img_path, $html_file)
1932
{
1933
    // Open the file
1934
    $fp = fopen($html_file, 'r');
1935
    $buffer = fread($fp, filesize($html_file));
1936
    $new_html_content = '';
1937
1938
    // Fix the image tags
1939
    for ($i = 0, $fileNb = count($original_img_path); $i < $fileNb; $i++) {
1940
        $replace_what = $original_img_path[$i];
1941
        // We only need the directory and the filename /path/to/file_html_files/missing_file.gif -> file_html_files/missing_file.gif
1942
        $exploded_file_path = explode('/', $new_img_path[$i]);
1943
        $replace_by = $exploded_file_path[count($exploded_file_path) - 2].'/'.$exploded_file_path[count($exploded_file_path) - 1];
1944
        $buffer = str_replace($replace_what, $replace_by, $buffer);
1945
    }
1946
1947
    $new_html_content .= $buffer;
1948
1949
    @fclose($fp);
1950
1951
    // Write the resulted new file
1952
1953
    if (!$fp = fopen($html_file, 'w')) {
1954
        return;
1955
    }
1956
1957
    if (!fwrite($fp, $new_html_content)) {
1958
        return;
1959
    }
1960
}
1961
1962
/**
1963
 * Checks the extension of a file, if it's .htm or .html
1964
 * we use search_img_from_html to get all image paths in the file.
1965
 *
1966
 * @param string $file
1967
 *
1968
 * @return array paths
1969
 *
1970
 * @see check_for_missing_files() uses search_img_from_html()
1971
 */
1972
function check_for_missing_files($file)
1973
{
1974
    if (strrchr($file, '.') == '.htm' || strrchr($file, '.') == '.html') {
1975
        $img_file_path = search_img_from_html($file);
1976
1977
        return $img_file_path;
1978
    }
1979
1980
    return false;
1981
}
1982
1983
/**
1984
 * This function builds a form that asks for the missing images in a html file
1985
 * maybe we should do this another way?
1986
 *
1987
 * @param array  $missing_files
1988
 * @param string $upload_path
1989
 * @param string $file_name
1990
 *
1991
 * @return string the form
1992
 */
1993
function build_missing_files_form($missing_files, $upload_path, $file_name)
1994
{
1995
    // Do we need a / or not?
1996
    $added_slash = ($upload_path == '/') ? '' : '/';
1997
    $folder_id = DocumentManager::get_document_id(api_get_course_info(), $upload_path);
1998
    // Build the form
1999
    $form = "<p><strong>".get_lang('MissingImagesDetected')."</strong></p>"
2000
        ."<form method=\"post\" action=\"".api_get_self()."\" enctype=\"multipart/form-data\">"
2001
        // Related_file is the path to the file that has missing images
2002
        ."<input type=\"hidden\" name=\"related_file\" value=\"".$upload_path.$added_slash.$file_name."\" />"
2003
        ."<input type=\"hidden\" name=\"upload_path\" value=\"".$upload_path."\" />"
2004
        ."<input type=\"hidden\" name=\"id\" value=\"".$folder_id."\" />"
2005
        ."<table border=\"0\">";
2006
    foreach ($missing_files as &$this_img_file_path) {
2007
        $form .= "<tr>"
2008
            ."<td>".basename($this_img_file_path)." : </td>"
2009
            ."<td>"
2010
            ."<input type=\"file\" name=\"img_file[]\"/>"
2011
            ."<input type=\"hidden\" name=\"img_file_path[]\" value=\"".$this_img_file_path."\" />"
2012
            ."</td>"
2013
            ."</tr>";
2014
    }
2015
    $form .= "</table>"
2016
        ."<button type='submit' name=\"cancel_submit_image\" value=\"".get_lang('Cancel')."\" class=\"cancel\">".get_lang('Cancel')."</button>"
2017
        ."<button type='submit' name=\"submit_image\" value=\"".get_lang('Ok')."\" class=\"save\">".get_lang('Ok')."</button>"
2018
        ."</form>";
2019
2020
    return $form;
2021
}
2022
2023
/**
2024
 * This recursive function can be used during the upgrade process form older
2025
 * versions of Chamilo
2026
 * It crawls the given directory, checks if the file is in the DB and adds
2027
 * it if it's not.
2028
 *
2029
 * @param array  $courseInfo
2030
 * @param array  $userInfo
2031
 * @param string $base_work_dir    course document dir
2032
 * @param string $folderPath       folder to read
2033
 * @param int    $sessionId
2034
 * @param int    $groupId          group.id
2035
 * @param bool   $output
2036
 * @param array  $parent
2037
 * @param string $whatIfFileExists
2038
 *
2039
 * @return bool
2040
 */
2041
function add_all_documents_in_folder_to_database(
2042
    $courseInfo,
2043
    $userInfo,
2044
    $base_work_dir,
2045
    $folderPath,
2046
    $sessionId = 0,
2047
    $groupId = 0,
2048
    $output = false,
2049
    $parent = [],
2050
    $whatIfFileExists = 'overwrite'
2051
) {
2052
    if (empty($userInfo) || empty($courseInfo)) {
2053
        return false;
2054
    }
2055
2056
    $userId = $userInfo['user_id'];
2057
2058
    // Open dir
2059
    $handle = opendir($folderPath);
2060
2061
    if (is_dir($folderPath)) {
2062
        // Run trough
2063
        while ($file = readdir($handle)) {
2064
            if ($file == '.' || $file == '..') {
2065
                continue;
2066
            }
2067
2068
            $parentPath = '';
2069
            if (!empty($parent) && isset($parent['path'])) {
2070
                $parentPath = $parent['path'];
2071
                if ($parentPath == '/') {
2072
                    $parentPath = '';
2073
                }
2074
            }
2075
2076
            $completePath = $parentPath.'/'.$file;
2077
            $sysFolderPath = $folderPath.'/'.$file;
2078
2079
            // Is directory?
2080
            if (is_dir($sysFolderPath)) {
2081
                $folderExists = DocumentManager::folderExists(
2082
                    $completePath,
2083
                    $courseInfo,
2084
                    $sessionId,
2085
                    $groupId
2086
                );
2087
2088
                if ($folderExists === true) {
2089
                    switch ($whatIfFileExists) {
2090
                        case 'overwrite':
2091
                            $documentId = DocumentManager::get_document_id($courseInfo, $completePath, $sessionId);
2092
                            if ($documentId) {
2093
                                $newFolderData = DocumentManager::get_document_data_by_id(
2094
                                    $documentId,
2095
                                    $courseInfo['code'],
2096
                                    false,
2097
                                    $sessionId
2098
                                );
2099
                            }
2100
                            break;
2101
                        case 'rename':
2102
                            $newFolderData = create_unexisting_directory(
2103
                                $courseInfo,
2104
                                $userId,
2105
                                $sessionId,
2106
                                $groupId,
2107
                                null,
2108
                                $base_work_dir,
2109
                                $completePath,
2110
                                null,
2111
                                null,
2112
                                true
2113
                            );
2114
                            break;
2115
                        case 'nothing':
2116
                            if ($output) {
2117
                                $documentId = DocumentManager::get_document_id($courseInfo, $completePath, $sessionId);
2118
                                if ($documentId) {
2119
                                    $folderData = DocumentManager::get_document_data_by_id(
2120
                                        $documentId,
2121
                                        $courseInfo['code'],
2122
                                        false,
2123
                                        $sessionId
2124
                                    );
2125
                                    Display::addFlash(
2126
                                        Display::return_message(
2127
                                            $folderData['path'].' '.get_lang('UplAlreadyExists'),
2128
                                            'warning'
2129
                                        )
2130
                                    );
2131
                                }
2132
                            }
2133
                            continue 2;
2134
                            break;
2135
                    }
2136
                } else {
2137
                    $newFolderData = create_unexisting_directory(
2138
                        $courseInfo,
2139
                        $userId,
2140
                        $sessionId,
2141
                        $groupId,
2142
                        null,
2143
                        $base_work_dir,
2144
                        $completePath,
2145
                        null,
2146
                        null,
2147
                        false
2148
                    );
2149
                }
2150
2151
                // Recursive
2152
                add_all_documents_in_folder_to_database(
2153
                    $courseInfo,
2154
                    $userInfo,
2155
                    $base_work_dir,
2156
                    $sysFolderPath,
2157
                    $sessionId,
2158
                    $groupId,
2159
                    $output,
2160
                    $newFolderData,
2161
                    $whatIfFileExists
2162
                );
2163
            } else {
2164
                // Rename
2165
                $uploadedFile = [
2166
                    'name' => $file,
2167
                    'tmp_name' => $sysFolderPath,
2168
                    'size' => filesize($sysFolderPath),
2169
                    'type' => null,
2170
                    'from_file' => true,
2171
                    'move_file' => true,
2172
                ];
2173
2174
                handle_uploaded_document(
2175
                    $courseInfo,
2176
                    $uploadedFile,
2177
                    $base_work_dir,
2178
                    $parentPath,
2179
                    $userId,
2180
                    $groupId,
2181
                    null,
2182
                    0,
2183
                    $whatIfFileExists,
2184
                    $output,
2185
                    false,
2186
                    null,
2187
                    $sessionId
2188
                );
2189
            }
2190
        }
2191
    }
2192
}
2193