‪TYPO3CMS  ‪main
BasicFileUtility.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
24 
37 {
41  public const ‪UNSAFE_FILENAME_CHARACTER_EXPRESSION = '\\x00-\\x2C\\/\\x3A-\\x3F\\x5B-\\x60\\x7B-\\xBF';
42 
48  public ‪$maxNumber = 99;
49 
55  public ‪$uniquePrecision = 6;
56 
64  protected function ‪sanitizeFolderPath($theDir)
65  {
66  if (!GeneralUtility::validPathStr($theDir)) {
67  return false;
68  }
69  $theDir = ‪PathUtility::getCanonicalPath($theDir);
70  if (@is_dir($theDir)) {
71  return $theDir;
72  }
73  return false;
74  }
75 
88  public function ‪getUniqueName($theFile, $theDest, $dontCheckForUnique = false)
89  {
90  // $theDest is cleaned up
91  $theDest = $this->‪sanitizeFolderPath($theDest);
92  if ($theDest) {
93  // Fetches info about path, name, extension of $theFile
94  $origFileInfo = GeneralUtility::split_fileref($theFile);
95  // Check if the file exists and if not - return the filename...
96  $fileInfo = $origFileInfo;
97  $theDestFile = $theDest . '/' . $fileInfo['file'];
98  // The destinations file
99  if (!file_exists($theDestFile) || $dontCheckForUnique) {
100  // If the file does NOT exist we return this filename
101  return $theDestFile;
102  }
103  // Well the filename in its pure form existed. Now we try to append numbers / unique-strings and see if we can find an available filename...
104  $theTempFileBody = preg_replace('/_[0-9][0-9]$/', '', $origFileInfo['filebody']);
105  // This removes _xx if appended to the file
106  $theOrigExt = $origFileInfo['realFileext'] ? '.' . $origFileInfo['realFileext'] : '';
107  for ($a = 1; $a <= $this->maxNumber + 1; $a++) {
108  if ($a <= $this->maxNumber) {
109  // First we try to append numbers
110  $insert = '_' . sprintf('%02d', $a);
111  } else {
112  // .. then we try unique-strings...
113  $insert = '_' . substr(md5(‪StringUtility::getUniqueId()), 0, $this->uniquePrecision);
114  }
115  $theTestFile = $theTempFileBody . $insert . $theOrigExt;
116  $theDestFile = $theDest . '/' . $theTestFile;
117  // The destinations file
118  if (!file_exists($theDestFile)) {
119  // If the file does NOT exist we return this filename
120  return $theDestFile;
121  }
122  }
123  }
124 
125  return null;
126  }
127 
136  public function ‪cleanFileName($fileName)
137  {
138  // Handle UTF-8 characters
139  if (‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
140  // allow ".", "-", 0-9, a-z, A-Z and everything beyond U+C0 (latin capital letter a with grave)
141  $cleanFileName = preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . ']/u', '_', trim($fileName)) ?? '';
142  } else {
143  $fileName = GeneralUtility::makeInstance(CharsetConverter::class)->utf8_char_mapping($fileName);
144  // Replace unwanted characters by underscores
145  $cleanFileName = preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . '\\xC0-\\xFF]/', '_', trim($fileName)) ?? '';
146  }
147  // Strip trailing dots and return
148  return rtrim($cleanFileName, '.');
149  }
150 }
‪TYPO3\CMS\Core\Utility\PathUtility\getCanonicalPath
‪static string getCanonicalPath(string $path)
Definition: PathUtility.php:365
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility
Definition: BasicFileUtility.php:37
‪TYPO3\CMS\Core\Charset\CharsetConverter
Definition: CharsetConverter.php:54
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\cleanFileName
‪string cleanFileName($fileName)
Definition: BasicFileUtility.php:134
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\UNSAFE_FILENAME_CHARACTER_EXPRESSION
‪const UNSAFE_FILENAME_CHARACTER_EXPRESSION
Definition: BasicFileUtility.php:41
‪TYPO3\CMS\Core\Utility\File
Definition: BasicFileUtility.php:18
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\getUniqueName
‪string null getUniqueName($theFile, $theDest, $dontCheckForUnique=false)
Definition: BasicFileUtility.php:86
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\$maxNumber
‪int $maxNumber
Definition: BasicFileUtility.php:47
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\sanitizeFolderPath
‪bool string sanitizeFolderPath($theDir)
Definition: BasicFileUtility.php:62
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Utility\File\BasicFileUtility\$uniquePrecision
‪int $uniquePrecision
Definition: BasicFileUtility.php:53
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static getUniqueId(string $prefix='')
Definition: StringUtility.php:57