Passed
Push — 1.11.x ( dda33d...44aaa1 )
by Julito
29:19 queued 12s
created

unzip_uploaded_document()   B

Complexity

Conditions 9
Paths 11

Size

Total Lines 70
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 36
nc 11
nop 11
dl 0
loc 70
rs 8.0555
c 0
b 0
f 0

How to fix   Long Method    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
/**
5
 * FILE UPLOAD LIBRARY.
6
 *
7
 * This is the file upload library for Chamilo.
8
 * Include/require it in your code to use its functionality.
9
 *
10
 * @package chamilo.library
11
 *
12
 * @todo test and reorganise
13
 */
14
15
/**
16
 * Changes the file name extension from .php to .phps
17
 * Useful for securing a site.
18
 *
19
 * @author Hugues Peeters <[email protected]>
20
 *
21
 * @param string $file_name Name of a file
22
 *
23
 * @return string the filename phps'ized
24
 */
25
function php2phps($file_name)
26
{
27
    return preg_replace('/\.(phar.?|php.?|phtml.?)(\.){0,1}.*$/i', '.phps', $file_name);
28
}
29
30
/**
31
 * Renames .htaccess & .HTACCESS to htaccess.txt.
32
 *
33
 * @param string $filename
34
 *
35
 * @return string
36
 */
37
function htaccess2txt($filename)
38
{
39
    return str_replace(['.htaccess', '.HTACCESS'], ['htaccess.txt', 'htaccess.txt'], $filename);
40
}
41
42
/**
43
 * This function executes our safety precautions
44
 * more functions can be added.
45
 *
46
 * @param string $filename
47
 *
48
 * @return string
49
 *
50
 * @see php2phps()
51
 * @see htaccess2txt()
52
 */
53
function disable_dangerous_file($filename)
54
{
55
    return htaccess2txt(php2phps($filename));
56
}
57
58
/**
59
 * Returns the name without extension, used for the title.
60
 *
61
 * @param string $name
62
 *
63
 * @return name without the extension
64
 */
65
function get_document_title($name)
66
{
67
    // If they upload .htaccess...
68
    $name = disable_dangerous_file($name);
69
    $ext = substr(strrchr($name, '.'), 0);
70
71
    if (empty($ext)) {
72
        return substr($name, 0, strlen($name));
73
    }
74
75
    return substr($name, 0, strlen($name) - strlen(strstr($name, $ext)));
76
}
77
78
/**
79
 * This function checks if the upload succeeded.
80
 *
81
 * @param array $uploaded_file ($_FILES)
82
 *
83
 * @return true if upload succeeded
84
 */
85
function process_uploaded_file($uploaded_file, $show_output = true)
86
{
87
    // Checking the error code sent with the file upload.
88
    if (isset($uploaded_file['error'])) {
89
        switch ($uploaded_file['error']) {
90
            case 1:
91
                // The uploaded file exceeds the upload_max_filesize directive in php.ini.
92
                if ($show_output) {
93
                    Display::addFlash(
94
                        Display::return_message(
95
                            get_lang('UplExceedMaxServerUpload').ini_get('upload_max_filesize'),
96
                            'error'
97
                        )
98
                    );
99
                }
100
101
                return false;
102
            case 2:
103
                // The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.
104
                // Not used at the moment, but could be handy if we want to limit the size of an upload
105
                // (e.g. image upload in html editor).
106
                $max_file_size = (int) $_POST['MAX_FILE_SIZE'];
107
                if ($show_output) {
108
                    Display::addFlash(
109
                        Display::return_message(
110
                            get_lang('UplExceedMaxPostSize').format_file_size($max_file_size),
111
                            'error'
112
                        )
113
                    );
114
                }
115
116
                return false;
117
            case 3:
118
                // The uploaded file was only partially uploaded.
119
                if ($show_output) {
120
                    Display::addFlash(
121
                        Display::return_message(
122
                            get_lang('UplPartialUpload').' '.get_lang('PleaseTryAgain'),
123
                            'error'
124
                        )
125
                    );
126
                }
127
128
                return false;
129
            case 4:
130
                // No file was uploaded.
131
                if ($show_output) {
132
                    Display::addFlash(
133
                        Display::return_message(
134
                            get_lang('UplNoFileUploaded').' '.get_lang('UplSelectFileFirst'),
135
                            'error'
136
                        )
137
                    );
138
                }
139
140
                return false;
141
        }
142
    }
143
144
    if (!file_exists($uploaded_file['tmp_name'])) {
145
        // No file was uploaded.
146
        if ($show_output) {
147
            Display::addFlash(Display::return_message(get_lang('UplUploadFailed'), 'error'));
148
        }
149
150
        return false;
151
    }
152
153
    if (file_exists($uploaded_file['tmp_name'])) {
154
        $filesize = filesize($uploaded_file['tmp_name']);
155
        if (empty($filesize)) {
156
            // No file was uploaded.
157
            if ($show_output) {
158
                Display::addFlash(
159
                    Display::return_message(
160
                        get_lang('UplUploadFailedSizeIsZero'),
161
                        'error'
162
                    )
163
                );
164
            }
165
166
            return false;
167
        }
168
    }
169
170
    $course_id = api_get_course_id();
171
172
    //Checking course quota if we are in a course
173
    if (!empty($course_id)) {
174
        $max_filled_space = DocumentManager::get_course_quota();
175
        // Check if there is enough space to save the file
176
        if (!DocumentManager::enough_space($uploaded_file['size'], $max_filled_space)) {
177
            if ($show_output) {
178
                Display::addFlash(
179
                    Display::return_message(
180
                        get_lang('UplNotEnoughSpace'),
181
                        'error'
182
                    )
183
                );
184
            }
185
186
            return false;
187
        }
188
    }
189
190
    // case 0: default: We assume there is no error, the file uploaded with success.
191
    return true;
192
}
193
194
/**
195
 * This function does the save-work for the documents.
196
 * It handles the uploaded file and adds the properties to the database
197
 * If unzip=1 and the file is a zipfile, it is extracted
198
 * If we decide to save ALL kinds of documents in one database,
199
 * we could extend this with a $type='document', 'scormdocument',...
200
 *
201
 * @param array  $courseInfo
202
 * @param array  $uploadedFile            ($_FILES)
203
 *                                        array(
204
 *                                        'name' => 'picture.jpg',
205
 *                                        'tmp_name' => '...', // absolute path
206
 *                                        );
207
 * @param string $documentDir             Example: /var/www/chamilo/courses/ABC/document
208
 * @param string $uploadPath              Example: /folder1/folder2/
209
 * @param int    $userId
210
 * @param int    $groupId                 group.id
211
 * @param int    $toUserId                User ID, or NULL for everybody
212
 * @param int    $unzip                   1/0
213
 * @param string $whatIfFileExists        overwrite, rename or warn if exists (default)
214
 * @param bool   $output                  optional output parameter
215
 * @param bool   $onlyUploadFile
216
 * @param string $comment
217
 * @param int    $sessionId
218
 * @param bool   $treat_spaces_as_hyphens
219
 *
220
 * So far only use for unzip_uploaded_document function.
221
 * If no output wanted on success, set to false.
222
 *
223
 * @return string path of the saved file
224
 */
