Completed
Push — 1.11.x ( 65444a...8a35a0 )
by
unknown
01:41 queued 56s
created

getIniMaxFileSizeInBytes()   B

Complexity

Conditions 10
Paths 16

Size

Total Lines 41
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 27
dl 0
loc 41
rs 7.6666
c 1
b 0
f 0
cc 10
nc 16
nop 2

How to fix   Complexity   

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:

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 (!Security::check_abs_path($documentDir.$uploadPath, $documentDir.'/')) {
271
        Display::addFlash(
272
            Display::return_message(
273
                get_lang('Forbidden'),
274
                'error'
275
            )
276
        );
277
278
        return false;
279
    }
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
    $copyFile = isset($file['copy_file']) && $file['copy_file'] ? true : false;
753
    if ($moveFile) {
754
        $copied = copy($file['tmp_name'], $storePath);
755
756
        if (!$copied) {
757
            return false;
758
        }
759
    }
760
761
    if ($copyFile) {
762
        $copied = copy($file['tmp_name'], $storePath);
763
        unlink($file['tmp_name']);
764
765
        return $copied;
766
    }
767
768
    if ($handleFromFile) {
769
        return file_exists($file['tmp_name']);
770
    } else {
771
        return move_uploaded_file($file['tmp_name'], $storePath);
772
    }
773
}
774
775
/**
776
 * Checks if there is enough place to add a file on a directory
777
 * on the base of a maximum directory size allowed
778
 * deprecated: use enough_space instead!
779
 *
780
 * @author Hugues Peeters <[email protected]>
781
 *
782
 * @param int    $file_size     Size of the file in byte
783
 * @param string $dir           Path of the directory where the file should be added
784
 * @param int    $max_dir_space Maximum size of the diretory in byte
785
 *
786
 * @return bool true if there is enough space, false otherwise
787
 *
788
 * @see enough_size() uses  dir_total_space() function
789
 */
790
function enough_size($file_size, $dir, $max_dir_space)
791
{
792
    // If the directory is the archive directory, safely ignore the size limit
793
    if (api_get_path(SYS_ARCHIVE_PATH) == $dir) {
794
        return true;
795
    }
796
797
    if ($max_dir_space) {
798
        $already_filled_space = dir_total_space($dir);
799
        if (($file_size + $already_filled_space) > $max_dir_space) {
800
            return false;
801
        }
802
    }
803
804
    return true;
805
}
806
807
/**
808
 * Computes the size already occupied by a directory and is subdirectories.
809
 *
810
 * @author Hugues Peeters <[email protected]>
811
 *
812
 * @param string $dir_path Size of the file in byte
813
 *
814
 * @return int Return the directory size in bytes
815
 */
816
function dir_total_space($dir_path)
817
{
818
    $save_dir = getcwd();
819
    chdir($dir_path);
820
    $handle = opendir($dir_path);
821
    $sumSize = 0;
822
    $dirList = [];
823
    while ($element = readdir($handle)) {
824
        if ($element == '.' || $element == '..') {
825
            continue; // Skip the current and parent directories
826
        }
827
        if (is_file($element)) {
828
            $sumSize += filesize($element);
829
        }
830
        if (is_dir($element)) {
831
            $dirList[] = $dir_path.'/'.$element;
832
        }
833
    }
834
835
    closedir($handle);
836
837
    if (sizeof($dirList) > 0) {
838
        foreach ($dirList as $j) {
839
            $sizeDir = dir_total_space($j); // Recursivity
840
            $sumSize += $sizeDir;
841
        }
842
    }
843
    chdir($save_dir); // Return to initial position
844
845
    return $sumSize;
846
}
847
848
/**
849
 * Tries to add an extension to files without extension
850
 * Some applications on Macintosh computers don't add an extension to the files.
851
 * This subroutine try to fix this on the basis of the MIME type sent
852
 * by the browser.
853
 *
854
 * Note : some browsers don't send the MIME Type (e.g. Netscape 4).
855
 *        We don't have solution for this kind of situation
856
 *
857
 * @author Hugues Peeters <[email protected]>
858
 * @author Bert Vanderkimpen
859
 *
860
 * @param string $file_name Name of the file
861
 * @param string $file_type Type of the file
862
 *
863
 * @return string File name
864
 */
