Fixed issue #13670: Performance optimization: change while(list() to foreach() (thank...
[Packages/TYPO3.CMS.git] / t3lib / class.t3lib_basicfilefunc.php
index 17f3a4c..f9e42c8 100644 (file)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2004 Kasper Skaarhoj (kasperYYYY@typo3.com)
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  *
  *
  *
- *   80: class t3lib_basicFileFunctions
+ *   81: class t3lib_basicFileFunctions
  *
  *              SECTION: Checking functions
- *  132:     function init($mounts, $f_ext)
- *  149:     function getTotalFileInfo($wholePath)
- *  169:     function is_allowed($iconkey,$type)
- *  194:     function checkIfFullAccess($theDest)
- *  208:     function is_webpath($path)
- *  228:     function checkIfAllowed($ext, $theDest, $filename='')
- *  238:     function checkFileNameLen($fileName)
- *  248:     function is_directory($theDir)
- *  265:     function isPathValid($theFile)
- *  280:     function getUniqueName($theFile, $theDest, $dontCheckForUnique=0)
- *  323:     function checkPathAgainstMounts($thePath)
- *  341:     function blindPath($thePath)
- *  357:     function findTempFolder()
+ *  133:     function init($mounts, $f_ext)
+ *  152:     function getTotalFileInfo($wholePath)
+ *  172:     function is_allowed($iconkey,$type)
+ *  197:     function checkIfFullAccess($theDest)
+ *  211:     function is_webpath($path)
+ *  231:     function checkIfAllowed($ext, $theDest, $filename='')
+ *  241:     function checkFileNameLen($fileName)
+ *  251:     function is_directory($theDir)
+ *  268:     function isPathValid($theFile)
+ *  283:     function getUniqueName($theFile, $theDest, $dontCheckForUnique=0)
+ *  326:     function checkPathAgainstMounts($thePath)
+ *  342:     function findFirstWebFolder()
+ *  362:     function blindPath($thePath)
+ *  378:     function findTempFolder()
  *
  *              SECTION: Cleaning functions
- *  386:     function cleanDirectoryName($theDir)
- *  396:     function rmDoubleSlash($string)
- *  406:     function slashPath($path)
- *  419:     function cleanFileName($fileName)
- *  430:     function formatSize($sizeInBytes)
+ *  412:     function cleanDirectoryName($theDir)
+ *  422:     function rmDoubleSlash($string)
+ *  432:     function slashPath($path)
+ *  446:     function cleanFileName($fileName,$charset='')
+ *  480:     function formatSize($sizeInBytes)
  *
- * TOTAL FUNCTIONS: 18
+ * TOTAL FUNCTIONS: 19
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
 
 
 