225
function handle_uploaded_document(
226
    $courseInfo,
227
    $uploadedFile,
228
    $documentDir,
229
    $uploadPath,
230
    $userId,
231
    $groupId = 0,
232
    $toUserId = null,
233
    $unzip = 0,
234
    $whatIfFileExists = '',
235
    $output = true,
236
    $onlyUploadFile = false,
237
    $comment = null,
238
    $sessionId = null,
239
    $treat_spaces_as_hyphens = true
240
) {
241
    if (empty($uploadedFile) || empty($userId) || empty($courseInfo) || empty($documentDir) || empty($uploadPath)) {
242
        return false;
243
    }
244
245
    $userInfo = api_get_user_info();
246
    $uploadedFile['name'] = stripslashes($uploadedFile['name']);
247
    // Add extension to files without one (if possible)
248
    $uploadedFile['name'] = add_ext_on_mime($uploadedFile['name'], $uploadedFile['type']);
249
    $sessionId = (int) $sessionId;
250
    if (empty($sessionId)) {
251
        $sessionId = api_get_session_id();
252
    }
253
254
    $groupInfo = [];
255
    if (!empty($groupId)) {
256
        $groupInfo = GroupManager::get_group_properties($groupId);
257
    }
258
259
    // Just in case process_uploaded_file is not called
260
    $maxSpace = DocumentManager::get_course_quota();
261
    // Check if there is enough space to save the file
262
    if (!DocumentManager::enough_space($uploadedFile['size'], $maxSpace)) {
263
        if ($output) {
264
            Display::addFlash(Display::return_message(get_lang('UplNotEnoughSpace'), 'error'));
265
        }
266
267
        return false;
268
    }
269
270
    if ($uploadPath !== '/') {
271
        $uploadPath = $uploadPath.'/';
272
    }
273
274
    if (!Security::check_abs_path($documentDir.$uploadPath, $documentDir.'/')) {
275
        Display::addFlash(
276
            Display::return_message(
277
                get_lang('Forbidden'),
278
                'error'
279
            )
280
        );
281
        return false;
282
    }
283
284
285
    // If the want to unzip, check if the file has a .zip (or ZIP,Zip,ZiP,...) extension
286
    if ($unzip == 1 && preg_match('/.zip$/', strtolower($uploadedFile['name']))) {
287
        return unzip_uploaded_document(
288
            $courseInfo,
289
            $userInfo,
290
            $uploadedFile,
291
            $uploadPath,
292
            $documentDir,
293
            $maxSpace,
294
            $sessionId,
295
            $groupId,
296
            $output,
297
            $onlyUploadFile,
298
            $whatIfFileExists
299
        );
300
    } elseif ($unzip == 1 && !preg_match('/.zip$/', strtolower($uploadedFile['name']))) {
301
        // We can only unzip ZIP files (no gz, tar,...)
302
        if ($output) {
303
            Display::addFlash(
304
                Display::return_message(get_lang('UplNotAZip')." ".get_lang('PleaseTryAgain'), 'error')
305
            );
306
        }
307
308
        return false;
309
    } else {
310
        // Clean up the name, only ASCII characters should stay. (and strict)
311
        $cleanName = api_replace_dangerous_char($uploadedFile['name'], $treat_spaces_as_hyphens);
312
313
        // No "dangerous" files
314
        $cleanName = disable_dangerous_file($cleanName);
315
316
        // Checking file extension
317
        if (!filter_extension($cleanName)) {
318
            if ($output) {
319
                Display::addFlash(
320
                    Display::return_message(get_lang('UplUnableToSaveFileFilteredExtension'), 'error')
321
                );
322
            }
323
324
            return false;
325
        } else {
326
            // If the upload path differs from / (= root) it will need a slash at the end
327
            if ($uploadPath !== '/') {
328
                $uploadPath = $uploadPath.'/';
329
            }
330
331
            // Full path to where we want to store the file with trailing slash
332
            $whereToSave = $documentDir.$uploadPath;
333
334
            // At least if the directory doesn't exist, tell so
335
            if (!is_dir($whereToSave)) {
336
                if (!mkdir($whereToSave, api_get_permissions_for_new_directories())) {
337
                    if ($output) {
338
                        Display::addFlash(
339
                            Display::return_message(
340
                                get_lang('DestDirectoryDoesntExist').' ('.$uploadPath.')',
341
                                'error'
342
                            )
343
                        );
344
                    }
345
346
                    return false;
347
                }
348
            }
349
350
            // Just upload the file "as is"
351
            if ($onlyUploadFile) {
352
                $errorResult = moveUploadedFile($uploadedFile, $whereToSave.$cleanName);
353
                if ($errorResult) {
354
                    return $whereToSave.$cleanName;
355
                } else {
356
                    return $errorResult;
357
                }
358
            }
359
360
            /*
361
                Based in the clean name we generate a new filesystem name
362
                Using the session_id and group_id if values are not empty
363
            */
364
            $fileSystemName = DocumentManager::fixDocumentName(
365
                $cleanName,
366
                'file',
367
                $courseInfo,
368
                $sessionId,
369
                $groupId
370
            );
371
372
            // Name of the document without the extension (for the title)
373
            $documentTitle = get_document_title($uploadedFile['name']);
374
375
            // Size of the uploaded file (in bytes)
376
            $fileSize = $uploadedFile['size'];
377
378
            // File permissions
379
            $filePermissions = api_get_permissions_for_new_files();
380
381
            // Example: /var/www/chamilo/courses/xxx/document/folder/picture.jpg
382
            $fullPath = $whereToSave.$fileSystemName;
383
384
            // Example: /folder/picture.jpg
385
            $filePath = $uploadPath.$fileSystemName;
386
387
            $docId = DocumentManager::get_document_id(
388
                $courseInfo,
389
                $filePath,
390
                $sessionId
391
            );
392
393
            // What to do if the target file exists
394
            switch ($whatIfFileExists) {
395
                // Overwrite the file if it exists
396
                case 'overwrite':
397
                    // Check if the target file exists, so we can give another message
398
                    $fileExists = file_exists($fullPath);
399
400
                    if (moveUploadedFile($uploadedFile, $fullPath)) {
401
                        chmod($fullPath, $filePermissions);
402
403
                        if ($fileExists && $docId) {
404
                            // UPDATE DATABASE
405
                            $documentId = DocumentManager::get_document_id(
406
                                $courseInfo,
407
                                $filePath
408
                            );
409
                            if (is_numeric($documentId)) {
410
                                // Update file size
411
                                update_existing_document(
412
                                    $courseInfo,
413
                                    $documentId,
414
                                    $uploadedFile['size']
415
                                );
416
417
                                // Update document item_property
418
                                api_item_property_update(
419
                                    $courseInfo,
420
                                    TOOL_DOCUMENT,
421
                                    $documentId,
422
                                    'DocumentUpdated',
423
                                    $userId,
424
                                    $groupInfo,
425
                                    $toUserId,
426
                                    null,
427
                                    null,
428
                                    $sessionId
429
                                );
430
431
                                // Redo visibility
432
                                api_set_default_visibility(
433
                                    $documentId,
434
                                    TOOL_DOCUMENT,
435
                                    null,
436
                                    $courseInfo
437
                                );
438
                            } else {
439
                                // There might be cases where the file exists on disk but there is no registration of
440
                                // that in the database
441
                                // In this case, and if we are in overwrite mode, overwrite and create the db record
442
                                $documentId = add_document(
443
                                    $courseInfo,
444
                                    $filePath,
445
                                    'file',
446
                                    $fileSize,
447
                                    $documentTitle,
448
                                    $comment,
449
                                    0,
450
                                    true,
451
                                    $groupId,
452
                                    $sessionId
453
                                );
454
455
                                if ($documentId) {
456
                                    // Put the document in item_property update
457
                                    api_item_property_update(
458
                                        $courseInfo,
459
                                        TOOL_DOCUMENT,
460
                                        $documentId,
461
                                        'DocumentAdded',
462
                                        $userId,
463
                                        $groupInfo,
464
                                        $toUserId,
465
                                        null,
466
                                        null,
467
                                        $sessionId
468
                                    );
469
470
                                    // Redo visibility
471
                                    api_set_default_visibility(
472
                                        $documentId,
473
                                        TOOL_DOCUMENT,
474
                                        null,
475
                                        $courseInfo
476
                                    );
477
                                }
478
                            }
479
480
                            // If the file is in a folder, we need to update all parent folders
481
                            item_property_update_on_folder($courseInfo, $uploadPath, $userId);
482
483
                            // Display success message with extra info to user
484
                            if ($output) {
485
                                Display::addFlash(
486
                                    Display::return_message(
487
                                        get_lang('UplUploadSucceeded').'<br /> '.
488
                                        $documentTitle.' '.get_lang('UplFileOverwritten'),
489
                                        'confirmation',
490
                                        false
491
                                    )
492
                                );
493
                            }
494
495
                            return $filePath;
496
                        } else {
497
                            // Put the document data in the database
498
                            $documentId = add_document(
499
                                $courseInfo,
500
                                $filePath,
501
                                'file',
502
                                $fileSize,
503
                                $documentTitle,
504
                                $comment,
505
                                0,
506
                                true,
507
                                $groupId,
508
                                $sessionId
509
                            );
510
511
                            if ($documentId) {
512
                                // Put the document in item_property update
513
                                api_item_property_update(
514
                                    $courseInfo,
515
                                    TOOL_DOCUMENT,
516
                                    $documentId,
517
                                    'DocumentAdded',
518
                                    $userId,
519
                                    $groupInfo,
520
                                    $toUserId,
521
                                    null,
522
                                    null,
523
                                    $sessionId
524
                                );
525
526
                                // Redo visibility
527
                                api_set_default_visibility($documentId, TOOL_DOCUMENT, null, $courseInfo);
528
                            }
529
530
                            // If the file is in a folder, we need to update all parent folders
531
                            item_property_update_on_folder($courseInfo, $uploadPath, $userId);
532
533
                            // Display success message to user
534
                            if ($output) {
535
                                Display::addFlash(
536
                                    Display::return_message(
537
                                        get_lang('UplUploadSucceeded').'<br /> '.$documentTitle,
538
                                        'confirmation',
539
                                        false
540
                                    )
541
                                );
542
                            }
543
544
                            return $filePath;
545
                        }
546
                    } else {
547
                        if ($output) {
548
                            Display::addFlash(
549
                                Display::return_message(
550
                                    get_lang('UplUnableToSaveFile'),
551
                                    'error',
552
                                    false
553
                                )
554
                            );
555
                        }
556
557
                        return false;
558
                    }
559
                    break;
560
                case 'rename':
561
                    // Rename the file if it exists
562
                    // Always rename.
563
                    $cleanName = DocumentManager::getUniqueFileName(
564
                        $uploadPath,
565
                        $cleanName,
566
                        $courseInfo,
567
                        $sessionId,
568
                        $groupId
569
                    );
570
571
                    $fileSystemName = DocumentManager::fixDocumentName(
572
                        $cleanName,
573
                        'file',
574
                        $courseInfo,
575
                        $sessionId,
576
                        $groupId
577
                    );
578
579
                    $documentTitle = disable_dangerous_file($cleanName);
580
                    $fullPath = $whereToSave.$fileSystemName;
581
                    $filePath = $uploadPath.$fileSystemName;
582
583
                    if (moveUploadedFile($uploadedFile, $fullPath)) {
584
                        chmod($fullPath, $filePermissions);
585
                        // Put the document data in the database
586
                        $documentId = add_document(
587
                            $courseInfo,
588
                            $filePath,
589
                            'file',
590
                            $fileSize,
591
                            $documentTitle,
592
                            $comment, // comment
593
                            0, // read only
594
                            true, // save visibility
595
                            $groupId,
596
                            $sessionId
597
                        );
598
599
                        if ($documentId) {
600
                            // Update document item_property
601
                            api_item_property_update(
602
                                $courseInfo,
603
                                TOOL_DOCUMENT,
604
                                $documentId,
605
                                'DocumentAdded',
606
                                $userId,
607
                                $groupInfo,
608
                                $toUserId,
609
                                null,
610
                                null,
611
                                $sessionId
612
                            );
613
614
                            // Redo visibility
615
                            api_set_default_visibility($documentId, TOOL_DOCUMENT, null, $courseInfo);
616
                        }
617
618
                        // If the file is in a folder, we need to update all parent folders
619
                        item_property_update_on_folder($courseInfo, $uploadPath, $userId);
620
621
                        // Display success message to user
622
                        if ($output) {
623
                            Display::addFlash(
624
                                Display::return_message(
625
                                    get_lang('UplUploadSucceeded').'<br />'.
626
                                    get_lang('UplFileSavedAs').' '.$documentTitle,
627
                                    'success',
628
                                    false
629
                                )
630
                            );
631
                        }
632
633
                        return $filePath;
634
                    } else {
635
                        if ($output) {
636
                            Display::addFlash(
637
                                Display::return_message(
638
                                    get_lang('UplUnableToSaveFile'),
639
                                    'error',
640
                                    false
641
                                )
642
                            );
643
                        }
644
645
                        return false;
646
                    }
647
                    break;
648
                case 'nothing':
649
                    $fileExists = file_exists($fullPath);
650
                    if ($fileExists) {
651
                        if ($output) {
652
                            Display::addFlash(
653
                                Display::return_message(
654
                                    $uploadPath.$cleanName.' '.get_lang('UplAlreadyExists'),
655
                                    'warning',
656
                                    false
657
                                )
658
                            );
659
                        }
660
                        break;
661
                    }
662
                    // no break
663
                default:
664
                    // Only save the file if it doesn't exist or warn user if it does exist
665
                    if (file_exists($fullPath) && $docId) {
666
                        if ($output) {
667
                            Display::addFlash(
668
                                Display::return_message($cleanName.' '.get_lang('UplAlreadyExists'), 'warning', false)
669
                            );
670
                        }
671
                    } else {
672
                        if (moveUploadedFile($uploadedFile, $fullPath)) {
673
                            chmod($fullPath, $filePermissions);
674
675
                            // Put the document data in the database
676
                            $documentId = add_document(
677
                                $courseInfo,
678
                                $filePath,
679
                                'file',
680
                                $fileSize,
681
                                $documentTitle,
682
                                $comment,
683
                                0,
684
                                true,
685
                                $groupId,
686
                                $sessionId
687
                            );
688
689
                            if ($documentId) {
690
                                // Update document item_property
691
                                api_item_property_update(
692
                                    $courseInfo,
693
                                    TOOL_DOCUMENT,
694
                                    $documentId,
695
                                    'DocumentAdded',
696
                                    $userId,
697
                                    $groupInfo,
698
                                    $toUserId,
699
                                    null,
700
                                    null,
701
                                    $sessionId
702
                                );
703
                                // Redo visibility
704
                                api_set_default_visibility($documentId, TOOL_DOCUMENT, null, $courseInfo);
705
                            }
706
707
                            // If the file is in a folder, we need to update all parent folders
708
                            item_property_update_on_folder(
709
                                $courseInfo,
710
                                $uploadPath,
711
                                $userId
712
                            );
713
714
                            // Display success message to user
715
                            if ($output) {
716
                                Display::addFlash(
717
                                    Display::return_message(
718
                                        get_lang('UplUploadSucceeded').'<br /> '.$documentTitle,
719
                                        'confirm',
720
                                        false
721
                                    )
722
                                );
723
                            }
724
725
                            return $filePath;
726
                        } else {
727
                            if ($output) {
728
                                Display::addFlash(
729
                                    Display::return_message(
730
                                        get_lang('UplUnableToSaveFile'),
731
                                        'error',
732
                                        false
733
                                    )
734
                                );
735
                            }
736
737
                            return false;
738
                        }
739
                    }
740
                    break;
741
            }
742
        }
743
    }
744
}
745
746
/**
747
 * @param string $file
748
 * @param string $storePath
749
 *
750
 * @return bool
751
 */