865
function add_ext_on_mime($file_name, $file_type)
866
{
867
    // Check whether the file has an extension AND whether the browser has sent a MIME Type
868
869
    if (!preg_match('/^.*\.[a-zA-Z_0-9]+$/', $file_name) && $file_type) {
870
        // Build a "MIME-types / extensions" connection table
871
        static $mime_type = [];
872
873
        $mime_type[] = 'application/msword';
874
        $extension[] = '.doc';
875
        $mime_type[] = 'application/rtf';
876
        $extension[] = '.rtf';
877
        $mime_type[] = 'application/vnd.ms-powerpoint';
878
        $extension[] = '.ppt';
879
        $mime_type[] = 'application/vnd.ms-excel';
880
        $extension[] = '.xls';
881
        $mime_type[] = 'application/pdf';
882
        $extension[] = '.pdf';
883
        $mime_type[] = 'application/postscript';
884
        $extension[] = '.ps';
885
        $mime_type[] = 'application/mac-binhex40';
886
        $extension[] = '.hqx';
887
        $mime_type[] = 'application/x-gzip';
888
        $extension[] = 'tar.gz';
889
        $mime_type[] = 'application/x-shockwave-flash';
890
        $extension[] = '.swf';
891
        $mime_type[] = 'application/x-stuffit';
892
        $extension[] = '.sit';
893
        $mime_type[] = 'application/x-tar';
894
        $extension[] = '.tar';
895
        $mime_type[] = 'application/zip';
896
        $extension[] = '.zip';
897
        $mime_type[] = 'application/x-tar';
898
        $extension[] = '.tar';
899
        $mime_type[] = 'text/html';
900
        $extension[] = '.html';
901
        $mime_type[] = 'text/plain';
902
        $extension[] = '.txt';
903
        $mime_type[] = 'text/rtf';
904
        $extension[] = '.rtf';
905
        $mime_type[] = 'img/gif';
906
        $extension[] = '.gif';
907
        $mime_type[] = 'img/jpeg';
908
        $extension[] = '.jpg';
909
        $mime_type[] = 'img/png';
910
        $extension[] = '.png';
911
        $mime_type[] = 'audio/midi';
912
        $extension[] = '.mid';
913
        $mime_type[] = 'audio/mpeg';
914
        $extension[] = '.mp3';
915
        $mime_type[] = 'audio/x-aiff';
916
        $extension[] = '.aif';
917
        $mime_type[] = 'audio/x-pn-realaudio';
918
        $extension[] = '.rm';
919
        $mime_type[] = 'audio/x-pn-realaudio-plugin';
920
        $extension[] = '.rpm';
921
        $mime_type[] = 'audio/x-wav';
922
        $extension[] = '.wav';
923
        $mime_type[] = 'video/mpeg';
924
        $extension[] = '.mpg';
925
        $mime_type[] = 'video/mpeg4-generic';
926
        $extension[] = '.mp4';
927
        $mime_type[] = 'video/quicktime';
928
        $extension[] = '.mov';
929
        $mime_type[] = 'video/x-msvideo';
930
        $extension[] = '.avi';
931
932
        $mime_type[] = 'video/x-ms-wmv';
933
        $extension[] = '.wmv';
934
        $mime_type[] = 'video/x-flv';
935
        $extension[] = '.flv';
936
        $mime_type[] = 'image/svg+xml';
937
        $extension[] = '.svg';
938
        $mime_type[] = 'image/svg+xml';
939
        $extension[] = '.svgz';
940
        $mime_type[] = 'video/ogg';
941
        $extension[] = '.ogv';
942
        $mime_type[] = 'audio/ogg';
943
        $extension[] = '.oga';
944
        $mime_type[] = 'application/ogg';
945
        $extension[] = '.ogg';
946
        $mime_type[] = 'application/ogg';
947
        $extension[] = '.ogx';
948
        $mime_type[] = 'application/x-freemind';
949
        $extension[] = '.mm';
950
951
        $mime_type[] = 'application/vnd.ms-word.document.macroEnabled.12';
952
        $extension[] = '.docm';
953
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
954
        $extension[] = '.docx';
955
        $mime_type[] = 'application/vnd.ms-word.template.macroEnabled.12';
956
        $extension[] = '.dotm';
957
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.template';
958
        $extension[] = '.dotx';
959
        $mime_type[] = 'application/vnd.ms-powerpoint.template.macroEnabled.12';
960
        $extension[] = '.potm';
961
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.template';
962
        $extension[] = '.potx';
963
        $mime_type[] = 'application/vnd.ms-powerpoint.addin.macroEnabled.12';
964
        $extension[] = '.ppam';
965
        $mime_type[] = 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12';
966
        $extension[] = '.ppsm';
967
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.slideshow';
968
        $extension[] = '.ppsx';
969
        $mime_type[] = 'application/vnd.ms-powerpoint.presentation.macroEnabled.12';
970
        $extension[] = '.pptm';
971
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
972
        $extension[] = '.pptx';
973
        $mime_type[] = 'application/vnd.ms-excel.addin.macroEnabled.12';
974
        $extension[] = '.xlam';
975
        $mime_type[] = 'application/vnd.ms-excel.sheet.binary.macroEnabled.12';
976
        $extension[] = '.xlsb';
977
        $mime_type[] = 'application/vnd.ms-excel.sheet.macroEnabled.12';
978
        $extension[] = '.xlsm';
979
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
980
        $extension[] = '.xlsx';
981
        $mime_type[] = 'application/vnd.ms-excel.template.macroEnabled.12';
982
        $extension[] = '.xltm';
983
        $mime_type[] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.template';
984
        $extension[] = '.xltx';
985
986
        // Test on PC (files with no extension get application/octet-stream)
987
        //$mime_type[] = 'application/octet-stream';      $extension[] = '.ext';
988
        // Check whether the MIME type sent by the browser is within the table
989
        foreach ($mime_type as $key => &$type) {
990
            if ($type == $file_type) {
991
                $file_name .= $extension[$key];
992
                break;
993
            }
994
        }
995
996
        unset($mime_type, $extension, $type, $key); // Delete to eschew possible collisions
997
    }
998
999
    return $file_name;
1000
}
1001
1002
/**
1003
 * Manages all the unzipping process of an uploaded file.
1004
 *
1005
 * @author Hugues Peeters <[email protected]>
1006
 *
1007
 * @param array  $uploaded_file    - follows the $_FILES Structure
1008
 * @param string $upload_path      - destination of the upload.
1009
 *                                 This path is to append to $base_work_dir
1010
 * @param string $base_work_dir    - base working directory of the module
1011
 * @param int    $max_filled_space - amount of bytes to not exceed in the base
1012
 *                                 working directory
1013
 *
1014
 * @return bool true if it succeeds false otherwise
1015
 */
1016
function unzip_uploaded_file($uploaded_file, $upload_path, $base_work_dir, $max_filled_space)
1017
{
1018
    $zip_file = new PclZip($uploaded_file['tmp_name']);
1019
1020
    // Check the zip content (real size and file extension)
1021
    if (file_exists($uploaded_file['tmp_name'])) {
1022
        $zip_content_array = $zip_file->listContent();
1023
        $ok_scorm = false;
1024
        $realFileSize = 0;
1025
        $ok_plantyn_scorm1 = false;
1026
        $ok_plantyn_scorm2 = false;
1027
        $ok_plantyn_scorm3 = false;
1028
        $ok_aicc_scorm = false;
1029
        foreach ($zip_content_array as $this_content) {
1030
            if (preg_match('~.(php.*|phtml|phar|htaccess)$~i', $this_content['filename'])) {
1031
                Display::addFlash(
1032
                    Display::return_message(get_lang('ZipNoPhp'))
1033
                );
1034
1035
                return false;
1036
            } elseif (stristr($this_content['filename'], 'imsmanifest.xml')) {
1037
                $ok_scorm = true;
1038
            } elseif (stristr($this_content['filename'], 'LMS')) {
1039
                $ok_plantyn_scorm1 = true;
1040
            } elseif (stristr($this_content['filename'], 'REF')) {
1041
                $ok_plantyn_scorm2 = true;
1042
            } elseif (stristr($this_content['filename'], 'SCO')) {
1043
                $ok_plantyn_scorm3 = true;
1044
            } elseif (stristr($this_content['filename'], 'AICC')) {
1045
                $ok_aicc_scorm = true;
1046
            }
1047
            $realFileSize += $this_content['size'];
1048
        }
1049
1050
        if (($ok_plantyn_scorm1 && $ok_plantyn_scorm2 && $ok_plantyn_scorm3) || $ok_aicc_scorm) {
1051
            $ok_scorm = true;
1052
        }
1053
1054
        if (!$ok_scorm && defined('CHECK_FOR_SCORM') && CHECK_FOR_SCORM) {
1055
            Display::addFlash(
1056
                Display::return_message(get_lang('NotScormContent'))
1057
            );
1058
1059
            return false;
1060
        }
1061
1062
        if (!enough_size($realFileSize, $base_work_dir, $max_filled_space)) {
1063
            Display::addFlash(
1064
                Display::return_message(get_lang('NoSpace'))
1065
            );
1066
1067
            return false;
1068
        }
1069
1070
        // It happens on Linux that $upload_path sometimes doesn't start with '/'
1071
        if ($upload_path[0] != '/' && substr($base_work_dir, -1, 1) != '/') {
1072
            $upload_path = '/'.$upload_path;
1073
        }
1074
1075
        if ($upload_path[strlen($upload_path) - 1] == '/') {
1076
            $upload_path = substr($upload_path, 0, -1);
1077
        }
1078
1079
        /*	Uncompressing phase */
1080
        $save_dir = getcwd();
1081
        chdir($base_work_dir.$upload_path);
1082
        $unzippingState = $zip_file->extract();
1083
        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...
1084
            $state = $unzippingState[$j];
1085
            // Fix relative links in html files
1086
            $extension = strrchr($state['stored_filename'], '.');
1087
        }
1088
        if ($dir = @opendir($base_work_dir.$upload_path)) {
1089
            while ($file = readdir($dir)) {
1090
                if ($file != '.' && $file != '..') {
1091
                    $filetype = 'file';
1092
                    if (is_dir($base_work_dir.$upload_path.'/'.$file)) {
1093
                        $filetype = 'folder';
1094
                    }
1095
1096
                    $safe_file = api_replace_dangerous_char($file);
1097
                    $safe_file = disable_dangerous_file($safe_file);
1098
1099
                    @rename($base_work_dir.$upload_path.'/'.$file, $base_work_dir.$upload_path.'/'.$safe_file);
1100
                    set_default_settings($upload_path, $safe_file, $filetype);
1101
                }
1102
            }
1103
1104
            closedir($dir);
1105
        } else {
1106
            error_log('Could not create directory '.$base_work_dir.$upload_path.' to unzip files');
1107
        }
1108
        chdir($save_dir); // Back to previous dir position
1109
    }
