Passed
Push — ofaj ( d9b422...0f9380 )
by
unknown
11:25 queued 11s
created

unzip_uploaded_document()   B

Complexity

Conditions 9
Paths 11

Size

Total Lines 69
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

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