752
function moveUploadedFile($file, $storePath)
753
{
754
    $handleFromFile = isset($file['from_file']) && $file['from_file'] ? true : false;
755
    $moveFile = isset($file['move_file']) && $file['move_file'] ? true : false;
756
    if ($moveFile) {
757
        $copied = copy($file['tmp_name'], $storePath);
758
759
        if (!$copied) {
760
            return false;
761
        }
762
    }
763
    if ($handleFromFile) {
764
        return file_exists($file['tmp_name']);
765
    } else {
766
        return move_uploaded_file($file['tmp_name'], $storePath);
767
    }
768
}
769
770
/**
771
 * Checks if there is enough place to add a file on a directory
772
 * on the base of a maximum directory size allowed
773
 * deprecated: use enough_space instead!
774
 *
775
 * @author Hugues Peeters <[email protected]>
776
 *
777
 * @param int    $file_size     Size of the file in byte
778
 * @param string $dir           Path of the directory where the file should be added
779
 * @param int    $max_dir_space Maximum size of the diretory in byte
780
 *
781
 * @return bool true if there is enough space, false otherwise
782
 *
783
 * @see enough_size() uses  dir_total_space() function
784
 */
785
function enough_size($file_size, $dir, $max_dir_space)
786
{
787
    // If the directory is the archive directory, safely ignore the size limit
788
    if (api_get_path(SYS_ARCHIVE_PATH) == $dir) {
789
        return true;
790
    }
791
792
    if ($max_dir_space) {
793
        $already_filled_space = dir_total_space($dir);
794
        if (($file_size + $already_filled_space) > $max_dir_space) {
795
            return false;
796
        }
797
    }
798
799
    return true;
800
}
801
802
/**
803
 * Computes the size already occupied by a directory and is subdirectories.
804
 *
805
 * @author Hugues Peeters <[email protected]>
806
 *
807
 * @param string $dir_path Size of the file in byte
808
 *
809
 * @return int Return the directory size in bytes
810
 */
811
function dir_total_space($dir_path)
812
{
813
    $save_dir = getcwd();
814
    chdir($dir_path);
815
    $handle = opendir($dir_path);
816
    $sumSize = 0;
817
    $dirList = [];
818
    while ($element = readdir($handle)) {
819
        if ($element == '.' || $element == '..') {
820
            continue; // Skip the current and parent directories
821
        }
822
        if (is_file($element)) {
823
            $sumSize += filesize($element);
824
        }
825
        if (is_dir($element)) {
826
            $dirList[] = $dir_path.'/'.$element;
827
        }
828
    }
829
830
    closedir($handle);
831
832
    if (sizeof($dirList) > 0) {
833
        foreach ($dirList as $j) {
834
            $sizeDir = dir_total_space($j); // Recursivity
835
            $sumSize += $sizeDir;
836
        }
837
    }
838
    chdir($save_dir); // Return to initial position
839
840
    return $sumSize;
841
}
842
843
/**
844
 * Tries to add an extension to files without extension
845
 * Some applications on Macintosh computers don't add an extension to the files.
846
 * This subroutine try to fix this on the basis of the MIME type sent
847
 * by the browser.
848
 *
849
 * Note : some browsers don't send the MIME Type (e.g. Netscape 4).
850
 *        We don't have solution for this kind of situation
851
 *
852
 * @author Hugues Peeters <[email protected]>
853
 * @author Bert Vanderkimpen
854
 *
855
 * @param string $file_name Name of the file
856
 * @param string $file_type Type of the file
857
 *
858
 * @return string File name
859
 */