1110
1111
    return true;
1112
}
1113
1114
/**
1115
 * Manages all the unzipping process of an uploaded document
1116
 * This uses the item_property table for properties of documents.
1117
 *
1118
 * @author Hugues Peeters <[email protected]>
1119
 * @author Bert Vanderkimpen
1120
 *
1121
 * @param array  $courseInfo
1122
 * @param array  $userInfo
1123
 * @param array  $uploaded_file    - follows the $_FILES Structure
1124
 * @param string $uploadPath       - destination of the upload.
1125
 *                                 This path is to append to $base_work_dir
1126
 * @param string $base_work_dir    - base working directory of the module
1127
 * @param int    $maxFilledSpace   - amount of bytes to not exceed in the base
1128
 *                                 working directory
1129
 * @param int    $sessionId
1130
 * @param int    $groupId          group.id
1131
 * @param bool   $output           Optional. If no output not wanted on success, set to false.
1132
 * @param bool   $onlyUploadFile
1133
 * @param string $whatIfFileExists (only works if $onlyUploadFile is false)
1134
 *
1135
 * @return bool true if it succeeds false otherwise
1136
 */
1137
function unzip_uploaded_document(
1138
    $courseInfo,
1139
    $userInfo,
1140
    $uploaded_file,
1141
    $uploadPath,
1142
    $base_work_dir,
1143
    $maxFilledSpace,
1144
    $sessionId = 0,
1145
    $groupId = 0,
1146
    $output = true,
1147
    $onlyUploadFile = false,
1148
    $whatIfFileExists = 'overwrite'
1149
) {
1150
    if (empty($courseInfo) || empty($userInfo) || empty($uploaded_file) || empty($uploadPath)) {
1151
        return false;
1152
    }
1153
1154
    $zip = new PclZip($uploaded_file['tmp_name']);
1155
1156
    // Check the zip content (real size and file extension)
1157
    $zip_content_array = (array) $zip->listContent();
1158
    $realSize = 0;
1159
    foreach ($zip_content_array as &$this_content) {
1160
        $realSize += $this_content['size'];
1161
    }
1162
1163
    if (!DocumentManager::enough_space($realSize, $maxFilledSpace)) {
1164
        echo Display::return_message(get_lang('UplNotEnoughSpace'), 'error');
1165
1166
        return false;
1167
    }
1168
1169
    $folder = api_get_unique_id();
1170
    $destinationDir = api_get_path(SYS_ARCHIVE_PATH).$folder;
1171
    mkdir($destinationDir, api_get_permissions_for_new_directories(), true);
1172
1173
    // Uncompress zip file
1174
    // We extract using a callback function that "cleans" the path
1175
    $zip->extract(
1176
        PCLZIP_OPT_PATH,
1177
        $destinationDir,
1178
        PCLZIP_CB_PRE_EXTRACT,
1179
        'clean_up_files_in_zip',
1180
        PCLZIP_OPT_REPLACE_NEWER
1181
    );
1182
1183
    if ($onlyUploadFile === false) {
1184
        // Add all documents in the unzipped folder to the database
1185
        add_all_documents_in_folder_to_database(
1186
            $courseInfo,
1187
            $userInfo,
1188
            $base_work_dir,
1189
            $destinationDir,
1190
            $sessionId,
1191
            $groupId,
1192
            $output,
1193
            ['path' => $uploadPath],
1194
            $whatIfFileExists
1195
        );
1196
    } else {
1197
        // Copy result
1198
        $fs = new \Symfony\Component\Filesystem\Filesystem();
1199
        $fs->mirror($destinationDir, $base_work_dir.$uploadPath, null, ['overwrite']);
1200
    }
1201
1202
    if (is_dir($destinationDir)) {
1203
        rmdirr($destinationDir);
1204
    }
1205
1206
    return true;
1207
}
1208
1209
/**
1210
 * This function is a callback function that is used while extracting a zipfile
1211
 * http://www.phpconcept.net/pclzip/man/en/index.php?options-pclzip_cb_pre_extract.
1212
 *
1213
 * @param array $p_event
1214
 * @param array $p_header
1215
 *
1216
 * @return int (If the function returns 1, then the extraction is resumed, if 0 the path was skipped)
1217
 */
1218
function clean_up_files_in_zip($p_event, &$p_header)
1219
{
1220
    $originalStoredFileName = $p_header['stored_filename'];
1221
    $baseName = basename($originalStoredFileName);
1222
    // Skip files
1223
    $skipFiles = [
1224
        '__MACOSX',
1225
        '.Thumbs.db',
1226
        'Thumbs.db',
1227
    ];
1228
1229
    if (in_array($baseName, $skipFiles)) {
1230
        return 0;
1231
    }
1232
    $modifiedStoredFileName = clean_up_path($originalStoredFileName);
1233
    $p_header['filename'] = str_replace($originalStoredFileName, $modifiedStoredFileName, $p_header['filename']);
1234
1235
    return 1;
1236
}
1237
1238
function cleanZipFilesNoRename($p_event, &$p_header)
1239
{
1240
    $originalStoredFileName = $p_header['stored_filename'];
1241
    $baseName = basename($originalStoredFileName);
1242
    // Skip files
1243
    $skipFiles = [
1244
        '__MACOSX',
1245
        '.Thumbs.db',
1246
        'Thumbs.db',
1247
    ];
1248
1249
    if (in_array($baseName, $skipFiles)) {
1250
        return 0;
1251
    }
1252
    $modifiedStoredFileName = clean_up_path($originalStoredFileName, false);
1253
    $p_header['filename'] = str_replace($originalStoredFileName, $modifiedStoredFileName, $p_header['filename']);
1254
1255
    return 1;
1256
}
1257
1258
/**
1259
 * Allow .htaccess file.
1260
 *
1261
 * @param $p_event
1262
 * @param $p_header
1263
 *
1264
 * @return int
1265
 */
