ILIAS  release_8 Revision v8.24
class.ilFileUtils.php
Go to the documentation of this file.
1<?php
2
24
33{
37 public static function processZipFile(
38 string $a_directory,
39 string $a_file,
40 bool $structure
41 ): void {
42 global $DIC;
43
44 $lng = $DIC->language();
45
46 $pathinfo = pathinfo($a_file);
47 $file = $pathinfo["basename"];
48
49 // see 22727
50 if ($pathinfo["extension"] ?? '' === '') {
51 $file .= ".zip";
52 }
53
54 // Copy zip-file to new directory, unzip and remove it
55 // TODO: check archive for broken file
56 //copy ($a_file, $a_directory . "/" . $file);
57 self::moveUploadedFile($a_file, $file, $a_directory . "/" . $file);
58 self::unzip($a_directory . "/" . $file);
59 unlink($a_directory . "/" . $file);
60 //echo "-".$a_directory . "/" . $file."-";
61 // Stores filename and paths into $filearray to check for viruses
62 // Checks if filenames can be read, else -> throw exception and leave
63 $filearray = [];
64 ilFileUtils::recursive_dirscan($a_directory, $filearray);
65
66 // if there are no files unziped (->broken file!)
67 if (empty($filearray)) {
68 throw new ilFileUtilsException(
69 $lng->txt("archive_broken"),
71 );
72 }
73
74 // virus handling
75 foreach ($filearray["file"] as $key => $value) {
76 // remove "invisible" files
77 if (substr($value, 0, 1) == "." || stristr(
78 $filearray["path"][$key],
79 "/__MACOSX/"
80 )) {
81 unlink($filearray["path"][$key] . $value);
82 unset($filearray["path"][$key]);
83 unset($filearray["file"][$key]);
84 continue;
85 }
86
87 $vir = ilVirusScanner::virusHandling($filearray["path"][$key], $value);
88 if (!$vir[0]) {
89 // Unlink file and throw exception
90 unlink($filearray['path'][$key]);
91 throw new ilFileUtilsException(
92 $lng->txt("file_is_infected") . "<br />" . $vir[1],
94 );
95 } elseif ($vir[1] != "") {
96 throw new ilFileUtilsException(
97 $vir[1],
99 );
100 }
101 }
102
103 // If archive is to be used "flat"
104 $doublettes = '';
105 if (!$structure) {
106 foreach (array_count_values($filearray["file"]) as $key => $value) {
107 // Archive contains same filenames in different directories
108 if ($value != "1") {
109 $doublettes .= " '" . ilFileUtils::utf8_encode($key) . "'";
110 }
111 }
112 if (strlen($doublettes) > 0) {
113 throw new ilFileUtilsException(
114 $lng->txt("exc_upload_error") . "<br />" . $lng->txt(
115 "zip_structure_error"
116 ) . $doublettes,
118 );
119 }
120 } else {
121 $mac_dir = $a_directory . "/__MACOSX";
122 if (file_exists($mac_dir)) {
123 self::delDir($mac_dir);
124 }
125 }
126 }
127
137 public static function recursive_dirscan(string $dir, array &$arr): void
138 {
139 global $DIC;
140
141 $lng = $DIC->language();
142
143 $dirlist = opendir($dir);
144 while (false !== ($file = readdir($dirlist))) {
145 if (!is_file($dir . "/" . $file) && !is_dir($dir . "/" . $file)) {
146 throw new ilFileUtilsException(
147 $lng->txt("filenames_not_supported"),
149 );
150 }
151
152 if ($file != '.' && $file != '..') {
153 $newpath = $dir . '/' . $file;
154 $level = explode('/', $newpath);
155 if (is_dir($newpath)) {
156 ilFileUtils::recursive_dirscan($newpath, $arr);
157 } else {
158 $arr["path"][] = $dir . "/";
159 $arr["file"][] = end($level);
160 }
161 }
162 }
163 closedir($dirlist);
164 }
165
175 public static function utf8_encode(string $string): string
176 {
177
178 // From http://w3.org/International/questions/qa-forms-utf-8.html
179 return (preg_match(
180 '%^(?:
181 [\x09\x0A\x0D\x20-\x7E] # ASCII
182 | [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
183 | \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs
184 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte
185 | \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates
186 | \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3
187 | [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15
188 | \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16
189 )*$%xs',
190 $string
191 )) ? $string : utf8_encode($string);
192 }
193
197 public static function getValidFilename(string $a_filename): string
198 {
199 global $DIC;
200 $sanitizer = new ilFileServicesFilenameSanitizer(
201 $DIC->fileServiceSettings()
202 );
203
204 return $sanitizer->sanitize($a_filename);
205 }
206
210 public static function rename(string $a_source, string $a_target): bool
211 {
212 $pi = pathinfo($a_target);
213 global $DIC;
214 $sanitizer = new ilFileServicesFilenameSanitizer(
215 $DIC->fileServiceSettings()
216 );
217
218 if (!$sanitizer->isClean($a_target)) {
219 throw new ilFileUtilsException("Invalid target file");
220 }
221
222 return rename($a_source, $a_target);
223 }
224
242 public static function rCopy(
243 string $a_sdir,
244 string $a_tdir,
245 bool $preserveTimeAttributes = false
246 ): bool {
247 $sourceFS = LegacyPathHelper::deriveFilesystemFrom($a_sdir);
248 $targetFS = LegacyPathHelper::deriveFilesystemFrom($a_tdir);
249
250 $sourceDir = LegacyPathHelper::createRelativePath($a_sdir);
251 $targetDir = LegacyPathHelper::createRelativePath($a_tdir);
252
253 // check if arguments are directories
254 if (!$sourceFS->hasDir($sourceDir)) {
255 return false;
256 }
257
258 $sourceList = $sourceFS->listContents($sourceDir, true);
259
260 foreach ($sourceList as $item) {
261 if ($item->isDir()) {
262 continue;
263 }
264 try {
265 $itemPath = $targetDir . '/' . substr(
266 $item->getPath(),
267 strlen($sourceDir)
268 );
269 $stream = $sourceFS->readStream($item->getPath());
270 $targetFS->writeStream($itemPath, $stream);
271 } catch (\ILIAS\Filesystem\Exception\FileAlreadyExistsException $e) {
272 // Do nothing with that type of exception
273 }
274 }
275
276 return true;
277 }
278
298 public static function makeDirParents(string $a_dir): bool
299 {
300 $dirs = [$a_dir];
301 $a_dir = dirname($a_dir);
302 $last_dirname = '';
303 while ($last_dirname != $a_dir) {
304 array_unshift($dirs, $a_dir);
305 $last_dirname = $a_dir;
306 $a_dir = dirname($a_dir);
307 }
308
309 // find the first existing dir
310 $reverse_paths = array_reverse($dirs, true);
311 $found_index = -1;
312 foreach ($reverse_paths as $key => $value) {
313 if ($found_index == -1) {
314 if (is_dir($value)) {
315 $found_index = $key;
316 }
317 }
318 }
319
320 $old_mask = umask(0000);
321 foreach ($dirs as $dirindex => $dir) {
322 // starting with the longest existing path
323 if ($dirindex >= $found_index) {
324 if (!file_exists($dir)) {
325 if (strcmp(substr($dir, strlen($dir) - 1, 1), "/") == 0) {
326 // on some systems there is an error when there is a slash
327 // at the end of a directory in mkdir, see Mantis #2554
328 $dir = substr($dir, 0, strlen($dir) - 1);
329 }
330 if (!mkdir($dir)) {
331 error_log("Can't make directory: $dir");
332 return false;
333 }
334 } elseif (!is_dir($dir)) {
335 error_log("$dir is not a directory");
336 return false;
337 } else {
338 // get umask of the last existing parent directory
339 $umask = fileperms($dir);
340 }
341 }
342 }
343 umask($old_mask);
344
345 return true;
346 }
347
358 public static function getDataDir(): string
359 {
360 return CLIENT_DATA_DIR;
361 }
362
371 public static function dirsize(string $directory): int
372 {
373 $size = 0;
374 if (!is_dir($directory)) {
375 // dirsize of non-existing directory
376 $size = @filesize($directory);
377 return ($size === false) ? -1 : $size;
378 }
379 if ($DIR = opendir($directory)) {
380 while (($dirfile = readdir($DIR)) !== false) {
381 if (is_link(
382 $directory . DIRECTORY_SEPARATOR . $dirfile
383 ) || $dirfile == '.' || $dirfile == '..') {
384 continue;
385 }
386 if (is_file($directory . DIRECTORY_SEPARATOR . $dirfile)) {
387 $size += filesize(
388 $directory . DIRECTORY_SEPARATOR . $dirfile
389 );
390 } elseif (is_dir($directory . DIRECTORY_SEPARATOR . $dirfile)) {
391 $dirSize = ilFileUtils::dirsize(
392 $directory . DIRECTORY_SEPARATOR . $dirfile
393 );
394 if ($dirSize >= 0) {
395 $size += $dirSize;
396 } else {
397 return -1;
398 }
399 }
400 }
401 closedir($DIR);
402 }
403 return $size;
404 }
405
424 public static function makeDir(string $a_dir): bool
425 {
426 $a_dir = trim($a_dir);
427
428 // remove trailing slash (bugfix for php 4.2.x)
429 if (substr($a_dir, -1) == "/") {
430 $a_dir = substr($a_dir, 0, -1);
431 }
432
433 // check if a_dir comes with a path
434 if (!($path = substr(
435 $a_dir,
436 0,
437 strrpos($a_dir, "/") - strlen($a_dir)
438 ))) {
439 $path = ".";
440 }
441
442 // create directory with file permissions of parent directory
443 if (is_dir($a_dir)) {
444 return true;
445 }
446 $old_mask = umask(0000);
447 $result = @mkdir($a_dir, fileperms($path));
448 umask($old_mask);
449
450 return $result;
451 }
452
453 protected static function sanitateTargetPath(string $a_target): array
454 {
455 switch (true) {
456 case strpos($a_target, ILIAS_WEB_DIR . '/' . CLIENT_ID) === 0:
457 case strpos(
458 $a_target,
459 './' . ILIAS_WEB_DIR . '/' . CLIENT_ID
460 ) === 0:
461 case strpos($a_target, CLIENT_WEB_DIR) === 0:
462 $targetFilesystem = \ILIAS\FileUpload\Location::WEB;
463 break;
464 case strpos($a_target, CLIENT_DATA_DIR . "/temp") === 0:
465 $targetFilesystem = \ILIAS\FileUpload\Location::TEMPORARY;
466 break;
467 case strpos($a_target, CLIENT_DATA_DIR) === 0:
468 $targetFilesystem = \ILIAS\FileUpload\Location::STORAGE;
469 break;
470 case strpos($a_target, ILIAS_ABSOLUTE_PATH . '/Customizing') === 0:
471 $targetFilesystem = \ILIAS\FileUpload\Location::CUSTOMIZING;
472 break;
473 default:
474 throw new InvalidArgumentException(
475 "Can not move files to \"$a_target\" because path can not be mapped to web, storage or customizing location."
476 );
477 }
478
479 $absTargetDir = dirname($a_target);
480 $targetDir = LegacyPathHelper::createRelativePath($absTargetDir);
481
482 return [$targetFilesystem, $targetDir];
483 }
484
504 public static function moveUploadedFile(
505 string $a_file,
506 string $a_name,
507 string $a_target,
508 bool $a_raise_errors = true,
509 string $a_mode = "move_uploaded"
510 ): bool {
511 global $DIC;
512 $main_tpl = $DIC->ui()->mainTemplate();
513 $target_filename = basename($a_target);
514
515 $target_filename = ilFileUtils::getValidFilename($target_filename);
516
517 // Make sure the target is in a valid subfolder. (e.g. no uploads to ilias/setup/....)
518 [$target_filesystem, $target_dir] = self::sanitateTargetPath($a_target);
519
520 $upload = $DIC->upload();
521
522 // If the upload has not yet been processed make sure he gets processed now.
523 if (!$upload->hasBeenProcessed()) {
524 $upload->process();
525 }
526
527 try {
528 if (!$upload->hasUploads()) {
529 throw new ilException(
530 $DIC->language()->txt("upload_error_file_not_found")
531 );
532 }
533 $upload_result = $upload->getResults()[$a_file] ?? null;
534 if ($upload_result instanceof UploadResult) {
535 if (!$upload_result->isOK()) {
536 throw new ilException($upload_result->getStatus()->getMessage());
537 }
538 } else {
539 return false;
540 }
541 } catch (ilException $e) {
542 if (!$a_raise_errors) {
543 $main_tpl->setOnScreenMessage('failure', $e->getMessage(), true);
544 } else {
545 throw $e;
546 }
547
548 return false;
549 }
550
551 $upload->moveOneFileTo(
552 $upload_result,
553 $target_dir,
554 $target_filesystem,
555 $target_filename,
556 true
557 );
558
559 return true;
560 }
561
568 public static function zip(
569 string $a_dir,
570 string $a_file,
571 bool $compress_content = false
572 ): bool {
573 $cdir = getcwd();
574
575 if ($compress_content) {
576 $a_dir .= "/*";
577 $pathinfo = pathinfo($a_dir);
578 chdir($pathinfo["dirname"]);
579 }
580
581 $pathinfo = pathinfo($a_file);
582 $dir = $pathinfo["dirname"];
583 $file = $pathinfo["basename"];
584
585 if (!$compress_content) {
586 chdir($dir);
587 }
588
589 $zip = PATH_TO_ZIP;
590
591 if (!$zip) {
592 chdir($cdir);
593 return false;
594 }
595
596 if (is_array($a_dir)) {
597 $source = "";
598 foreach ($a_dir as $dir) {
599 $name = basename($dir);
601 }
602 } else {
603 $name = basename($a_dir);
604 if (trim($name) != "*") {
606 } else {
607 $source = $name;
608 }
609 }
610
611 $zipcmd = "-r " . ilShellUtil::escapeShellArg($a_file) . " " . $source;
612 ilShellUtil::execQuoted($zip, $zipcmd);
613 chdir($cdir);
614 return true;
615 }
616
632 public static function delDir(string $a_dir, bool $a_clean_only = false): void
633 {
634 if (!is_dir($a_dir) || is_int(strpos($a_dir, ".."))) {
635 return;
636 }
637
638 $current_dir = opendir($a_dir);
639
640 $files = [];
641
642 // this extra loop has been necessary because of a strange bug
643 // at least on MacOS X. A looped readdir() didn't work
644 // correctly with larger directories
645 // when an unlink happened inside the loop. Getting all files
646 // into the memory first solved the problem.
647 while ($entryname = readdir($current_dir)) {
648 $files[] = $entryname;
649 }
650
651 foreach ($files as $file) {
652 if (is_dir(
653 $a_dir . "/" . $file
654 ) and ($file != "." and $file != "..")) {
655 ilFileUtils::delDir($a_dir . "/" . $file);
656 } elseif ($file != "." and $file != "..") {
657 unlink($a_dir . "/" . $file);
658 }
659 }
660
661 closedir($current_dir);
662 if (!$a_clean_only) {
663 @rmdir($a_dir);
664 }
665 }
666
667 public static function getSafeFilename(string $a_initial_filename): string
668 {
669 $file_peaces = explode('.', $a_initial_filename);
670
671 $file_extension = array_pop($file_peaces);
672
673 if (SUFFIX_REPL_ADDITIONAL) {
674 $string_extensions = SUFFIX_REPL_DEFAULT . "," . SUFFIX_REPL_ADDITIONAL;
675 } else {
676 $string_extensions = SUFFIX_REPL_DEFAULT;
677 }
678
679 $sufixes = explode(",", $string_extensions);
680
681 if (in_array($file_extension, $sufixes)) {
682 $file_extension = "sec";
683 }
684
685 $file_peaces[] = $file_extension;
686
687 $safe_filename = "";
688 foreach ($file_peaces as $piece) {
689 $safe_filename .= "$piece";
690 if ($piece != end($file_peaces)) {
691 $safe_filename .= ".";
692 }
693 }
694
695 return $safe_filename;
696 }
697
713 public static function getDir(
714 string $a_dir,
715 bool $a_rec = false,
716 ?string $a_sub_dir = ""
717 ): array {
718 $current_dir = opendir($a_dir . $a_sub_dir);
719
720 $dirs = [];
721 $files = [];
722 $subitems = [];
723 while ($entry = readdir($current_dir)) {
724 if (is_dir($a_dir . "/" . $entry)) {
725 $dirs[$entry] = ["type" => "dir",
726 "entry" => $entry,
727 "subdir" => $a_sub_dir
728 ];
729 if ($a_rec && $entry != "." && $entry != "..") {
731 $a_dir,
732 true,
733 $a_sub_dir . "/" . $entry
734 );
735 $subitems = array_merge($subitems, $si);
736 }
737 } else {
738 if ($entry != "." && $entry != "..") {
739 $size = filesize($a_dir . $a_sub_dir . "/" . $entry);
740 $files[$entry] = ["type" => "file",
741 "entry" => $entry,
742 "size" => $size,
743 "subdir" => $a_sub_dir
744 ];
745 }
746 }
747 }
748 ksort($dirs);
749 ksort($files);
750
751 return array_merge($dirs, $files, $subitems);
752 }
753
769 public static function getWebspaceDir(string $mode = "filesystem"): string
770 {
771 if ($mode === "filesystem") {
772 return "./" . ILIAS_WEB_DIR . "/" . CLIENT_ID;
773 } else {
774 if (defined("ILIAS_MODULE")) {
775 return "../" . ILIAS_WEB_DIR . "/" . CLIENT_ID;
776 } else {
777 return "./" . ILIAS_WEB_DIR . "/" . CLIENT_ID;
778 }
779 }
780 }
781
794 public static function createDirectory(string $a_dir, int $a_mod = 0755): void
795 {
796 ilFileUtils::makeDir($a_dir);
797 }
798
799 public static function getFileSizeInfo(): string
800 {
801 global $DIC;
802 $size = new DataSize(self::getUploadSizeLimitBytes(), DataSize::MB);
803 $max_filesize = $size->__toString();
804 $lng = $DIC->language();
805
806 return $lng->txt("file_notice") . " $max_filesize.";
807 }
808
812 public static function getASCIIFilename(string $a_filename): string
813 {
814 global $DIC;
815 $policy = new ilFileServicesPolicy($DIC->fileServiceSettings());
816 return $policy->ascii($a_filename);
817 }
818
826 public static function ilTempnam(?string $a_temp_path = null): string
827 {
828 if ($a_temp_path === null) {
829 $temp_path = ilFileUtils::getDataDir() . "/temp";
830 } else {
831 $temp_path = $a_temp_path;
832 }
833
834 if (!is_dir($temp_path)) {
836 }
837 $temp_name = $temp_path . "/" . uniqid("tmp");
838
839 return $temp_name;
840 }
841
842 public static function unzip(
843 string $path_to_zip_file,
844 bool $overwrite_existing = false,
845 bool $unpack_flat = false
846 ): void {
847 global $DIC;
848
849 $sanitizer = new ilFileServicesFilenameSanitizer(
850 $DIC->fileServiceSettings()
851 );
852
853 $log = $DIC->logger()->root();
854
855 if (!is_file($path_to_zip_file)) {
856 return;
857 }
858
859 // we unpack the zip always in a temp directory
860 $temporary_unzip_directory = self::ilTempnam();
861 self::makeDir($temporary_unzip_directory);
862 copy($path_to_zip_file, $temporary_unzip_directory . DIRECTORY_SEPARATOR . basename($path_to_zip_file));
863 $original_path_to_zip_file = $path_to_zip_file;
864 $path_to_zip_file = $temporary_unzip_directory . DIRECTORY_SEPARATOR . basename($path_to_zip_file);
865 $original_zip_path_info = pathinfo($original_path_to_zip_file);
866 $unzippable_zip_path_info = pathinfo($path_to_zip_file);
867
868 $unzippable_zip_directory = $unzippable_zip_path_info["dirname"];
869 $unzippable_zip_filename = $unzippable_zip_path_info["basename"];
870
871 // unzip
872 $current_directory = getcwd();
873 chdir($unzippable_zip_directory);
874 $unzip_command = PATH_TO_UNZIP;
875
876 // real unzip
877 if (!$overwrite_existing) {
878 $unzip_parameters = ilShellUtil::escapeShellArg($unzippable_zip_filename);
879 } else {
880 $unzip_parameters = "-o " . ilShellUtil::escapeShellArg($unzippable_zip_filename);
881 }
882 ilShellUtil::execQuoted($unzip_command, $unzip_parameters);
883 // move back
884 chdir($current_directory);
885
886 // remove all sym links
887 clearstatcache(); // prevent is_link from using cache
888 $dir_realpath = realpath($unzippable_zip_directory);
889 foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($unzippable_zip_directory)) as $name => $f) {
890 if (is_link($name)) {
891 $target = readlink($name);
892 if (substr($target, 0, strlen($dir_realpath)) != $dir_realpath) {
893 unlink($name);
894 $log->info("Removed symlink " . $name);
895 }
896 }
897 if (is_file($name) && $name !== $sanitizer->sanitize($name)) {
898 // rename file if it contains invalid suffix
900 rename($name, $new_name);
901 }
902 }
903
904 // rename executables
905 self::renameExecutables($unzippable_zip_directory);
906
907 // now we have to move the files to the original directory.
908 // if $a_flat is true, we move the files only without directories, otherwise we move the whole directory.
909 // since some provide a realtive path here, we have to get the absolute path first
910 $target_dir_name = $original_zip_path_info["dirname"];
911 $target_dir_name = realpath($target_dir_name);
912
913 if ($unpack_flat) {
914 $file_array = [];
915 self::recursive_dirscan($temporary_unzip_directory, $file_array);
916 if (is_array($file_array["file"])) {
917 foreach ($file_array["file"] as $k => $f) {
918 if (
919 substr($f, 0, 1) !== "."
920 && $f !== basename($original_path_to_zip_file)
921 ) {
922 copy(
923 $file_array["path"][$k] . $f,
924 $target_dir_name . DIRECTORY_SEPARATOR . $f
925 );
926 }
927 }
928 }
929 } else {
930 $target_directory = $target_dir_name;
931 self::rCopy(
932 $temporary_unzip_directory,
933 $target_directory
934 );
935 }
936
937 self::delDir($temporary_unzip_directory);
938 }
939
943 public static function renameExecutables(string $a_dir): void
944 {
945 $def_arr = explode(",", SUFFIX_REPL_DEFAULT);
946 foreach ($def_arr as $def) {
947 self::rRenameSuffix($a_dir, trim($def), "sec");
948 }
949
950 $def_arr = explode(",", SUFFIX_REPL_ADDITIONAL);
951 foreach ($def_arr as $def) {
952 self::rRenameSuffix($a_dir, trim($def), "sec");
953 }
954 }
955
962 public static function rRenameSuffix(string $a_dir, string $a_old_suffix, string $a_new_suffix): bool
963 {
964 if ($a_dir === "/"
965 || $a_dir === ""
966 || strpos($a_dir, "..") !== false
967 || trim($a_old_suffix) === "") {
968 return false;
969 }
970
971 // check if argument is directory
972 if (!@is_dir($a_dir)) {
973 return false;
974 }
975
976 // read a_dir
977 $dir = opendir($a_dir);
978 if ($dir === false) {
979 return false;
980 }
981
982 $prohibited = [
983 '...'
984 ];
985
986 while ($file = readdir($dir)) {
987 if (
988 $file !== "."
989 && $file !== ".."
990 ) {
991 // triple dot is not allowed in filenames
992 if (in_array($file, $prohibited)) {
993 unlink($a_dir . "/" . $file);
994 continue;
995 }
996
997 // directories
998 if (@is_dir($a_dir . "/" . $file)) {
999 self::rRenameSuffix($a_dir . "/" . $file, $a_old_suffix, $a_new_suffix);
1000 }
1001
1002 // files
1003 if (@is_file($a_dir . "/" . $file)) {
1004 // first check for files with trailing dot
1005 if (strrpos($file, '.') == (strlen($file) - 1)) {
1006 try {
1007 rename($a_dir . '/' . $file, substr($a_dir . '/' . $file, 0, -1));
1008 } catch (Throwable $t) {
1009 // to avoid exploits we do delete this file and continue renaming
1010 unlink($a_dir . '/' . $file);
1011 continue;
1012 }
1013
1014 $file = substr($file, 0, -1);
1015 }
1016
1017 $path_info = pathinfo($a_dir . "/" . $file);
1018
1019 if (strtolower($path_info["extension"] ?? '') === strtolower($a_old_suffix)) {
1020 $pos = strrpos($a_dir . "/" . $file, ".");
1021 $new_name = substr($a_dir . "/" . $file, 0, $pos) . "." . $a_new_suffix;
1022 // check if file exists
1023 if (file_exists($new_name)) {
1024 if (is_dir($new_name)) {
1025 self::delDir($new_name);
1026 } else {
1027 unlink($new_name);
1028 }
1029 }
1030 rename($a_dir . "/" . $file, $new_name);
1031 }
1032 }
1033 }
1034 }
1035 return true;
1036 }
1037
1038 public static function removeTrailingPathSeparators(string $path): string
1039 {
1040 $path = preg_replace("/[\/\\\]+$/", "", $path);
1041 return (string) $path;
1042 }
1043
1047 public static function getUploadSizeLimitBytes(): string
1048 {
1049 $convertPhpIniSizeValueToBytes = function ($phpIniSizeValue) {
1050 if (is_numeric($phpIniSizeValue)) {
1051 return $phpIniSizeValue;
1052 }
1053
1054 $suffix = substr($phpIniSizeValue, -1);
1055 $value = substr($phpIniSizeValue, 0, -1);
1056
1057 switch (strtoupper($suffix)) {
1058 case 'P':
1059 $value *= 1024;
1060 // no break
1061 case 'T':
1062 $value *= 1024;
1063 // no break
1064 case 'G':
1065 $value *= 1024;
1066 // no break
1067 case 'M':
1068 $value *= 1024;
1069 // no break
1070 case 'K':
1071 $value *= 1024;
1072 break;
1073 }
1074
1075 return $value;
1076 };
1077
1078
1079 $uploadSizeLimitBytes = min(
1080 $convertPhpIniSizeValueToBytes(ini_get('post_max_size')),
1081 $convertPhpIniSizeValueToBytes(ini_get('upload_max_filesize'))
1082 );
1083
1084 return $uploadSizeLimitBytes;
1085 }
1086
1087 public static function _sanitizeFilemame(string $a_filename): string
1088 {
1089 return strip_tags(ilUtil::stripSlashes($a_filename));
1090 }
1091}
This class provides the data size with additional information to remove the work to calculate the siz...
Definition: DataSize.php:31
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Class ilFileServicesFilenameSanitizer.
Class ilFileServicesPolicy.
Class ilFileUtils.
static utf8_encode(string $string)
utf8-encodes string if it is not a valid utf8-string.
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static unzip(string $path_to_zip_file, bool $overwrite_existing=false, bool $unpack_flat=false)
static getFileSizeInfo()
static getWebspaceDir(string $mode="filesystem")
get webspace directory
static getASCIIFilename(string $a_filename)
static getDir(string $a_dir, bool $a_rec=false, ?string $a_sub_dir="")
get directory
static recursive_dirscan(string $dir, array &$arr)
Recursively scans a given directory and writes path and filename into referenced array.
static zip(string $a_dir, string $a_file, bool $compress_content=false)
zips given directory/file into given zip.file
static makeDir(string $a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
static processZipFile(string $a_directory, string $a_file, bool $structure)
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static rename(string $a_source, string $a_target)
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static sanitateTargetPath(string $a_target)
static getUploadSizeLimitBytes()
static getDataDir()
get data directory (outside webspace)
static dirsize(string $directory)
get size of a directory or a file.
static renameExecutables(string $a_dir)
static getSafeFilename(string $a_initial_filename)
static createDirectory(string $a_dir, int $a_mod=0755)
create directory
static getValidFilename(string $a_filename)
static rRenameSuffix(string $a_dir, string $a_old_suffix, string $a_new_suffix)
Renames all files with certain suffix and gives them a new suffix.
static _sanitizeFilemame(string $a_filename)
static removeTrailingPathSeparators(string $path)
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
static rCopy(string $a_sdir, string $a_tdir, bool $preserveTimeAttributes=false)
Copies content of a directory $a_sdir recursively to a directory $a_tdir.
static escapeShellArg(string $a_arg)
static execQuoted(string $cmd, ?string $args=null)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static virusHandling(string $a_file, string $a_orig_name='', bool $a_clean=true)
const CLIENT_ID
Definition: constants.php:41
const ILIAS_WEB_DIR
Definition: constants.php:45
const CLIENT_WEB_DIR
Definition: constants.php:47
const CLIENT_DATA_DIR
Definition: constants.php:46
global $DIC
Definition: feed.php:28
const TEMPORARY
The ILIAS temporary directory.
Definition: Location.php:50
const CUSTOMIZING
The filesystem within the web root where all the skins and plugins are saved.
Definition: Location.php:45
const WEB
The filesystem within the ilias web root.
Definition: Location.php:35
const STORAGE
The filesystem outside of the ilias web root.
Definition: Location.php:40
$path
Definition: ltiservices.php:32
if($format !==null) $name
Definition: metadata.php:247
$source
Definition: metadata.php:93
Class FlySystemFileAccessTest \Provider\FlySystem @runTestsInSeparateProcesses @preserveGlobalState d...
string $key
Consumer key/client ID value.
Definition: System.php:193
Class ChatMainBarProvider \MainMenu\Provider.
$log
Definition: result.php:33
$lng