860
function add_ext_on_mime($file_name, $file_type)
861
{
862
    // Check whether the file has an extension AND whether the browser has sent a MIME Type
863
864
    if (!preg_match('/^.*\.[a-zA-Z_0-9]+$/', $file_name) && $file_type) {
865
        // Build a "MIME-types / extensions" connection table
866
        static $mime_type = [];
867
868
        $mime_type[] = 'application/msword';
869
        $extension[] = '.doc';
870
        $mime_type[] = 'application/rtf';
871
        $extension[] = '.rtf';
872
        $mime_type[] = 'application/vnd.ms-powerpoint';
873
        $extension[] = '.ppt';
874
        $mime_type[] = 'application/vnd.ms-excel';
875
        $extension[] = '.xls';
876
        $mime_type[] = 'application/pdf';
877
        $extension[] = '.pdf';
878
        $mime_type[] = 'application/postscript';
879
        $extension[] = '.ps';
880
        $mime_type[] = 'application/mac-binhex40';
881
        $extension[] = '.hqx';
882
        $mime_type[] = 'application/x-gzip';
883
        $extension[] = 'tar.gz';
884
        $mime_type[] = 'application/x-shockwave-flash';
885
        $extension[] = '.swf';
886
        $mime_type[] = 'application/x-stuffit';
887
        $extension[] = '.sit';
888
        $mime_type[] = 'application/x-tar';
889
        $extension[] = '.tar';
890
        $mime_type[] = 'application/zip';
891
        $extension[] = '.zip';
892
        $mime_type[] = 'application/x-tar';
893
        $extension[] = '.tar';
894
        $mime_type[] = 'text/html';
895
        $extension[] = '.html';
896
        $mime_type[] = 'text/plain';
897
        $extension[] = '.txt';
898
        $mime_type[] = 'text/rtf';
899
        $extension[] = '.rtf';
900
        $mime_type[] = 'img/gif';
901
        $extension[] = '.gif';
902
        $mime_type[] = 'img/jpeg';
903
        $extension[] = '.jpg';
904
        $mime_type[] = 'img/png';
905
        $extension[] = '.png';
906
        $mime_type[] = 'audio/midi';
907
        $extension[] = '.mid';
908
        $mime_type[] = 'audio/mpeg';
909
        $extension[] = '.mp3';
910
        $mime_type[] = 'audio/x-aiff';
911
        $extension[] = '.aif';
912
        $mime_type[] = 'audio/x-pn-realaudio';
913
        $extension[] = '.rm';
914
        $mime_type[] = 'audio/x-pn-realaudio-plugin';
915
        $extension[] = '.rpm';
916
        $mime_type[] = 'audio/x-wav';
917
        $extension[] = '.wav';
918
        $mime_type[] = 'video/mpeg';
919
        $extension[] = '.mpg';
920
        $mime_type[] = 'video/mpeg4-generic';
921
        $extension[] = '.mp4';
922
        $mime_type[] = 'video/quicktime';
923
        $extension[] = '.mov';
924
        $mime_type[] = 'video/x-msvideo';
925
        $extension[] = '.avi';
926
927
        $mime_type[] = 'video/x-ms-wmv';
928
        $extension[] = '.wmv';
929
        $mime_type[] = 'video/x-flv';
930
        $extension[] = '.flv';
931
        $mime_type[] = 'image/svg+xml';
932
        $extension[] = '.svg';
933
        $mime_type[] = 'image/svg+xml';
934
        $extension[] = '.svgz';
935
        $mime_type[] = 'video/ogg';
936
        $extension[] = '.ogv';
937
        $mime_type[] = 'audio/ogg';
938
        $extension[] = '.oga';
939
        $mime_type[] = 'application/ogg';
940
        $extension[] = '.ogg';
941
        $mime_type[] = 'application/ogg';
942
        $extension[] = '.ogx';
943
        $mime_type[] = 'application/x-freemind';
944
        $extension[] = '.mm';
945
946
        $mime_type[] = 'application/vnd.ms-word.document.macroEnabled.12';
947
        $extension[] = '.docm';
948
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
949
        $extension[] = '.docx';
950
        $mime_type[] = 'application/vnd.ms-word.template.macroEnabled.12';
951
        $extension[] = '.dotm';
952
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.template';
953
        $extension[] = '.dotx';
954
        $mime_type[] = 'application/vnd.ms-powerpoint.template.macroEnabled.12';
955
        $extension[] = '.potm';
956
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.template';
957
        $extension[] = '.potx';
958
        $mime_type[] = 'application/vnd.ms-powerpoint.addin.macroEnabled.12';
959
        $extension[] = '.ppam';
960
        $mime_type[] = 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12';
961
        $extension[] = '.ppsm';
962
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.slideshow';
963
        $extension[] = '.ppsx';
964
        $mime_type[] = 'application/vnd.ms-powerpoint.presentation.macroEnabled.12';
965
        $extension[] = '.pptm';
966
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
967
        $extension[] = '.pptx';
968
        $mime_type[] = 'application/vnd.ms-excel.addin.macroEnabled.12';
969
        $extension[] = '.xlam';
970
        $mime_type[] = 'application/vnd.ms-excel.sheet.binary.macroEnabled.12';
971
        $extension[] = '.xlsb';
972
        $mime_type[] = 'application/vnd.ms-excel.sheet.macroEnabled.12';
973
        $extension[] = '.xlsm';
974
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
975
        $extension[] = '.xlsx';
976
        $mime_type[] = 'application/vnd.ms-excel.template.macroEnabled.12';
977
        $extension[] = '.xltm';
978
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.template';
979
        $extension[] = '.xltx';
980
981
        // Test on PC (files with no extension get application/octet-stream)
982
        //$mime_type[] = 'application/octet-stream';      $extension[] = '.ext';
983
        // Check whether the MIME type sent by the browser is within the table
984
        foreach ($mime_type as $key => &$type) {
985
            if ($type == $file_type) {
986
                $file_name .= $extension[$key];
987
                break;
988
            }
989
        }
990
991
        unset($mime_type, $extension, $type, $key); // Delete to eschew possible collisions
992
    }
993
994
    return $file_name;
995
}
996
997
/**
998
 * Manages all the unzipping process of an uploaded file.
999
 *
1000
 * @author Hugues Peeters <[email protected]>
1001
 *
1002
 * @param array  $uploaded_file    - follows the $_FILES Structure
1003
 * @param string $upload_path      - destination of the upload.
1004
 *                                 This path is to append to $base_work_dir
1005
 * @param string $base_work_dir    - base working directory of the module
1006
 * @param int    $max_filled_space - amount of bytes to not exceed in the base
1007
 *                                 working directory
1008
 *
1009
 * @return bool true if it succeeds false otherwise
1010
 */
1011
function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_filled_space)
1012
{
1013
    $zip_file = new PclZip($uploaded_file['tmp_name']);
1014
1015
    // Check the zip content (real size and file extension)
1016
    if (file_exists($uploaded_file['tmp_name'])) {
1017
        $zip_content_array = $zip_file->listContent();
1018
        $ok_scorm = false;
1019
        $realFileSize = 0;
1020
        foreach ($zip_content_array as &$this_content) {
1021
            if (preg_match('~.(php.*|phtml)$~i', $this_content['filename'])) {
1022
                Display::addFlash(
1023
                    Display::return_message(get_lang('ZipNoPhp'))
1024
                );
1025
1026
                return false;
1027
            } elseif (stristr($this_content['filename'], 'imsmanifest.xml')) {
1028
                $ok_scorm = true;
1029
            } elseif (stristr($this_content['filename'], 'LMS')) {
1030
                $ok_plantyn_scorm1 = true;
1031
            } elseif (stristr($this_content['filename'], 'REF')) {
1032
                $ok_plantyn_scorm2 = true;
1033
            } elseif (stristr($this_content['filename'], 'SCO')) {
1034
                $ok_plantyn_scorm3 = true;
1035
            } elseif (stristr($this_content['filename'], 'AICC')) {
1036
                $ok_aicc_scorm = true;
1037
            }
1038
            $realFileSize += $this_content['size'];
1039
        }
1040
1041
        if (($ok_plantyn_scorm1 && $ok_plantyn_scorm2 && $ok_plantyn_scorm3) || $ok_aicc_scorm) {
1042
            $ok_scorm = true;
1043
        }
1044
1045
        if (!$ok_scorm && defined('CHECK_FOR_SCORM') && CHECK_FOR_SCORM) {
1046
            Display::addFlash(
1047
                Display::return_message(get_lang('NotScormContent'))
1048
            );
1049
1050
            return false;
1051
        }
1052
1053
        if (!enough_size($realFileSize, $base_work_dir, $max_filled_space)) {
1054
            Display::addFlash(
1055
                Display::return_message(get_lang('NoSpace'))
1056
            );
1057
1058
            return false;
1059
        }
1060
1061
        // It happens on Linux that $upload_path sometimes doesn't start with '/'
1062
        if ($upload_path[0] != '/' && substr($base_work_dir, -1, 1) != '/') {
1063
            $upload_path = '/'.$upload_path;
1064
        }
1065
1066
        if ($upload_path[strlen($upload_path) - 1] == '/') {
1067
            $upload_path = substr($upload_path, 0, -1);
1068
        }
1069
1070
        /*	Uncompressing phase */
1071
1072
        /*
1073
            The first version, using OS unzip, is not used anymore
1074
            because it does not return enough information.
1075
            We need to process each individual file in the zip archive to
1076
            - add it to the database
1077
            - parse & change relative html links
1078
        */
1079
        if (PHP_OS == 'Linux' && !get_cfg_var('safe_mode') && false) { // *** UGent, changed by OC ***
1080
            // Shell Method - if this is possible, it gains some speed
1081
            exec("unzip -d \"".$base_work_dir.$upload_path."/\"".$uploaded_file['name']." ".$uploaded_file['tmp_name']);
1082
        } else {
1083
            // PHP method - slower...
1084
            $save_dir = getcwd();
1085
            chdir($base_work_dir.$upload_path);
1086
            $unzippingState = $zip_file->extract();
1087
            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...
1088
                $state = $unzippingState[$j];
1089
1090
                // Fix relative links in html files
1091
                $extension = strrchr($state['stored_filename'], '.');
1092
            }
1093
            if ($dir = @opendir($base_work_dir.$upload_path)) {
1094
                while ($file = readdir($dir)) {
1095
                    if ($file != '.' && $file != '..') {
1096
                        $filetype = 'file';
1097
                        if (is_dir($base_work_dir.$upload_path.'/'.$file)) {
1098
                            $filetype = 'folder';
1099
                        }
1100
1101
                        $safe_file = api_replace_dangerous_char($file);
1102
                        @rename($base_work_dir.$upload_path.'/'.$file, $base_work_dir.$upload_path.'/'.$safe_file);
1103
                        set_default_settings($upload_path, $safe_file, $filetype);
1104
                    }
1105
                }
1106
1107
                closedir($dir);
1108
            } else {
1109
                error_log('Could not create directory '.$base_work_dir.$upload_path.' to unzip files');
1110
            }
1111
            chdir($save_dir); // Back to previous dir position
1112
        }
1113
    }