1266
function cleanZipFilesAllowHtaccess($p_event, &$p_header)
1267
{
1268
    $originalStoredFileName = $p_header['stored_filename'];
1269
    $baseName = basename($originalStoredFileName);
1270
1271
    $allowFiles = ['.htaccess'];
1272
    if (in_array($baseName, $allowFiles)) {
1273
        return 1;
1274
    }
1275
1276
    // Skip files
1277
    $skipFiles = [
1278
        '__MACOSX',
1279
        '.Thumbs.db',
1280
        'Thumbs.db',
1281
    ];
1282
1283
    if (in_array($baseName, $skipFiles)) {
1284
        return 0;
1285
    }
1286
    $modifiedStoredFileName = clean_up_path($originalStoredFileName);
1287
    $p_header['filename'] = str_replace($originalStoredFileName, $modifiedStoredFileName, $p_header['filename']);
1288
1289
    return 1;
1290
}
1291
1292
/**
1293
 * This function cleans up a given path
1294
 * by eliminating dangerous file names and cleaning them.
1295
 *
1296
 * @param string $path
1297
 * @param bool   $replaceName
1298
 *
1299
 * @return string
1300
 *
1301
 * @see disable_dangerous_file()
1302
 * @see api_replace_dangerous_char()
1303
 */
1304
function clean_up_path($path, $replaceName = true)
1305
{
1306
    // Split the path in folders and files
1307
    $path_array = explode('/', $path);
1308
    // Clean up every folder and filename in the path
1309
    foreach ($path_array as $key => &$val) {
1310
        // We don't want to lose the dots in ././folder/file (cfr. zipfile)
1311
        if ($val != '.') {
1312
            if ($replaceName) {
1313
                $val = api_replace_dangerous_char($val);
1314
            }
1315
            $val = disable_dangerous_file($val);
1316
        }
1317
    }
1318
    // Join the "cleaned" path (modified in-place as passed by reference)
1319
    $path = implode('/', $path_array);
1320
    filter_extension($path);
1321
1322
    return $path;
1323
}
1324
1325
/**
1326
 * Checks if the file is dangerous, based on extension and/or mimetype.
1327
 * The list of extensions accepted/rejected can be found from
1328
 * api_get_setting('upload_extensions_exclude') and api_get_setting('upload_extensions_include').
1329
 *
1330
 * @param string $filename passed by reference. The filename will be modified
1331
 *                         if filter rules say so! (you can include path but the filename should look like 'abc.html')
1332
 *
1333
 * @return int 0 to skip file, 1 to keep file
1334
 */
1335
function filter_extension(&$filename)
1336
{
1337
    if (substr($filename, -1) == '/') {
1338
        return 1; // Authorize directories
1339
    }
1340
    $blacklist = api_get_setting('upload_extensions_list_type');
1341
    if ($blacklist != 'whitelist') { // if = blacklist
1342
        $extensions = explode(';', strtolower(api_get_setting('upload_extensions_blacklist')));
1343
1344
        $skip = api_get_setting('upload_extensions_skip');
1345
        $ext = strrchr($filename, '.');
1346
        $ext = substr($ext, 1);
1347
        if (empty($ext)) {
1348
            return 1; // We're in blacklist mode, so accept empty extensions
1349
        }
1350
        if (in_array(strtolower($ext), $extensions)) {
1351
            if ($skip == 'true') {
1352
                return 0;
1353
            } else {
1354
                $new_ext = getReplacedByExtension();
1355
                $filename = str_replace('.'.$ext, '.'.$new_ext, $filename);
1356
1357
                return 1;
1358
            }
1359
        } else {
1360
            return 1;
1361
        }
1362
    } else {
1363
        $extensions = explode(';', strtolower(api_get_setting('upload_extensions_whitelist')));
1364
        $skip = api_get_setting('upload_extensions_skip');
1365
        $ext = strrchr($filename, '.');
1366
        $ext = substr($ext, 1);
1367
        if (empty($ext)) {
1368
            return 1; // Accept empty extensions
1369
        }
1370
        if (!in_array(strtolower($ext), $extensions)) {
1371
            if ($skip == 'true') {
1372
                return 0;
1373
            } else {
1374
                $new_ext = getReplacedByExtension();
1375
                $filename = str_replace('.'.$ext, '.'.$new_ext, $filename);
1376
1377
                return 1;
1378
            }
1379
        } else {
1380
            return 1;
1381
        }
1382
    }
1383
}
1384
1385
function getReplacedByExtension()
1386
{
1387
    $extension = api_get_setting('upload_extensions_replace_by');
1388
1389
    return 'REPLACED_'.api_replace_dangerous_char(str_replace('.', '', $extension));
1390
}
1391
1392
/**
1393
 * Adds a new document to the database.
1394
 *
1395
 * @param array  $courseInfo
1396
 * @param string $path
1397
 * @param string $fileType
1398
 * @param int    $fileSize
1399
 * @param string $title
1400
 * @param string $comment
1401
 * @param int    $readonly
1402
 * @param bool   $saveVisibility
1403
 * @param int    $group_id         group.id
1404
 * @param int    $sessionId        Session ID, if any
1405
 * @param int    $userId           creator user id
1406
 * @param bool   $sendNotification
1407
 *
1408
 * @return int id if inserted document
1409
 */
1410
function add_document(
1411
    $courseInfo,
1412
    $path,
1413
    $fileType,
1414
    $fileSize,
1415
    $title,
1416
    $comment = null,
1417
    $readonly = 0,
1418
    $saveVisibility = true,
1419
    $group_id = 0,
1420
    $sessionId = 0,
1421
    $userId = 0,
1422
    $sendNotification = true
1423
) {
1424
    $sessionId = empty($sessionId) ? api_get_session_id() : $sessionId;
1425
    $userId = empty($userId) ? api_get_user_id() : $userId;
1426
1427
    $readonly = (int) $readonly;
1428
    $c_id = $courseInfo['real_id'];
1429
    $params = [
1430
        'c_id' => $c_id,
1431
        'path' => $path,
1432
        'filetype' => $fileType,
1433
        'size' => $fileSize,
1434
        'title' => $title,
1435
        'comment' => $comment,
1436
        'readonly' => $readonly,
1437
        'session_id' => $sessionId,
1438
    ];
1439
    $table = Database::get_course_table(TABLE_DOCUMENT);
1440
    $documentId = Database::insert($table, $params);
1441
    if ($documentId) {
1442
        $sql = "UPDATE $table SET id = iid WHERE iid = $documentId";
1443
        Database::query($sql);
1444
1445
        if ($saveVisibility) {
1446
            api_set_default_visibility(
1447
                $documentId,
1448
                TOOL_DOCUMENT,
1449
                $group_id,
1450
                $courseInfo,
1451
                $sessionId,
1452
                $userId
1453
            );
1454
        }
1455
1456
        $allowNotification = api_get_configuration_value('send_notification_when_document_added');
1457
        if ($sendNotification && $allowNotification) {
1458
            $courseTitle = $courseInfo['title'];
1459
            if (!empty($sessionId)) {
1460
                $sessionInfo = api_get_session_info($sessionId);
1461
                $courseTitle .= " ( ".$sessionInfo['name'].") ";
1462
            }
1463
1464
            $url = api_get_path(WEB_CODE_PATH).
1465
                'document/showinframes.php?cidReq='.$courseInfo['code'].'&id_session='.$sessionId.'&id='.$documentId;
1466
            $link = Display::url(basename($title), $url, ['target' => '_blank']);
1467
            $userInfo = api_get_user_info($userId);
1468
1469
            $message = sprintf(
1470
                get_lang('DocumentXHasBeenAddedToDocumentInYourCourseXByUserX'),
1471
                $link,
1472
                $courseTitle,
1473
                $userInfo['complete_name']
1474
            );
1475
            $subject = sprintf(get_lang('NewDocumentAddedToCourseX'), $courseTitle);
1476
            MessageManager::sendMessageToAllUsersInCourse($subject, $message, $courseInfo, $sessionId);
1477
        }
1478
1479
        return $documentId;
1480
    } else {
1481
        return false;
1482
    }
1483
}
1484
1485
/**
1486
 * Updates an existing document in the database
1487
 * as the file exists, we only need to change the size.
1488
 *
1489
 * @param array $_course
1490
 * @param int   $documentId
1491
 * @param int   $filesize
1492
 * @param int   $readonly
1493
 *
1494
 * @return bool true /false
1495
 */