-
 /**
  * Contains functions for management, validation etc of files in TYPO3, using the concepts of web- and ftp-space. Please see the comment for the init() function
  *
@@ -79,9 +79,9 @@
  */
 class t3lib_basicFileFunctions {
        var $getUniqueNamePrefix = '';  // Prefix which will be prepended the file when using the getUniqueName-function
-       var $maxNumber = 20;                    // This number decides the highest allowed appended number used on a filename before we use naming with unique strings
+       var $maxNumber = 99;                    // This number decides the highest allowed appended number used on a filename before we use naming with unique strings
        var $uniquePrecision = 6;               // This number decides how many characters out of a unique MD5-hash that is appended to a filename if getUniqueName is asked to find an available filename.
-       var $maxInputNameLen = 30;              // This is the maximum length of names treated by cleanFileName()
+       var $maxInputNameLen = 60;              // This is the maximum length of names treated by cleanFileName()
        var $tempFN = '_temp_';                 // Temp-foldername. A folder in the root of one of the mounts with this name is regarded a TEMP-folder (used for upload from clipboard)
 
                // internal
@@ -112,7 +112,7 @@ class t3lib_basicFileFunctions      {
         *
         *      A typical example of the array $f_ext is this:
         *              $f_ext['webspace']['allow']='';
-        *              $f_ext['webspace']['deny']='php3,php';
+        *              $f_ext['webspace']['deny']= PHP_EXTENSIONS_DEFAULT;
         *              $f_ext['ftpspace']['allow']='*';
         *              $f_ext['ftpspace']['deny']='';
         *      The control of fileextensions goes in two catagories. Webspace and Ftpspace. Webspace is folders accessible from a webbrowser (below TYPO3_DOCUMENT_ROOT) and ftpspace is everything else.
@@ -138,6 +138,8 @@ class t3lib_basicFileFunctions      {
                $this->mounts = $mounts;
                $this->webPath = t3lib_div::getIndpEnv('TYPO3_DOCUMENT_ROOT');
                $this->isInit = 1;
+
+               $this->maxInputNameLen = $GLOBALS['TYPO3_CONF_VARS']['SYS']['maxFileNameLength'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['maxFileNameLength'] : $this->maxInputNameLen;
        }
 
        /**
@@ -149,7 +151,7 @@ class t3lib_basicFileFunctions      {
        function getTotalFileInfo($wholePath)   {
                $theuser = getmyuid();
                $info = t3lib_div::split_fileref($wholePath);
-               $info['tstamp'] = @filectime($wholePath);
+               $info['tstamp'] = @filemtime($wholePath);
                $info['size'] = @filesize($wholePath);
                $info['type'] = @filetype($wholePath);
                $info['owner'] = @fileowner($wholePath);
@@ -289,12 +291,12 @@ class t3lib_basicFileFunctions    {
                                // Check if the file exists and if not - return the filename...
                        $fileInfo = $origFileInfo;
                        $theDestFile = $theDest.'/'.$fileInfo['file'];          // The destinations file
-                       if (!@file_exists($theDestFile) || $dontCheckForUnique)         {       // If the file does NOT exist we return this filename
+                       if (!file_exists($theDestFile) || $dontCheckForUnique)          {       // If the file does NOT exist we return this filename
                                return $theDestFile;
                        }
 
                                // 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...
-                       $theTempFileBody = ereg_replace('_[0-9][0-9]$','',$origFileInfo['filebody']);           // This removes _xx if appended to the file
+                       $theTempFileBody = preg_replace('/_[0-9][0-9]$/','',$origFileInfo['filebody']);         // This removes _xx if appended to the file
                        $theOrigExt = $origFileInfo['realFileext'] ? '.'.$origFileInfo['realFileext'] : '';
 
                        for ($a=1; $a<=($this->maxNumber+1); $a++)      {
@@ -305,7 +307,7 @@ class t3lib_basicFileFunctions      {
                                }
                                $theTestFile = $theTempFileBody.$insert.$theOrigExt;
                                $theDestFile = $theDest.'/'.$theTestFile;               // The destinations file
-                               if (!@file_exists($theDestFile))                {       // If the file does NOT exist we return this filename
+                               if (!file_exists($theDestFile))         {       // If the file does NOT exist we return this filename
                                        return $theDestFile;
                                }
                        }
@@ -322,8 +324,7 @@ class t3lib_basicFileFunctions      {
         */
        function checkPathAgainstMounts($thePath)       {
                if ($thePath && $this->isPathValid($thePath) && is_array($this->mounts))        {
-                       reset ($this->mounts);
-                       while(list($k,$val)=each($this->mounts))        {
+                       foreach ($this->mounts as $k => $val) {
                                if (t3lib_div::isFirstPartOfStr($thePath,$val['path'])) {
                                        return $k;
                                }
@@ -340,8 +341,7 @@ class t3lib_basicFileFunctions      {
                global $TYPO3_CONF_VARS;
 
                if (is_array($this->mounts))    {
-                       reset ($this->mounts);
-                       while(list($k,$val)=each($this->mounts))        {
+                       foreach ($this->mounts as $k => $val) {
                                if (t3lib_div::isFirstPartOfStr($val['path'], PATH_site.$TYPO3_CONF_VARS['BE']['fileadminDir']))        {
                                        return $k;
                                }
@@ -374,8 +374,7 @@ class t3lib_basicFileFunctions      {
         */
        function findTempFolder()       {
                if ($this->tempFN && is_array($this->mounts))   {
-                       reset ($this->mounts);
-                       while(list($k,$val)=each($this->mounts))        {
+                       foreach ($this->mounts as $k => $val) {
                                $tDir = $val['path'].$this->tempFN;
                                if (@is_dir($tDir))     {
                                        return $tDir;
@@ -407,7 +406,7 @@ class t3lib_basicFileFunctions      {
         * @return      string          Output string
         */
        function cleanDirectoryName($theDir)    {
-               return ereg_replace('[\/\. ]*$','',$this->rmDoubleSlash($theDir));
+               return preg_replace('/[\/\. ]*$/','',$this->rmDoubleSlash($theDir));
        }
 
        /**
@@ -435,13 +434,52 @@ class t3lib_basicFileFunctions    {
 
        /**
         * Returns a string where any character not matching [.a-zA-Z0-9_-] is substituted by '_'
+        * Trailing dots are removed
         *
         * @param       string          Input string, typically the body of a filename
-        * @return      string          Output string with any characters not matching [.a-zA-Z0-9_-] is substituted by '_'
+        * @param       string          Charset of the a filename (defaults to current charset; depending on context)
+        * @return      string          Output string with any characters not matching [.a-zA-Z0-9_-] is substituted by '_' and trailing dots removed
         */
-       function cleanFileName($fileName)       {
-               $theNewName = ereg_replace('[^.[:alnum:]_-]','_',trim($fileName));
-               return $theNewName;
+       function cleanFileName($fileName, $charset = '') {
+                       // Handle UTF-8 characters
+               if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] == 'utf-8' && $GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
+                               // allow ".", "-", 0-9, a-z, A-Z and everything beyond U+C0 (latin capital letter a with grave)
+                       $cleanFileName = preg_replace('/[\x00-\x2C\/\x3A-\x3F\x5B-\x60\x7B-\xBF]/u', '_', trim($fileName));
+
+                       // Handle other character sets
+               } else {
+                               // Get conversion object or initialize if needed
+                       if (!is_object($this->csConvObj)) {
+                               if (TYPO3_MODE=='FE') {
+                                       $this->csConvObj = $GLOBALS['TSFE']->csConvObj;
+                               } elseif (is_object($GLOBALS['LANG'])) {        // BE assumed:
+                                       $this->csConvObj = $GLOBALS['LANG']->csConvObj;
+                               } else {        // The object may not exist yet, so we need to create it now. Happens in the Install Tool for example.
+                                       $this->csConvObj = t3lib_div::makeInstance('t3lib_cs');
+                               }
+                       }
+
+                               // Define character set
+                       if (!$charset)  {
+                               if (TYPO3_MODE == 'FE') {
+                                       $charset = $GLOBALS['TSFE']->renderCharset;
+                               } elseif (is_object($GLOBALS['LANG'])) {        // BE assumed:
+                                       $charset = $GLOBALS['LANG']->charSet;
+                               } else {        // best guess
+                                       $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
+                               }
+                       }
+
+                               // If a charset was found, convert filename
+                       if ($charset) {
+                               $fileName = $this->csConvObj->specCharsToASCII($charset, $fileName);
+                       }
+
+                               // Replace unwanted characters by underscores
+                       $cleanFileName = preg_replace('/[^.[:alnum:]_-]/', '_', trim($fileName));
+               }
+                       // Strip trailing dots and return
+               return preg_replace('/\.*$/', '', $cleanFileName);
        }
 
        /**
@@ -449,8 +487,11 @@ class t3lib_basicFileFunctions     {
         *
         * @param       integer         Bytes to be formated
         * @return      string          Formatted with M,K or &nbsp;&nbsp; appended.
+        * @deprecated since at least TYPO3 4.2 - Use t3lib_div::formatSize() instead
         */
        function formatSize($sizeInBytes)       {
+               t3lib_div::logDeprecatedFunction();
+
                if ($sizeInBytes>900)   {
                        if ($sizeInBytes>900000)        {       // MB
                                $val = $sizeInBytes/(1024*1024);
@@ -470,4 +511,5 @@ class t3lib_basicFileFunctions      {
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_basicfilefunc.php'])    {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_basicfilefunc.php']);
 }
+
 ?>
\ No newline at end of file