1114
1115
    return true;
1116
}
1117
1118
/**
1119
 * Manages all the unzipping process of an uploaded document
1120
 * This uses the item_property table for properties of documents.
1121
 *
1122
 * @author Hugues Peeters <[email protected]>
1123
 * @author Bert Vanderkimpen
1124
 *
1125
 * @param array  $courseInfo
1126
 * @param array  $userInfo
1127
 * @param array  $uploaded_file    - follows the $_FILES Structure
1128
 * @param string $uploadPath       - destination of the upload.
1129
 *                                 This path is to append to $base_work_dir
1130
 * @param string $base_work_dir    - base working directory of the module
1131
 * @param int    $maxFilledSpace   - amount of bytes to not exceed in the base
1132
 *                                 working directory
1133
 * @param int    $sessionId
1134
 * @param int    $groupId          group.id
1135
 * @param bool   $output           Optional. If no output not wanted on success, set to false.
1136
 * @param bool   $onlyUploadFile
1137
 * @param string $whatIfFileExists (only works if $onlyUploadFile is false)
1138
 *
1139
 * @return bool true if it succeeds false otherwise
1140
 */
1141
function unzip_uploaded_document(
1142
    $courseInfo,
1143
    $userInfo,
1144
    $uploaded_file,
1145
    $uploadPath,
1146
    $base_work_dir,
1147
    $maxFilledSpace,
1148
    $sessionId = 0,
1149
    $groupId = 0,
1150
    $output = true,
1151
    $onlyUploadFile = false,
1152
    $whatIfFileExists = 'overwrite'
1153
) {
1154
    if (empty($courseInfo) || empty($userInfo) || empty($uploaded_file) || empty($uploadPath)) {
1155
        return false;
1156
    }
1157
1158
    $zip = new PclZip($uploaded_file['tmp_name']);
1159
1160
    // Check the zip content (real size and file extension)
1161
    $zip_content_array = (array) $zip->listContent();
1162
    $realSize = 0;
1163
    foreach ($zip_content_array as &$this_content) {
1164
        $realSize += $this_content['size'];
1165
    }
1166
1167
    if (!DocumentManager::enough_space($realSize, $maxFilledSpace)) {
1168
        echo Display::return_message(get_lang('UplNotEnoughSpace'), 'error');
1169
1170
        return false;
1171
    }
1172
1173
    $folder = api_get_unique_id();
1174
    $destinationDir = api_get_path(SYS_ARCHIVE_PATH).$folder;
1175
    mkdir($destinationDir, api_get_permissions_for_new_directories(), true);
1176
1177
    // Uncompress zip file
1178
    // We extract using a callback function that "cleans" the path
1179
    $zip->extract(
1180
        PCLZIP_OPT_PATH,
1181
        $destinationDir,
1182
        PCLZIP_CB_PRE_EXTRACT,
1183
        'clean_up_files_in_zip',
1184
        PCLZIP_OPT_REPLACE_NEWER
1185
    );
1186
1187
    if ($onlyUploadFile === false) {
1188
        // Add all documents in the unzipped folder to the database
1189
        add_all_documents_in_folder_to_database(
1190
            $courseInfo,
1191
            $userInfo,
1192
            $base_work_dir,
1193
            $destinationDir,
1194
            $sessionId,
1195
            $groupId,
1196
            $output,
1197
            ['path' => $uploadPath],
1198
            $whatIfFileExists
1199
        );
1200
    } else {
1201
        // Copy result
1202
        $fs = new \Symfony\Component\Filesystem\Filesystem();
1203
        $fs->mirror($destinationDir, $base_work_dir.$uploadPath, null, ['overwrite']);
1204
    }
1205
1206
    if (is_dir($destinationDir)) {
1207
        rmdirr($destinationDir);
1208
    }
1209
1210
    return true;
1211
}
1212
1213
/**
1214
 * This function is a callback function that is used while extracting a zipfile
1215
 * http://www.phpconcept.net/pclzip/man/en/index.php?options-pclzip_cb_pre_extract.
1216
 *
1217
 * @param array $p_event
1218
 * @param array $p_header
1219
 *
1220
 * @return int (If the function returns 1, then the extraction is resumed, if 0 the path was skipped)
1221
 */
1222
function clean_up_files_in_zip($p_event, &$p_header)
1223
{
1224
    $originalStoredFileName = $p_header['stored_filename'];
1225
    $baseName = basename($originalStoredFileName);
1226
    // Skip files
1227
    $skipFiles = [
1228
        '__MACOSX',
1229
        '.Thumbs.db',
1230
        'Thumbs.db',
1231
    ];
1232
1233
    if (in_array($baseName, $skipFiles)) {
1234
        return 0;
1235
    }
1236
    $modifiedStoredFileName = clean_up_path($originalStoredFileName);
1237
    $p_header['filename'] = str_replace($originalStoredFileName, $modifiedStoredFileName, $p_header['filename']);
1238
1239
    return 1;
1240
}
1241
1242
function cleanZipFilesNoRename($p_event, &$p_header)
1243
{
1244
    $originalStoredFileName = $p_header['stored_filename'];
1245
    $baseName = basename($originalStoredFileName);
1246
    // Skip files
1247
    $skipFiles = [
1248
        '__MACOSX',
1249
        '.Thumbs.db',
1250
        'Thumbs.db',
1251
    ];
1252
1253
    if (in_array($baseName, $skipFiles)) {
1254
        return 0;
1255
    }
1256
    $modifiedStoredFileName = clean_up_path($originalStoredFileName, false);
1257
    $p_header['filename'] = str_replace($originalStoredFileName, $modifiedStoredFileName, $p_header['filename']);
1258
1259
    return 1;
1260
}
1261
1262
/**
1263
 * Allow .htaccess file.
1264
 *
1265
 * @param $p_event
1266
 * @param $p_header
1267
 *
1268
 * @return int
1269
 */
1270
function cleanZipFilesAllowHtaccess($p_event, &$p_header)
1271
{
1272
    $originalStoredFileName = $p_header['stored_filename'];
1273
    $baseName = basename($originalStoredFileName);
1274
1275
    $allowFiles = ['.htaccess'];
1276
    if (in_array($baseName, $allowFiles)) {
1277
        return 1;
1278
    }
1279
1280
    // Skip files
1281
    $skipFiles = [
1282
        '__MACOSX',
1283
        '.Thumbs.db',
1284
        'Thumbs.db',
1285
    ];
1286
1287
    if (in_array($baseName, $skipFiles)) {
1288
        return 0;
1289
    }
1290
    $modifiedStoredFileName = clean_up_path($originalStoredFileName);
1291
    $p_header['filename'] = str_replace($originalStoredFileName, $modifiedStoredFileName, $p_header['filename']);
1292
1293
    return 1;
1294
}
1295
1296
/**
1297
 * This function cleans up a given path
1298
 * by eliminating dangerous file names and cleaning them.
1299
 *
1300
 * @param string $path
1301
 * @param bool   $replaceName
1302
 *
1303
 * @return string
1304
 *
1305
 * @see disable_dangerous_file()
1306
 * @see api_replace_dangerous_char()
1307
 */
1308
function clean_up_path($path, $replaceName = true)
1309
{
1310
    // Split the path in folders and files
1311
    $path_array = explode('/', $path);
1312
    // Clean up every folder and filename in the path
1313
    foreach ($path_array as $key => &$val) {
1314
        // We don't want to lose the dots in ././folder/file (cfr. zipfile)
1315
        if ($val != '.') {
1316
            if ($replaceName) {
1317
                $val = api_replace_dangerous_char($val);
1318
            }
1319
            $val = disable_dangerous_file($val);
1320
        }
1321
    }
1322
    // Join the "cleaned" path (modified in-place as passed by reference)
1323
    $path = implode('/', $path_array);
1324
    filter_extension($path);
1325
1326
    return $path;
1327
}
1328
1329
/**
1330
 * Checks if the file is dangerous, based on extension and/or mimetype.
1331
 * The list of extensions accepted/rejected can be found from
1332
 * api_get_setting('upload_extensions_exclude') and api_get_setting('upload_extensions_include').
1333
 *
1334
 * @param string $filename passed by reference. The filename will be modified
1335
 *                         if filter rules say so! (you can include path but the filename should look like 'abc.html')
1336
 *
1337
 * @return int 0 to skip file, 1 to keep file
1338
 */