1496
function update_existing_document($_course, $documentId, $filesize, $readonly = 0)
1497
{
1498
    $document_table = Database::get_course_table(TABLE_DOCUMENT);
1499
    $documentId = intval($documentId);
1500
    $filesize = intval($filesize);
1501
    $readonly = intval($readonly);
1502
    $course_id = $_course['real_id'];
1503
1504
    $sql = "UPDATE $document_table SET
1505
            size = '$filesize',
1506
            readonly = '$readonly'
1507
			WHERE c_id = $course_id AND id = $documentId";
1508
    if (Database::query($sql)) {
1509
        return true;
1510
    } else {
1511
        return false;
1512
    }
1513
}
1514
1515
/**
1516
 * This function updates the last_edit_date, last edit user id on all folders in a given path.
1517
 *
1518
 * @param array  $_course
1519
 * @param string $path
1520
 * @param int    $user_id
1521
 */
1522
function item_property_update_on_folder($_course, $path, $user_id)
1523
{
1524
    // If we are in the root, just return... no need to update anything
1525
    if ($path == '/') {
1526
        return;
1527
    }
1528
1529
    $user_id = intval($user_id);
1530
1531
    // If the given path ends with a / we remove it
1532
    $endchar = substr($path, strlen($path) - 1, 1);
1533
    if ($endchar == '/') {
1534
        $path = substr($path, 0, strlen($path) - 1);
1535
    }
1536
1537
    $table = Database::get_course_table(TABLE_ITEM_PROPERTY);
1538
1539
    // Get the time
1540
    $time = api_get_utc_datetime();
1541
1542
    // Det all paths in the given path
1543
    // /folder/subfolder/subsubfolder/file
1544
    // if file is updated, subsubfolder, subfolder and folder are updated
1545
    $exploded_path = explode('/', $path);
1546
    $course_id = api_get_course_int_id();
1547
    $newpath = '';
1548
    foreach ($exploded_path as $key => &$value) {
1549
        // We don't want a slash before our first slash
1550
        if ($key != 0) {
1551
            $newpath .= '/'.$value;
1552
            // Select ID of given folder
1553
            $folder_id = DocumentManager::get_document_id($_course, $newpath);
1554
1555
            if ($folder_id) {
1556
                $sql = "UPDATE $table SET
1557
				        lastedit_date = '$time',
1558
				        lastedit_type = 'DocumentInFolderUpdated',
1559
				        lastedit_user_id='$user_id'
1560
						WHERE
1561
						    c_id = $course_id AND
1562
						    tool='".TOOL_DOCUMENT."' AND
1563
						    ref = '$folder_id'";
1564
                Database::query($sql);
1565
            }
1566
        }
1567
    }
1568
}
1569
1570
/**
1571
 * Adds file to document table in database
1572
 * deprecated: use file_set_default_settings instead.
1573
 *
1574
 * @author	Olivier Cauberghe <[email protected]>
1575
 *
1576
 * @param	path,filename
1577
 * action:	Adds an entry to the document table with the default settings
1578
 */
1579
function set_default_settings($upload_path, $filename, $filetype = 'file')
1580
{
1581
    $dbTable = Database::get_course_table(TABLE_DOCUMENT);
1582
    global $default_visibility;
1583
1584
    if (!$default_visibility) {
1585
        $default_visibility = 'v';
1586
    }
1587
    $filetype = Database::escape_string($filetype);
1588
1589
    $upload_path = str_replace('\\', '/', $upload_path);
1590
    $upload_path = str_replace('//', '/', $upload_path);
1591
1592
    if ($upload_path == '/') {
1593
        $upload_path = '';
1594
    } elseif (!empty($upload_path) && $upload_path[0] != '/') {
1595
        $upload_path = "/$upload_path";
1596
    }
1597
1598
    $endchar = substr($filename, strlen($filename) - 1, 1);
1599
1600
    if ($endchar == '/') {
1601
        $filename = substr($filename, 0, -1);
1602
    }
1603
    $filename = Database::escape_string($filename);
1604
    $query = "SELECT count(*) as bestaat FROM $dbTable
1605
              WHERE path='$upload_path/$filename'";
1606
    $result = Database::query($query);
1607
    $row = Database::fetch_array($result);
1608
    if ($row['bestaat'] > 0) {
1609
        $query = "UPDATE $dbTable SET
1610
		            path='$upload_path/$filename',
1611
		            visibility='$default_visibility',
1612
		            filetype='$filetype'
1613
		          WHERE path='$upload_path/$filename'";
1614
    } else {
1615
        $query = "INSERT INTO $dbTable (path,visibility,filetype)
1616
		          VALUES('$upload_path/$filename','$default_visibility','$filetype')";
1617
    }
1618
    Database::query($query);
1619
}
1620
1621
/**
1622
 * Retrieves the image path list in a html file.
1623
 *
1624
 * @author Hugues Peeters <[email protected]>
1625
 *
1626
 * @param string $html_file
1627
 *
1628
 * @return array -  images path list
1629
 */