1339
function filter_extension(&$filename)
1340
{
1341
    if (substr($filename, -1) == '/') {
1342
        return 1; // Authorize directories
1343
    }
1344
    $blacklist = api_get_setting('upload_extensions_list_type');
1345
    if ($blacklist != 'whitelist') { // if = blacklist
1346
        $extensions = explode(';', strtolower(api_get_setting('upload_extensions_blacklist')));
1347
1348
        $skip = api_get_setting('upload_extensions_skip');
1349
        $ext = strrchr($filename, '.');
1350
        $ext = substr($ext, 1);
1351
        if (empty($ext)) {
1352
            return 1; // We're in blacklist mode, so accept empty extensions
1353
        }
1354
        if (in_array(strtolower($ext), $extensions)) {
1355
            if ($skip == 'true') {
1356
                return 0;
1357
            } else {
1358
                $new_ext = api_get_setting('upload_extensions_replace_by');
1359
                $filename = str_replace('.'.$ext, '.'.$new_ext, $filename);
1360
1361
                return 1;
1362
            }
1363
        } else {
1364
            return 1;
1365
        }
1366
    } else {
1367
        $extensions = explode(';', strtolower(api_get_setting('upload_extensions_whitelist')));
1368
        $skip = api_get_setting('upload_extensions_skip');
1369
        $ext = strrchr($filename, '.');
1370
        $ext = substr($ext, 1);
1371
        if (empty($ext)) {
1372
            return 1; // Accept empty extensions
1373
        }
1374
        if (!in_array(strtolower($ext), $extensions)) {
1375
            if ($skip == 'true') {
1376
                return 0;
1377
            } else {
1378
                $new_ext = api_get_setting('upload_extensions_replace_by');
1379
                $filename = str_replace('.'.$ext, '.'.$new_ext, $filename);
1380
1381
                return 1;
1382
            }
1383
        } else {
1384
            return 1;
1385
        }
1386
    }
1387
}
1388
1389
/**
1390
 * Adds a new document to the database.
1391
 *
1392
 * @param array  $courseInfo
1393
 * @param string $path
1394
 * @param string $fileType
1395
 * @param int    $fileSize
1396
 * @param string $title
1397
 * @param string $comment
1398
 * @param int    $readonly
1399
 * @param bool   $saveVisibility
1400
 * @param int    $group_id         group.id
1401
 * @param int    $sessionId        Session ID, if any
1402
 * @param int    $userId           creator user id
1403
 * @param bool   $sendNotification
1404
 *
1405
 * @return int id if inserted document
1406
 */
1407
function add_document(
1408
    $courseInfo,
1409
    $path,
1410
    $fileType,
1411
    $fileSize,
1412
    $title,
1413
    $comment = null,
1414
    $readonly = 0,
1415
    $saveVisibility = true,
1416
    $group_id = 0,
1417
    $sessionId = 0,
1418
    $userId = 0,
1419
    $sendNotification = true
1420
) {
1421
    $sessionId = empty($sessionId) ? api_get_session_id() : $sessionId;
1422
    $userId = empty($userId) ? api_get_user_id() : $userId;
1423
1424
    $readonly = (int) $readonly;
1425
    $c_id = $courseInfo['real_id'];
1426
    $params = [
1427
        'c_id' => $c_id,
1428
        'path' => $path,
1429
        'filetype' => $fileType,
1430
        'size' => $fileSize,
1431
        'title' => $title,
1432
        'comment' => $comment,
1433
        'readonly' => $readonly,
1434
        'session_id' => $sessionId,
1435
    ];
1436
    $table = Database::get_course_table(TABLE_DOCUMENT);
1437
    $documentId = Database::insert($table, $params);
1438
    if ($documentId) {
1439
        $sql = "UPDATE $table SET id = iid WHERE iid = $documentId";
1440
        Database::query($sql);
1441
1442
        if ($saveVisibility) {
1443
            api_set_default_visibility(
1444
                $documentId,
1445
                TOOL_DOCUMENT,
1446
                $group_id,
1447
                $courseInfo,
1448
                $sessionId,
1449
                $userId
1450
            );
1451
        }
1452
1453
        $allowNotification = api_get_configuration_value('send_notification_when_document_added');
1454
        if ($sendNotification && $allowNotification) {
1455
            $courseTitle = $courseInfo['title'];
1456
            if (!empty($sessionId)) {
1457
                $sessionInfo = api_get_session_info($sessionId);
1458
                $courseTitle .= " ( ".$sessionInfo['name'].") ";
1459
            }
1460
1461
            $url = api_get_path(WEB_CODE_PATH).
1462
                'document/showinframes.php?cidReq='.$courseInfo['code'].'&id_session='.$sessionId.'&id='.$documentId;
1463
            $link = Display::url(basename($title), $url, ['target' => '_blank']);
1464
            $userInfo = api_get_user_info($userId);
1465
1466
            $message = sprintf(
1467
                get_lang('DocumentXHasBeenAddedToDocumentInYourCourseXByUserX'),
1468
                $link,
1469
                $courseTitle,
1470
                $userInfo['complete_name']
1471
            );
1472
            $subject = sprintf(get_lang('NewDocumentAddedToCourseX'), $courseTitle);
1473
            MessageManager::sendMessageToAllUsersInCourse($subject, $message, $courseInfo, $sessionId);
1474
        }
1475
1476
        return $documentId;
1477
    } else {
1478
        return false;
1479
    }
1480
}
1481
1482
/**
1483
 * Updates an existing document in the database
1484
 * as the file exists, we only need to change the size.
1485
 *
1486
 * @param array $_course
1487
 * @param int   $documentId
1488
 * @param int   $filesize
1489
 * @param int   $readonly
1490
 *
1491
 * @return bool true /false
1492
 */
1493
function update_existing_document($_course, $documentId, $filesize, $readonly = 0)
1494
{
1495
    $document_table = Database::get_course_table(TABLE_DOCUMENT);
1496
    $documentId = intval($documentId);
1497
    $filesize = intval($filesize);
1498
    $readonly = intval($readonly);
1499
    $course_id = $_course['real_id'];
1500
1501
    $sql = "UPDATE $document_table SET
1502
            size = '$filesize',
1503
            readonly = '$readonly'
1504
			WHERE c_id = $course_id AND id = $documentId";
1505
    if (Database::query($sql)) {
1506
        return true;
1507
    } else {
1508
        return false;
1509
    }
1510
}
1511
1512
/**
1513
 * This function updates the last_edit_date, last edit user id on all folders in a given path.
1514
 *
1515
 * @param array  $_course
1516
 * @param string $path
1517
 * @param int    $user_id
1518
 */
1519
function item_property_update_on_folder($_course, $path, $user_id)
1520
{
1521
    // If we are in the root, just return... no need to update anything
1522
    if ($path == '/') {
1523
        return;
1524
    }
1525
1526
    $user_id = intval($user_id);
1527
1528
    // If the given path ends with a / we remove it
1529
    $endchar = substr($path, strlen($path) - 1, 1);
1530
    if ($endchar == '/') {
1531
        $path = substr($path, 0, strlen($path) - 1);
1532
    }
1533
1534
    $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1535
1536
    // Get the time
1537
    $time = api_get_utc_datetime();
1538
1539
    // Det all paths in the given path
1540
    // /folder/subfolder/subsubfolder/file
1541
    // if file is updated, subsubfolder, subfolder and folder are updated
1542
    $exploded_path = explode('/', $path);
1543
    $course_id = api_get_course_int_id();
1544
    $newpath = '';
1545
    foreach ($exploded_path as $key => &$value) {
1546
        // We don't want a slash before our first slash
1547
        if ($key != 0) {
1548
            $newpath .= '/'.$value;
1549
            // Select ID of given folder
1550
            $folder_id = DocumentManager::get_document_id($_course, $newpath);
1551
1552
            if ($folder_id) {
1553
                $sql = "UPDATE $table SET
1554
				        lastedit_date = '$time',
1555
				        lastedit_type = 'DocumentInFolderUpdated',
1556
				        lastedit_user_id='$user_id'
1557
						WHERE
1558
						    c_id = $course_id AND
1559
						    tool='".TOOL_DOCUMENT."' AND
1560
						    ref = '$folder_id'";
1561
                Database::query($sql);
1562
            }
1563
        }
1564
    }
1565
}
1566
1567
/**
1568
 * Adds file to document table in database
1569
 * deprecated: use file_set_default_settings instead.
1570
 *
1571
 * @author	Olivier Cauberghe <[email protected]>
1572
 *
1573
 * @param	path,filename
1574
 * action:	Adds an entry to the document table with the default settings
1575
 */
1576
function set_default_settings($upload_path, $filename, $filetype = 'file')
1577
{
1578
    $dbTable = Database::get_course_table(TABLE_DOCUMENT);
1579
    global $default_visibility;
1580
1581
    if (!$default_visibility) {
1582
        $default_visibility = 'v';
1583
    }
1584
    $filetype = Database::escape_string($filetype);
1585
1586
    $upload_path = str_replace('\\', '/', $upload_path);
1587
    $upload_path = str_replace('//', '/', $upload_path);
1588
1589
    if ($upload_path == '/') {
1590
        $upload_path = '';
1591
    } elseif (!empty($upload_path) && $upload_path[0] != '/') {
1592
        $upload_path = "/$upload_path";
1593
    }
1594
1595
    $endchar = substr($filename, strlen($filename) - 1, 1);
1596
1597
    if ($endchar == '/') {
1598
        $filename = substr($filename, 0, -1);
1599
    }
1600
    $filename = Database::escape_string($filename);
1601
    $query = "SELECT count(*) as bestaat FROM $dbTable
1602
              WHERE path='$upload_path/$filename'";
1603
    $result = Database::query($query);
1604
    $row = Database::fetch_array($result);
1605
    if ($row['bestaat'] > 0) {
1606
        $query = "UPDATE $dbTable SET
1607
		            path='$upload_path/$filename',
1608
		            visibility='$default_visibility',
1609
		            filetype='$filetype'
1610
		          WHERE path='$upload_path/$filename'";
1611
    } else {
1612
        $query = "INSERT INTO $dbTable (path,visibility,filetype)
1613
		          VALUES('$upload_path/$filename','$default_visibility','$filetype')";
1614
    }
1615
    Database::query($query);
1616
}
1617
1618
/**
1619
 * Retrieves the image path list in a html file.
1620
 *
1621
 * @author Hugues Peeters <[email protected]>
1622
 *
1623
 * @param string $html_file
1624
 *
1625
 * @return array -  images path list
1626
 */
1627
function search_img_from_html($html_file)
1628
{
1629
    $img_path_list = [];
1630
1631
    if (!$fp = fopen($html_file, 'r')) {
1632
        return;
1633
    }
1634
1635
    // Aearch and store occurences of the <img> tag in an array
1636
    $size_file = (filesize($html_file) === 0) ? 1 : filesize($html_file);
1637
    if (isset($fp) && $fp !== false) {
1638
        $buffer = fread($fp, $size_file);
1639
        if (strlen($buffer) >= 0 && $buffer !== false) {
1640
        } else {
1641
            exit('<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...
1642
        }
1643
    } else {
1644
        exit('<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...
1645
    }
1646
    $matches = [];
1647
    if (preg_match_all('~<[[:space:]]*img[^>]*>~i', $buffer, $matches)) {
1648
        $img_tag_list = $matches[0];
1649
    }
1650
1651
    fclose($fp);
1652
    unset($buffer);
1653
1654
    // Search the image file path from all the <IMG> tag detected
1655
1656
    if (sizeof($img_tag_list) > 0) {
1657
        foreach ($img_tag_list as &$this_img_tag) {
1658
            if (preg_match('~src[[:space:]]*=[[:space:]]*[\"]{1}([^\"]+)[\"]{1}~i', $this_img_tag, $matches)) {
1659
                $img_path_list[] = $matches[1];
1660
            }
1661
        }
1662
        $img_path_list = array_unique($img_path_list); // Remove duplicate entries
1663
    }
1664
1665
    return $img_path_list;
1666
}
1667
1668
/**
1669
 * Creates a new directory trying to find a directory name
1670
 * that doesn't already exist.
1671
 *
1672
 * @author  Hugues Peeters <[email protected]>
1673
 * @author  Bert Vanderkimpen
1674
 *
1675
 * @param array  $_course                 current course information
1676
 * @param int    $user_id                 current user id
1677
 * @param int    $session_id
1678
 * @param int    $to_group_id             group.id
1679
 * @param int    $to_user_id
1680
 * @param string $base_work_dir           /var/www/chamilo/courses/ABC/document
1681
 * @param string $desired_dir_name        complete path of the desired name
1682
 *                                        Example: /folder1/folder2
1683
 * @param string $title                   "folder2"
1684
 * @param int    $visibility              (0 for invisible, 1 for visible, 2 for deleted)
1685
 * @param bool   $generateNewNameIfExists
1686
 * @param bool   $sendNotification        depends in conf setting "send_notification_when_document_added"
1687
 *
1688
 * @return string actual directory name if it succeeds,
1689
 *                boolean false otherwise
1690
 */
1691
function create_unexisting_directory(
1692
    $_course,
1693
    $user_id,
1694
    $session_id,
1695
    $to_group_id,
1696
    $to_user_id,
1697
    $base_work_dir,
1698
    $desired_dir_name,
1699
    $title = '',
1700
    $visibility = '',
1701
    $generateNewNameIfExists = false,
1702
    $sendNotification = true
1703
) {
1704
    $course_id = $_course['real_id'];
1705
    $session_id = (int) $session_id;
1706
1707
    $folderExists = DocumentManager::folderExists(
1708
        $desired_dir_name,
1709
        $_course,
1710
        $session_id,
1711
        $to_group_id
1712
    );
1713
1714
    if ($folderExists === true) {
1715
        if ($generateNewNameIfExists) {
1716
            $counter = 1;
1717
            while (1) {
1718
                $folderExists = DocumentManager::folderExists(
1719
                    $desired_dir_name.'_'.$counter,
1720
                    $_course,
1721
                    $session_id,
1722
                    $to_group_id
1723
                );
1724
1725
                if ($folderExists === false) {
1726
                    break;
1727
                }
1728
                $counter++;
1729
            }
1730
            $desired_dir_name = $desired_dir_name.'_'.$counter;
1731
        } else {
1732
            return false;
1733
        }
1734
    }
1735
1736
    $systemFolderName = $desired_dir_name;
1737
1738
    // Adding suffix
1739
    $suffix = DocumentManager::getDocumentSuffix(
1740
        $_course,
1741
        $session_id,
1742
        $to_group_id
1743
    );
1744
1745
    $systemFolderName .= $suffix;
1746
1747
    if ($title == null) {
1748
        $title = basename($desired_dir_name);
1749
    }
1750
1751
    if (!is_dir($base_work_dir.$systemFolderName)) {
1752
        $result = @mkdir(
1753
            $base_work_dir.$systemFolderName,
1754
            api_get_permissions_for_new_directories(),
1755
            true
1756
        );
1757
1758
        if ($result) {
1759
            // Check if pathname already exists inside document table
1760
            $tbl_document = Database::get_course_table(TABLE_DOCUMENT);
1761
            $sql = "SELECT id, path FROM $tbl_document
1762
                    WHERE
1763
                        c_id = $course_id AND
1764
                        (
1765
                            path = '".Database::escape_string($systemFolderName)."'
1766
                        )
1767
            ";
1768
1769
            $groupInfo = [];
1770
            if (!empty($to_group_id)) {
1771
                $groupInfo = GroupManager::get_group_properties($to_group_id);
1772
            }
1773
1774
            $rs = Database::query($sql);
1775
            if (Database::num_rows($rs) == 0) {
1776
                $document_id = add_document(
1777
                    $_course,
1778
                    $systemFolderName,
1779
                    'folder',
1780
                    0,
1781
                    $title,
1782
                    null,
1783
                    0,
1784
                    true,
1785
                    $to_group_id,
1786
                    $session_id,
1787
                    $user_id,
1788
                    $sendNotification
1789
                );
1790
1791
                if ($document_id) {
1792
                    $lastEditType = [
1793
                        0 => 'invisible',
1794
                        1 => 'visible',
1795
                        2 => 'delete',
1796
                    ];
1797
                    // Update document item_property
1798
                    if (isset($lastEditType[$visibility])) {
1799
                        api_item_property_update(
1800
                            $_course,
1801
                            TOOL_DOCUMENT,
1802
                            $document_id,
1803
                            $lastEditType[$visibility],
1804
                            $user_id,
1805
                            $groupInfo,
1806
                            $to_user_id,
1807
                            null,
1808
                            null,
1809
                            $session_id
1810
                        );
1811
                    } else {
1812
                        api_item_property_update(
1813
                            $_course,
1814
                            TOOL_DOCUMENT,
1815
                            $document_id,
1816
                            'FolderCreated',
1817
                            $user_id,
1818
                            $groupInfo,
1819
                            $to_user_id,
1820
                            null,
1821
                            null,
1822
                            $session_id
1823
                        );
1824
                    }
1825
1826
                    $documentData = DocumentManager::get_document_data_by_id(
1827
                        $document_id,
1828
                        $_course['code'],
1829
                        false,
1830
                        $session_id
1831
                    );
1832
1833
                    return $documentData;
1834
                }
1835
            } else {
1836
                $document = Database::fetch_array($rs);
1837
                $documentData = DocumentManager::get_document_data_by_id(
1838
                    $document['id'],
1839
                    $_course['code'],
1840
                    false,
1841
                    $session_id
1842
                );
1843
1844
                /* This means the folder NOT exist in the filesystem
1845
                 (now this was created) but there is a record in the Database*/
1846
1847
                return $documentData;
1848
            }
1849
        }
1850
    }
1851
1852
    return false;
1853
}
1854
1855
/**
1856
 * Handles uploaded missing images.
1857
 *
1858
 * @author Hugues Peeters <[email protected]>
1859
 * @author Bert Vanderkimpen
1860
 *
1861
 * @param array  $_course
1862
 * @param array  $uploaded_file_collection - follows the $_FILES Structure
1863
 * @param string $base_work_dir
1864
 * @param string $missing_files_dir
1865
 * @param int    $user_id
1866
 * @param int    $to_group_id              group.id
1867
 */
1868
function move_uploaded_file_collection_into_directory(
1869
    $_course,
1870
    $uploaded_file_collection,
1871
    $base_work_dir,
1872
    $missing_files_dir,
1873
    $user_id,
1874
    $to_group_id,
1875
    $to_user_id,
1876
    $max_filled_space
1877
) {
1878
    $number_of_uploaded_images = count($uploaded_file_collection['name']);
1879
    $list = [];
1880
    for ($i = 0; $i < $number_of_uploaded_images; $i++) {
1881
        $missing_file['name'] = $uploaded_file_collection['name'][$i];
1882
        $missing_file['type'] = $uploaded_file_collection['type'][$i];
1883
        $missing_file['tmp_name'] = $uploaded_file_collection['tmp_name'][$i];
1884
        $missing_file['error'] = $uploaded_file_collection['error'][$i];
1885
        $missing_file['size'] = $uploaded_file_collection['size'][$i];
1886
1887
        $upload_ok = process_uploaded_file($missing_file);
1888
        if ($upload_ok) {
1889
            $list[] = handle_uploaded_document(
1890
                $_course,
1891
                $missing_file,
1892
                $base_work_dir,
1893
                $missing_files_dir,
1894
                $user_id,
1895
                $to_group_id,
1896
                $to_user_id,
1897
                $max_filled_space,
1898
                0,
1899
                'overwrite'
1900
            );
1901
        }
1902
        unset($missing_file);
1903
    }
1904
1905
    return $list;
1906
}
1907
1908
/**
1909
 * Opens the old html file and replace the src path into the img tag
1910
 * This also works for files in subdirectories.
1911
 *
1912
 * @param $original_img_path is an array
1913
 * @param $new_img_path is an array
1914
 */
1915
function replace_img_path_in_html_file($original_img_path, $new_img_path, $html_file)
1916
{
1917
    // Open the file
1918
    $fp = fopen($html_file, 'r');
1919
    $buffer = fread($fp, filesize($html_file));
1920
    $new_html_content = '';
1921
1922
    // Fix the image tags
1923
    for ($i = 0, $fileNb = count($original_img_path); $i < $fileNb; $i++) {
1924
        $replace_what = $original_img_path[$i];
1925
        // We only need the directory and the filename /path/to/file_html_files/missing_file.gif -> file_html_files/missing_file.gif
1926
        $exploded_file_path = explode('/', $new_img_path[$i]);
1927
        $replace_by = $exploded_file_path[count($exploded_file_path) - 2].'/'.$exploded_file_path[count($exploded_file_path) - 1];
1928
        $buffer = str_replace($replace_what, $replace_by, $buffer);
1929
    }
1930
1931
    $new_html_content .= $buffer;
1932
1933
    @fclose($fp);
1934
1935
    // Write the resulted new file
1936
1937
    if (!$fp = fopen($html_file, 'w')) {
1938
        return;
1939
    }
1940
1941
    if (!fwrite($fp, $new_html_content)) {
1942
        return;
1943
    }
1944
}
1945
1946
/**
1947
 * Checks the extension of a file, if it's .htm or .html
1948
 * we use search_img_from_html to get all image paths in the file.
1949
 *
1950
 * @param string $file
1951
 *
1952
 * @return array paths
1953
 *
1954
 * @see check_for_missing_files() uses search_img_from_html()
1955
 */
1956
function check_for_missing_files($file)
1957
{
1958
    if (strrchr($file, '.') == '.htm' || strrchr($file, '.') == '.html') {
1959
        $img_file_path = search_img_from_html($file);
1960
1961
        return $img_file_path;
1962
    }
1963
1964
    return false;
1965
}
1966
1967
/**
1968
 * This function builds a form that asks for the missing images in a html file
1969
 * maybe we should do this another way?
1970
 *
1971
 * @param array  $missing_files
1972
 * @param string $upload_path
1973
 * @param string $file_name
1974
 *
1975
 * @return string the form
1976
 */
1977
function build_missing_files_form($missing_files, $upload_path, $file_name)
1978
{
1979
    // Do we need a / or not?
1980
    $added_slash = ($upload_path == '/') ? '' : '/';
1981
    $folder_id = DocumentManager::get_document_id(api_get_course_info(), $upload_path);
1982
    // Build the form
1983
    $form = "<p><strong>".get_lang('MissingImagesDetected')."</strong></p>"
1984
        ."<form method=\"post\" action=\"".api_get_self()."\" enctype=\"multipart/form-data\">"
1985
        // Related_file is the path to the file that has missing images
1986
        ."<input type=\"hidden\" name=\"related_file\" value=\"".$upload_path.$added_slash.$file_name."\" />"
1987
        ."<input type=\"hidden\" name=\"upload_path\" value=\"".$upload_path."\" />"
1988
        ."<input type=\"hidden\" name=\"id\" value=\"".$folder_id."\" />"
1989
        ."<table border=\"0\">";
1990
    foreach ($missing_files as &$this_img_file_path) {
1991
        $form .= "<tr>"
1992
            ."<td>".basename($this_img_file_path)." : </td>"
1993
            ."<td>"
1994
            ."<input type=\"file\" name=\"img_file[]\"/>"
1995
            ."<input type=\"hidden\" name=\"img_file_path[]\" value=\"".$this_img_file_path."\" />"
1996
            ."</td>"
1997
            ."</tr>";
1998
    }
1999
    $form .= "</table>"
2000
        ."<button type='submit' name=\"cancel_submit_image\" value=\"".get_lang('Cancel')."\" class=\"cancel\">".get_lang('Cancel')."</button>"
2001
        ."<button type='submit' name=\"submit_image\" value=\"".get_lang('Ok')."\" class=\"save\">".get_lang('Ok')."</button>"
2002
        ."</form>";
2003
2004
    return $form;
2005
}
2006
2007
/**
2008
 * This recursive function can be used during the upgrade process form older
2009
 * versions of Chamilo
2010
 * It crawls the given directory, checks if the file is in the DB and adds
2011
 * it if it's not.
2012
 *
2013
 * @param array  $courseInfo
2014
 * @param array  $userInfo
2015
 * @param string $base_work_dir    course document dir
2016
 * @param string $folderPath       folder to read
2017
 * @param int    $sessionId
2018
 * @param int    $groupId          group.id
2019
 * @param bool   $output
2020
 * @param array  $parent
2021
 * @param string $whatIfFileExists
2022
 *
2023
 * @return bool
2024
 */
2025
function add_all_documents_in_folder_to_database(
2026
    $courseInfo,
2027
    $userInfo,
2028
    $base_work_dir,
2029
    $folderPath,
2030
    $sessionId = 0,
2031
    $groupId = 0,
2032
    $output = false,
2033
    $parent = [],
2034
    $whatIfFileExists = 'overwrite'
2035
) {
2036
    if (empty($userInfo) || empty($courseInfo)) {
2037
        return false;
2038
    }
2039
2040
    $userId = $userInfo['user_id'];
2041
2042
    // Open dir
2043
    $handle = opendir($folderPath);
2044
2045
    if (is_dir($folderPath)) {
2046
        // Run trough
2047
        while ($file = readdir($handle)) {
2048
            if ($file == '.' || $file == '..') {
2049
                continue;
2050
            }
2051
2052
            $parentPath = '';
2053
            if (!empty($parent) && isset($parent['path'])) {
2054
                $parentPath = $parent['path'];
2055
                if ($parentPath == '/') {
2056
                    $parentPath = '';
2057
                }
2058
            }
2059
2060
            $completePath = $parentPath.'/'.$file;
2061
            $sysFolderPath = $folderPath.'/'.$file;
2062
2063
            // Is directory?
2064
            if (is_dir($sysFolderPath)) {
2065
                $folderExists = DocumentManager::folderExists(
2066
                    $completePath,
2067
                    $courseInfo,
2068
                    $sessionId,
2069
                    $groupId
2070
                );
2071
2072
                if ($folderExists === true) {
2073
                    switch ($whatIfFileExists) {
2074
                        case 'overwrite':
2075
                            $documentId = DocumentManager::get_document_id($courseInfo, $completePath, $sessionId);
2076
                            if ($documentId) {
2077
                                $newFolderData = DocumentManager::get_document_data_by_id(
2078
                                    $documentId,
2079
                                    $courseInfo['code'],
2080
                                    false,
2081
                                    $sessionId
2082
                                );
2083
                            }
2084
                            break;
2085
                        case 'rename':
2086
                            $newFolderData = create_unexisting_directory(
2087
                                $courseInfo,
2088
                                $userId,
2089
                                $sessionId,
2090
                                $groupId,
2091
                                null,
2092
                                $base_work_dir,
2093
                                $completePath,
2094
                                null,
2095
                                null,
2096
                                true
2097
                            );
2098
                            break;
2099
                        case 'nothing':
2100
                            if ($output) {
2101
                                $documentId = DocumentManager::get_document_id($courseInfo, $completePath, $sessionId);
2102
                                if ($documentId) {
2103
                                    $folderData = DocumentManager::get_document_data_by_id(
2104
                                        $documentId,
2105
                                        $courseInfo['code'],
2106
                                        false,
2107
                                        $sessionId
2108
                                    );
2109
                                    Display::addFlash(
2110
                                        Display::return_message(
2111
                                            $folderData['path'].' '.get_lang('UplAlreadyExists'),
2112
                                            'warning'
2113
                                        )
2114
                                    );
2115
                                }
2116
                            }
2117
                            continue 2;
2118
                            break;
2119
                    }
2120
                } else {
2121
                    $newFolderData = create_unexisting_directory(
2122
                        $courseInfo,
2123
                        $userId,
2124
                        $sessionId,
2125
                        $groupId,
2126
                        null,
2127
                        $base_work_dir,
2128
                        $completePath,
2129
                        null,
2130
                        null,
2131
                        false
2132
                    );
2133
                }
2134
2135
                // Recursive
2136
                add_all_documents_in_folder_to_database(
2137
                    $courseInfo,
2138
                    $userInfo,
2139
                    $base_work_dir,
2140
                    $sysFolderPath,
2141
                    $sessionId,
2142
                    $groupId,
2143
                    $output,
2144
                    $newFolderData,
2145
                    $whatIfFileExists
2146
                );
2147
            } else {
2148
                // Rename
2149
                $uploadedFile = [
2150
                    'name' => $file,
2151
                    'tmp_name' => $sysFolderPath,
2152
                    'size' => filesize($sysFolderPath),
2153
                    'type' => null,
2154
                    'from_file' => true,
2155
                    'move_file' => true,
2156
                ];
2157
2158
                handle_uploaded_document(
2159
                    $courseInfo,
2160
                    $uploadedFile,
2161
                    $base_work_dir,
2162
                    $parentPath,
2163
                    $userId,
2164
                    $groupId,
2165
                    null,
2166
                    0,
2167
                    $whatIfFileExists,
2168
                    $output,
2169
                    false,
2170
                    null,
2171
                    $sessionId
2172
                );
2173
            }
2174
        }
2175
    }
2176
}
2177