1630
function search_img_from_html($html_file)
1631
{
1632
    $img_path_list = [];
1633
1634
    if (!$fp = fopen($html_file, 'r')) {
1635
        return;
1636
    }
1637
1638
    // Aearch and store occurences of the <img> tag in an array
1639
    $size_file = (filesize($html_file) === 0) ? 1 : filesize($html_file);
1640
    if (isset($fp) && $fp !== false) {
1641
        $buffer = fread($fp, $size_file);
1642
        if (strlen($buffer) >= 0 && $buffer !== false) {
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
    } else {
1647
        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...
1648
    }
1649
    $matches = [];
1650
    if (preg_match_all('~<[[:space:]]*img[^>]*>~i', $buffer, $matches)) {
1651
        $img_tag_list = $matches[0];
1652
    }
1653
1654
    fclose($fp);
1655
    unset($buffer);
1656
1657
    // Search the image file path from all the <IMG> tag detected
1658
1659
    if (sizeof($img_tag_list) > 0) {
1660
        foreach ($img_tag_list as &$this_img_tag) {
1661
            if (preg_match('~src[[:space:]]*=[[:space:]]*[\"]{1}([^\"]+)[\"]{1}~i', $this_img_tag, $matches)) {
1662
                $img_path_list[] = $matches[1];
1663
            }
1664
        }
1665
        $img_path_list = array_unique($img_path_list); // Remove duplicate entries
1666
    }
1667
1668
    return $img_path_list;
1669
}
1670
1671
/**
1672
 * Creates a new directory trying to find a directory name
1673
 * that doesn't already exist.
1674
 *
1675
 * @author  Hugues Peeters <[email protected]>
1676
 * @author  Bert Vanderkimpen
1677
 *
1678
 * @param array  $_course                 current course information
1679
 * @param int    $user_id                 current user id
1680
 * @param int    $session_id
1681
 * @param int    $to_group_id             group.id
1682
 * @param int    $to_user_id
1683
 * @param string $base_work_dir           /var/www/chamilo/courses/ABC/document
1684
 * @param string $desired_dir_name        complete path of the desired name
1685
 *                                        Example: /folder1/folder2
1686
 * @param string $title                   "folder2"
1687
 * @param int    $visibility              (0 for invisible, 1 for visible, 2 for deleted)
1688
 * @param bool   $generateNewNameIfExists
1689
 * @param bool   $sendNotification        depends in conf setting "send_notification_when_document_added"
1690
 *
1691
 * @return string actual directory name if it succeeds,
1692
 *                boolean false otherwise
1693
 */
1694
function create_unexisting_directory(
1695
    $_course,
1696
    $user_id,
1697
    $session_id,
1698
    $to_group_id,
1699
    $to_user_id,
1700
    $base_work_dir,
1701
    $desired_dir_name,
1702
    $title = '',
1703
    $visibility = '',
1704
    $generateNewNameIfExists = false,
1705
    $sendNotification = true
1706
) {
1707
    $course_id = $_course['real_id'];
1708
    $session_id = (int) $session_id;
1709
1710
    $folderExists = DocumentManager::folderExists(
1711
        $desired_dir_name,
1712
        $_course,
1713
        $session_id,
1714
        $to_group_id
1715
    );
1716
1717
    if ($folderExists === true) {
1718
        if ($generateNewNameIfExists) {
1719
            $counter = 1;
1720
            while (1) {
1721
                $folderExists = DocumentManager::folderExists(
1722
                    $desired_dir_name.'_'.$counter,
1723
                    $_course,
1724
                    $session_id,
1725
                    $to_group_id
1726
                );
1727
1728
                if ($folderExists === false) {
1729
                    break;
1730
                }
1731
                $counter++;
1732
            }
1733
            $desired_dir_name = $desired_dir_name.'_'.$counter;
1734
        } else {
1735
            return false;
1736
        }
1737
    }
1738
1739
    $systemFolderName = $desired_dir_name;
1740
1741
    // Adding suffix
1742
    $suffix = DocumentManager::getDocumentSuffix(
1743
        $_course,
1744
        $session_id,
1745
        $to_group_id
1746
    );
1747
1748
    $systemFolderName .= $suffix;
1749
1750
    if ($title == null) {
1751
        $title = basename($desired_dir_name);
1752
    }
1753
1754
    if (!is_dir($base_work_dir.$systemFolderName)) {
1755
        $result = @mkdir(
1756
            $base_work_dir.$systemFolderName,
1757
            api_get_permissions_for_new_directories(),
1758
            true
1759
        );
1760
1761
        if ($result) {
1762
            // Check if pathname already exists inside document table
1763
            $tbl_document = Database::get_course_table(TABLE_DOCUMENT);
1764
            $sql = "SELECT id, path FROM $tbl_document
1765
                    WHERE
1766
                        c_id = $course_id AND
1767
                        (
1768
                            path = '".Database::escape_string($systemFolderName)."'
1769
                        )
1770
            ";
1771
1772
            $groupInfo = [];
1773
            if (!empty($to_group_id)) {
1774
                $groupInfo = GroupManager::get_group_properties($to_group_id);
1775
            }
1776
1777
            $rs = Database::query($sql);
1778
            if (Database::num_rows($rs) == 0) {
1779
                $document_id = add_document(
1780
                    $_course,
1781
                    $systemFolderName,
1782
                    'folder',
1783
                    0,
1784
                    $title,
1785
                    null,
1786
                    0,
1787
                    true,
1788
                    $to_group_id,
1789
                    $session_id,
1790
                    $user_id,
1791
                    $sendNotification
1792
                );
1793
1794
                if ($document_id) {
1795
                    $lastEditType = [
1796
                        0 => 'invisible',
1797
                        1 => 'visible',
1798
                        2 => 'delete',
1799
                    ];
1800
                    // Update document item_property
1801
                    if (isset($lastEditType[$visibility])) {
1802
                        api_item_property_update(
1803
                            $_course,
1804
                            TOOL_DOCUMENT,
1805
                            $document_id,
1806
                            $lastEditType[$visibility],
1807
                            $user_id,
1808
                            $groupInfo,
1809
                            $to_user_id,
1810
                            null,
1811
                            null,
1812
                            $session_id
1813
                        );
1814
                    } else {
1815
                        api_item_property_update(
1816
                            $_course,
1817
                            TOOL_DOCUMENT,
1818
                            $document_id,
1819
                            'FolderCreated',
1820
                            $user_id,
1821
                            $groupInfo,
1822
                            $to_user_id,
1823
                            null,
1824
                            null,
1825
                            $session_id
1826
                        );
1827
                    }
1828
1829
                    $documentData = DocumentManager::get_document_data_by_id(
1830
                        $document_id,
1831
                        $_course['code'],
1832
                        false,
1833
                        $session_id
1834
                    );
1835
1836
                    return $documentData;
1837
                }
1838
            } else {
1839
                $document = Database::fetch_array($rs);
1840
                $documentData = DocumentManager::get_document_data_by_id(
1841
                    $document['id'],
1842
                    $_course['code'],
1843
                    false,
1844
                    $session_id
1845
                );
1846
1847
                /* This means the folder NOT exist in the filesystem
1848
                 (now this was created) but there is a record in the Database*/
1849
1850
                return $documentData;
1851
            }
1852
        }
1853
    }
1854
1855
    return false;
1856
}
1857
1858
/**
1859
 * Handles uploaded missing images.
1860
 *
1861
 * @author Hugues Peeters <[email protected]>
1862
 * @author Bert Vanderkimpen
1863
 *
1864
 * @param array  $_course
1865
 * @param array  $uploaded_file_collection - follows the $_FILES Structure
1866
 * @param string $base_work_dir
1867
 * @param string $missing_files_dir
1868
 * @param int    $user_id
1869
 * @param int    $to_group_id              group.id
1870
 */
1871
function move_uploaded_file_collection_into_directory(
1872
    $_course,
1873
    $uploaded_file_collection,
1874
    $base_work_dir,
1875
    $missing_files_dir,
1876
    $user_id,
1877
    $to_group_id,
1878
    $to_user_id,
1879
    $max_filled_space
1880
) {
1881
    $number_of_uploaded_images = count($uploaded_file_collection['name']);
1882
    $list = [];
1883
    for ($i = 0; $i < $number_of_uploaded_images; $i++) {
1884
        $missing_file['name'] = $uploaded_file_collection['name'][$i];
1885
        $missing_file['type'] = $uploaded_file_collection['type'][$i];
1886
        $missing_file['tmp_name'] = $uploaded_file_collection['tmp_name'][$i];
1887
        $missing_file['error'] = $uploaded_file_collection['error'][$i];
1888
        $missing_file['size'] = $uploaded_file_collection['size'][$i];
1889
1890
        $upload_ok = process_uploaded_file($missing_file);
1891
        if ($upload_ok) {
1892
            $list[] = handle_uploaded_document(
1893
                $_course,
1894
                $missing_file,
1895
                $base_work_dir,
1896
                $missing_files_dir,
1897
                $user_id,
1898
                $to_group_id,
1899
                $to_user_id,
1900
                $max_filled_space,
1901
                0,
1902
                'overwrite'
1903
            );
1904
        }
1905
        unset($missing_file);
1906
    }
1907
1908
    return $list;
1909
}
1910
1911
/**
1912
 * Opens the old html file and replace the src path into the img tag
1913
 * This also works for files in subdirectories.
1914
 *
1915
 * @param $original_img_path is an array
1916
 * @param $new_img_path is an array
1917
 */
1918
function replace_img_path_in_html_file($original_img_path, $new_img_path, $html_file)
1919
{
1920
    // Open the file
1921
    $fp = fopen($html_file, 'r');
1922
    $buffer = fread($fp, filesize($html_file));
1923
    $new_html_content = '';
1924
1925
    // Fix the image tags
1926
    for ($i = 0, $fileNb = count($original_img_path); $i < $fileNb; $i++) {
1927
        $replace_what = $original_img_path[$i];
1928
        // We only need the directory and the filename /path/to/file_html_files/missing_file.gif -> file_html_files/missing_file.gif
1929
        $exploded_file_path = explode('/', $new_img_path[$i]);
1930
        $replace_by = $exploded_file_path[count($exploded_file_path) - 2].'/'.$exploded_file_path[count($exploded_file_path) - 1];
1931
        $buffer = str_replace($replace_what, $replace_by, $buffer);
1932
    }
1933
1934
    $new_html_content .= $buffer;
1935
1936
    @fclose($fp);
1937
1938
    // Write the resulted new file
1939
1940
    if (!$fp = fopen($html_file, 'w')) {
1941
        return;
1942
    }
1943
1944
    if (!fwrite($fp, $new_html_content)) {
1945
        return;
1946
    }
1947
}
1948
1949
/**
1950
 * Checks the extension of a file, if it's .htm or .html
1951
 * we use search_img_from_html to get all image paths in the file.
1952
 *
1953
 * @param string $file
1954
 *
1955
 * @return array paths
1956
 *
1957
 * @see check_for_missing_files() uses search_img_from_html()
1958
 */
1959
function check_for_missing_files($file)
1960
{
1961
    if (strrchr($file, '.') == '.htm' || strrchr($file, '.') == '.html') {
1962
        $img_file_path = search_img_from_html($file);
1963
1964
        return $img_file_path;
1965
    }
1966
1967
    return false;
1968
}
1969
1970
/**
1971
 * This function builds a form that asks for the missing images in a html file
1972
 * maybe we should do this another way?
1973
 *
1974
 * @param array  $missing_files
1975
 * @param string $upload_path
1976
 * @param string $file_name
1977
 *
1978
 * @return string the form
1979
 */
1980
function build_missing_files_form($missing_files, $upload_path, $file_name)
1981
{
1982
    // Do we need a / or not?
1983
    $added_slash = ($upload_path == '/') ? '' : '/';
1984
    $folder_id = DocumentManager::get_document_id(api_get_course_info(), $upload_path);
1985
    // Build the form
1986
    $form = "<p><strong>".get_lang('MissingImagesDetected')."</strong></p>"
1987
        ."<form method=\"post\" action=\"".api_get_self()."\" enctype=\"multipart/form-data\">"
1988
        // Related_file is the path to the file that has missing images
1989
        ."<input type=\"hidden\" name=\"related_file\" value=\"".$upload_path.$added_slash.$file_name."\" />"
1990
        ."<input type=\"hidden\" name=\"upload_path\" value=\"".$upload_path."\" />"
1991
        ."<input type=\"hidden\" name=\"id\" value=\"".$folder_id."\" />"
1992
        ."<table border=\"0\">";
1993
    foreach ($missing_files as &$this_img_file_path) {
1994
        $form .= "<tr>"
1995
            ."<td>".basename($this_img_file_path)." : </td>"
1996
            ."<td>"
1997
            ."<input type=\"file\" name=\"img_file[]\"/>"
1998
            ."<input type=\"hidden\" name=\"img_file_path[]\" value=\"".$this_img_file_path."\" />"
1999
            ."</td>"
2000
            ."</tr>";
2001
    }
2002
    $form .= "</table>"
2003
        ."<button type='submit' name=\"cancel_submit_image\" value=\"".get_lang('Cancel')."\" class=\"cancel\">".get_lang('Cancel')."</button>"
2004
        ."<button type='submit' name=\"submit_image\" value=\"".get_lang('Ok')."\" class=\"save\">".get_lang('Ok')."</button>"
2005
        ."</form>";
2006
2007
    return $form;
2008
}
2009
2010
/**
2011
 * This recursive function can be used during the upgrade process form older
2012
 * versions of Chamilo
2013
 * It crawls the given directory, checks if the file is in the DB and adds
2014
 * it if it's not.
2015
 *
2016
 * @param array  $courseInfo
2017
 * @param array  $userInfo
2018
 * @param string $base_work_dir    course document dir
2019
 * @param string $folderPath       folder to read
2020
 * @param int    $sessionId
2021
 * @param int    $groupId          group.id
2022
 * @param bool   $output
2023
 * @param array  $parent
2024
 * @param string $whatIfFileExists
2025
 *
2026
 * @return bool
2027
 */
2028
function add_all_documents_in_folder_to_database(
2029
    $courseInfo,
2030
    $userInfo,
2031
    $base_work_dir,
2032
    $folderPath,
2033
    $sessionId = 0,
2034
    $groupId = 0,
2035
    $output = false,
2036
    $parent = [],
2037
    $whatIfFileExists = 'overwrite'
2038
) {
2039
    if (empty($userInfo) || empty($courseInfo)) {
2040
        return false;
2041
    }
2042
2043
    $userId = $userInfo['user_id'];
2044
2045
    // Open dir
2046
    $handle = opendir($folderPath);
2047
2048
    if (is_dir($folderPath)) {
2049
        // Run trough
2050
        while ($file = readdir($handle)) {
2051
            if ($file == '.' || $file == '..') {
2052
                continue;
2053
            }
2054
2055
            $parentPath = '';
2056
            if (!empty($parent) && isset($parent['path'])) {
2057
                $parentPath = $parent['path'];
2058
                if ($parentPath == '/') {
2059
                    $parentPath = '';
2060
                }
2061
            }
2062
2063
            $completePath = $parentPath.'/'.$file;
2064
            $sysFolderPath = $folderPath.'/'.$file;
2065
2066
            // Is directory?
2067
            if (is_dir($sysFolderPath)) {
2068
                $folderExists = DocumentManager::folderExists(
2069
                    $completePath,
2070
                    $courseInfo,
2071
                    $sessionId,
2072
                    $groupId
2073
                );
2074
2075
                if ($folderExists === true) {
2076
                    switch ($whatIfFileExists) {
2077
                        case 'overwrite':
2078
                            $documentId = DocumentManager::get_document_id($courseInfo, $completePath, $sessionId);
2079
                            if ($documentId) {
2080
                                $newFolderData = DocumentManager::get_document_data_by_id(
2081
                                    $documentId,
2082
                                    $courseInfo['code'],
2083
                                    false,
2084
                                    $sessionId
2085
                                );
2086
                            }
2087
                            break;
2088
                        case 'rename':
2089
                            $newFolderData = create_unexisting_directory(
2090
                                $courseInfo,
2091
                                $userId,
2092
                                $sessionId,
2093
                                $groupId,
2094
                                null,
2095
                                $base_work_dir,
2096
                                $completePath,
2097
                                null,
2098
                                null,
2099
                                true
2100
                            );
2101
                            break;
2102
                        case 'nothing':
2103
                            if ($output) {
2104
                                $documentId = DocumentManager::get_document_id($courseInfo, $completePath, $sessionId);
2105
                                if ($documentId) {
2106
                                    $folderData = DocumentManager::get_document_data_by_id(
2107
                                        $documentId,
2108
                                        $courseInfo['code'],
2109
                                        false,
2110
                                        $sessionId
2111
                                    );
2112
                                    Display::addFlash(
2113
                                        Display::return_message(
2114
                                            $folderData['path'].' '.get_lang('UplAlreadyExists'),
2115
                                            'warning'
2116
                                        )
2117
                                    );
2118
                                }
2119
                            }
2120
                            continue 2;
2121
                            break;
2122
                    }
2123
                } else {
2124
                    $newFolderData = create_unexisting_directory(
2125
                        $courseInfo,
2126
                        $userId,
2127
                        $sessionId,
2128
                        $groupId,
2129
                        null,
2130
                        $base_work_dir,
2131
                        $completePath,
2132
                        null,
2133
                        null,
2134
                        false
2135
                    );
2136
                }
2137
2138
                // Recursive
2139
                add_all_documents_in_folder_to_database(
2140
                    $courseInfo,
2141
                    $userInfo,
2142
                    $base_work_dir,
2143
                    $sysFolderPath,
2144
                    $sessionId,
2145
                    $groupId,
2146
                    $output,
2147
                    $newFolderData,
2148
                    $whatIfFileExists
2149
                );
2150
            } else {
2151
                // Rename
2152
                $uploadedFile = [
2153
                    'name' => $file,
2154
                    'tmp_name' => $sysFolderPath,
2155
                    'size' => filesize($sysFolderPath),
2156
                    'type' => null,
2157
                    'from_file' => true,
2158
                    'move_file' => true,
2159
                ];
2160
2161
                handle_uploaded_document(
2162
                    $courseInfo,
2163
                    $uploadedFile,
2164
                    $base_work_dir,
2165
                    $parentPath,
2166
                    $userId,
2167
                    $groupId,
2168
                    null,
2169
                    0,
2170
                    $whatIfFileExists,
2171
                    $output,
2172
                    false,
2173
                    null,
2174
                    $sessionId
2175
                );
2176
            }
2177
        }
2178
    }
2179
}
2180
2181
/**
2182
 * Get the uploax max filesize from ini php in bytes.
2183
 *
2184
 * @return int
2185
 */
2186
function getIniMaxFileSizeInBytes($humanReadable = false, $checkMessageSetting = false)
2187
{
2188
    $maxSize = 0;
2189
    $uploadMaxFilesize = ini_get('upload_max_filesize');
2190
    $fileSizeForTeacher = getFileUploadSizeLimitForTeacher();
2191
    if (!empty($fileSizeForTeacher)) {
2192
        $uploadMaxFilesize = $fileSizeForTeacher.'M';
2193
    }
2194
2195
    if (empty($fileSizeForTeacher) && $checkMessageSetting) {
2196
        $uploadMaxFilesize = api_get_setting('message_max_upload_filesize'); // in bytes
2197
        if ($humanReadable) {
2198
            $uploadMaxFilesize = format_file_size($uploadMaxFilesize);
2199
        }
2200
2201
        return $uploadMaxFilesize;
2202
    }
2203
2204
    if ($humanReadable) {
2205
        return $uploadMaxFilesize;
2206
    }
2207
2208
    if (preg_match('/^([0-9]+)([a-zA-Z]*)$/', $uploadMaxFilesize, $matches)) {
2209
        // see http://www.php.net/manual/en/faq.using.php#faq.using.shorthandbytes
2210
        switch (strtoupper($matches['2'])) {
2211
            case 'G':
2212
                $maxSize = $matches['1'] * 1073741824;
2213
                break;
2214
            case 'M':
2215
                $maxSize = $matches['1'] * 1048576;
2216
                break;
2217
            case 'K':
2218
                $maxSize = $matches['1'] * 1024;
2219
                break;
2220
            default:
2221
                $maxSize = $matches['1'];
2222
        }
2223
    }
2224
    $maxSize = (int) $maxSize;
2225
2226
    return $maxSize;
2227
}
2228
2229
/**
2230
 * Get the uploax max filesize from configuration.php for trainers in bytes.
2231
 *
2232
 * @return int
2233
 */
2234
function getFileUploadSizeLimitForTeacher()
2235
{
2236
    $size = 0;
2237
    $settingValue = (int) api_get_configuration_value('file_upload_size_limit_for_teacher'); // setting value in MB
2238
    if ($settingValue > 0 && (api_is_allowed_to_create_course() && !api_is_platform_admin())) {
2239
        $size = $settingValue;
2240
    }
2241
2242
    return $size;
2243
}
2244