[ Index ]
 

Code source de Typo3 4.1.3

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/t3lib/ -> class.t3lib_basicfilefunc.php (source)

   1  <?php
   2  /***************************************************************
   3  *  Copyright notice
   4  *
   5  *  (c) 1999-2006 Kasper Skaarhoj (kasperYYYY@typo3.com)
   6  *  All rights reserved
   7  *
   8  *  This script is part of the TYPO3 project. The TYPO3 project is
   9  *  free software; you can redistribute it and/or modify
  10  *  it under the terms of the GNU General Public License as published by
  11  *  the Free Software Foundation; either version 2 of the License, or
  12  *  (at your option) any later version.
  13  *
  14  *  The GNU General Public License can be found at
  15  *  http://www.gnu.org/copyleft/gpl.html.
  16  *  A copy is found in the textfile GPL.txt and important notices to the license
  17  *  from the author is found in LICENSE.txt distributed with these scripts.
  18  *
  19  *
  20  *  This script is distributed in the hope that it will be useful,
  21  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23  *  GNU General Public License for more details.
  24  *
  25  *  This copyright notice MUST APPEAR in all copies of the script!
  26  ***************************************************************/
  27  /**
  28   * Contains class with basic file management functions
  29   *
  30   * $Id: class.t3lib_basicfilefunc.php 1979 2007-02-04 21:04:20Z mundaun $
  31   * Revised for TYPO3 3.6 July/2003 by Kasper Skaarhoj
  32   *
  33   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
  34   */
  35  /**
  36   * [CLASS/FUNCTION INDEX of SCRIPT]
  37   *
  38   *
  39   *
  40   *   81: class t3lib_basicFileFunctions
  41   *
  42   *              SECTION: Checking functions
  43   *  133:     function init($mounts, $f_ext)
  44   *  152:     function getTotalFileInfo($wholePath)
  45   *  172:     function is_allowed($iconkey,$type)
  46   *  197:     function checkIfFullAccess($theDest)
  47   *  211:     function is_webpath($path)
  48   *  231:     function checkIfAllowed($ext, $theDest, $filename='')
  49   *  241:     function checkFileNameLen($fileName)
  50   *  251:     function is_directory($theDir)
  51   *  268:     function isPathValid($theFile)
  52   *  283:     function getUniqueName($theFile, $theDest, $dontCheckForUnique=0)
  53   *  326:     function checkPathAgainstMounts($thePath)
  54   *  342:     function findFirstWebFolder()
  55   *  362:     function blindPath($thePath)
  56   *  378:     function findTempFolder()
  57   *
  58   *              SECTION: Cleaning functions
  59   *  412:     function cleanDirectoryName($theDir)
  60   *  422:     function rmDoubleSlash($string)
  61   *  432:     function slashPath($path)
  62   *  446:     function cleanFileName($fileName,$charset='')
  63   *  480:     function formatSize($sizeInBytes)
  64   *
  65   * TOTAL FUNCTIONS: 19
  66   * (This index is automatically created/updated by the extension "extdeveval")
  67   *
  68   */
  69  
  70  require_once(PATH_t3lib.'class.t3lib_cs.php');
  71  
  72  
  73  /**
  74   * 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
  75   *
  76   * @author    Kasper Skaarhoj <kasperYYYY@typo3.com>
  77   * @package TYPO3
  78   * @subpackage t3lib
  79   * @see t3lib_basicFileFunctions::init()
  80   */
  81  class t3lib_basicFileFunctions    {
  82      var $getUniqueNamePrefix = '';    // Prefix which will be prepended the file when using the getUniqueName-function
  83      var $maxNumber = 99;            // This number decides the highest allowed appended number used on a filename before we use naming with unique strings
  84      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.
  85      var $maxInputNameLen = 60;        // This is the maximum length of names treated by cleanFileName()
  86      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)
  87  
  88          // internal
  89      var $f_ext = Array();            // See comment in header
  90      var $mounts = Array();            // See comment in header
  91      var $webPath ='';                // Set to DOCUMENT_ROOT.
  92      var $isInit = 0;                // Set to true after init()/start();
  93  
  94  
  95  
  96      /**********************************
  97       *
  98       * Checking functions
  99       *
 100       **********************************/
 101  
 102      /**
 103       * Constructor
 104       * This function should be called to initialise the internal arrays $this->mounts and $this->f_ext
 105       *
 106       *  A typical example of the array $mounts is this:
 107       *         $mounts[xx][path] = (..a mounted path..)
 108       *     the 'xx'-keys is just numerical from zero. There are also a [name] and [type] value that just denotes the mountname and type. Not used for athentication here.
 109       *     $this->mounts is traversed in the function checkPathAgainstMounts($thePath), and it is checked that $thePath is actually below one of the mount-paths
 110       *     The mountpaths are with a trailing '/'. $thePath must be with a trailing '/' also!
 111       *     As you can see, $this->mounts is very critical! This is the array that decides where the user will be allowed to copy files!!
 112       *  Typically the global var $WEBMOUNTS would be passed along as $mounts
 113       *
 114       *     A typical example of the array $f_ext is this:
 115       *         $f_ext['webspace']['allow']='';
 116       *         $f_ext['webspace']['deny']='php3,php';
 117       *         $f_ext['ftpspace']['allow']='*';
 118       *         $f_ext['ftpspace']['deny']='';
 119       *     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.
 120       *     The control is done like this: If an extension matches 'allow' then the check returns true. If not and an extension matches 'deny' then the check return false. If no match at all, returns true.
 121       *     You list extensions comma-separated. If the value is a '*' every extension is allowed
 122       *     The list is case-insensitive when used in this class (see init())
 123       *  Typically TYPO3_CONF_VARS['BE']['fileExtensions'] would be passed along as $f_ext.
 124       *
 125       *  Example:
 126       *     $basicff->init($GLOBALS['FILEMOUNTS'],$TYPO3_CONF_VARS['BE']['fileExtensions']);
 127       *
 128       * @param    array        Contains the paths of the file mounts for the current BE user. Normally $GLOBALS['FILEMOUNTS'] is passed. This variable is set during backend user initialization; $FILEMOUNTS = $BE_USER->returnFilemounts(); (see typo3/init.php)
 129       * @param    array        Array with information about allowed and denied file extensions. Typically passed: $TYPO3_CONF_VARS['BE']['fileExtensions']
 130       * @return    void
 131       * @see typo3/init.php, t3lib_userAuthGroup::returnFilemounts()
 132       */
 133  	function init($mounts, $f_ext)    {
 134          $this->f_ext['webspace']['allow'] = t3lib_div::uniqueList(strtolower($f_ext['webspace']['allow']));
 135          $this->f_ext['webspace']['deny'] = t3lib_div::uniqueList(strtolower($f_ext['webspace']['deny']));
 136          $this->f_ext['ftpspace']['allow'] = t3lib_div::uniqueList(strtolower($f_ext['ftpspace']['allow']));
 137          $this->f_ext['ftpspace']['deny'] = t3lib_div::uniqueList(strtolower($f_ext['ftpspace']['deny']));
 138  
 139          $this->mounts = $mounts;
 140          $this->webPath = t3lib_div::getIndpEnv('TYPO3_DOCUMENT_ROOT');
 141          $this->isInit = 1;
 142  
 143          $this->maxInputNameLen = $GLOBALS['TYPO3_CONF_VARS']['SYS']['maxFileNameLength'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['maxFileNameLength'] : $this->maxInputNameLen;
 144      }
 145  
 146      /**
 147       * Returns an array with a whole lot of fileinformation.
 148       *
 149       * @param    string        Filepath to existing file. Should probably be absolute. Filefunctions are performed on this value.
 150       * @return    array        Information about the file in the filepath
 151       */
 152  	function getTotalFileInfo($wholePath)    {
 153          $theuser = getmyuid();
 154          $info = t3lib_div::split_fileref($wholePath);
 155          $info['tstamp'] = @filemtime($wholePath);
 156          $info['size'] = @filesize($wholePath);
 157          $info['type'] = @filetype($wholePath);
 158          $info['owner'] = @fileowner($wholePath);
 159          $info['perms'] = @fileperms($wholePath);
 160          $info['writable'] = !@is_writable($wholePath);
 161          $info['readable'] = !@is_readable($wholePath);
 162          return $info;
 163      }
 164  
 165      /**
 166       * Checks if a $iconkey (fileextension) is allowed according to $this->f_ext.
 167       *
 168       * @param    string        The extension to check, eg. "php" or "html" etc.
 169       * @param    string        Either "webspage" or "ftpspace" - points to a key in $this->f_ext
 170       * @return    boolean        True if file extension is allowed.
 171       */
 172  	function is_allowed($iconkey,$type)    {
 173          if (isset($this->f_ext[$type]))    {
 174              $ik = strtolower($iconkey);
 175              if ($ik)    {
 176                      // If the extension is found amongst the allowed types, we return true immediately
 177                  if ($this->f_ext[$type]['allow']=='*' || t3lib_div::inList($this->f_ext[$type]['allow'],$ik))    return true;
 178                      // If the extension is found amongst the denied types, we return false immediately
 179                  if ($this->f_ext[$type]['deny']=='*' || t3lib_div::inList($this->f_ext[$type]['deny'],$ik))    return false;
 180                      // If no match we return true
 181                  return true;
 182              } else {    // If no extension:
 183                  if ($this->f_ext[$type]['allow']=='*')    return true;
 184                  if ($this->f_ext[$type]['deny']=='*')    return false;
 185                  return true;
 186              }
 187          }
 188          return false;
 189      }
 190  
 191      /**
 192       * Returns true if you can operate of ANY file ('*') in the space $theDest is in ('webspace' / 'ftpspace')
 193       *
 194       * @param    string        Absolute path
 195       * @return    boolean
 196       */
 197  	function checkIfFullAccess($theDest)    {
 198          $type = $this->is_webpath($theDest)?'webspace':'ftpspace';
 199          if (isset($this->f_ext[$type]))    {
 200              if ((string)$this->f_ext[$type]['deny']=='' || $this->f_ext[$type]['allow']=='*')    return true;
 201          }
 202      }
 203  
 204      /**
 205       * Checks if $this->webPath (should be TYPO3_DOCUMENT_ROOT) is in the first part of $path
 206       * Returns true also if $this->init is not set or if $path is empty...
 207       *
 208       * @param    string        Absolute path to check
 209       * @return    boolean
 210       */
 211  	function is_webpath($path)    {
 212          if ($this->isInit)    {
 213              $testPath = $this->slashPath($path);
 214              $testPathWeb = $this->slashPath($this->webPath);
 215              if ($testPathWeb && $testPath)    {
 216                  return t3lib_div::isFirstPartOfStr($testPath,$testPathWeb);
 217              }
 218          }
 219          return true;    // Its more safe to return true (as the webpath is more restricted) if something went wrong...
 220      }
 221  
 222      /**
 223       * If the filename is given, check it against the TYPO3_CONF_VARS[BE][fileDenyPattern] +
 224       * Checks if the $ext fileextension is allowed in the path $theDest (this is based on whether $theDest is below the $this->webPath)
 225       *
 226       * @param    string        File extension, eg. "php" or "html"
 227       * @param    string        Absolute path for which to test
 228       * @param    string        Filename to check against TYPO3_CONF_VARS[BE][fileDenyPattern]
 229       * @return    boolean        True if extension/filename is allowed
 230       */
 231  	function checkIfAllowed($ext, $theDest, $filename='')    {
 232          return t3lib_div::verifyFilenameAgainstDenyPattern($filename) && $this->is_allowed($ext,($this->is_webpath($theDest)?'webspace':'ftpspace'));
 233      }
 234  
 235      /**
 236       * Returns true if the input filename string is shorter than $this->maxInputNameLen.
 237       *
 238       * @param    string        Filename, eg "somefile.html"
 239       * @return    boolean
 240       */
 241  	function checkFileNameLen($fileName)    {
 242          return strlen($fileName) <= $this->maxInputNameLen;
 243      }
 244  
 245      /**
 246       * Cleans $theDir for slashes in the end of the string and returns the new path, if it exists on the server.
 247       *
 248       * @param    string        Directory path to check
 249       * @return    string        Returns the cleaned up directory name if OK, otherwise false.
 250       */
 251  	function is_directory($theDir)    {
 252          if ($this->isPathValid($theDir))    {
 253              $theDir=$this->cleanDirectoryName($theDir);
 254              if (@is_dir($theDir))    {
 255                  return $theDir;
 256              }
 257          }
 258          return false;
 259      }
 260  
 261      /**
 262       * Wrapper for t3lib_div::validPathStr()
 263       *
 264       * @param    string        Filepath to evaluate
 265       * @return    boolean        True, if no '//', '..' or '\' is in the $theFile
 266       * @see    t3lib_div::validPathStr()
 267       */
 268  	function isPathValid($theFile)    {
 269          return t3lib_div::validPathStr($theFile);
 270      }
 271  
 272      /**
 273       * Returns the destination path/filename of a unique filename/foldername in that path.
 274       * If $theFile exists in $theDest (directory) the file have numbers appended up to $this->maxNumber. Hereafter a unique string will be appended.
 275       * This function is used by fx. TCEmain when files are attached to records and needs to be uniquely named in the uploads/* folders
 276       *
 277       * @param    string        The input filename to check
 278       * @param    string        The directory for which to return a unique filename for $theFile. $theDest MUST be a valid directory. Should be absolute.
 279       * @param    boolean        If set the filename is returned with the path prepended without checking whether it already existed!
 280       * @return    string        The destination absolute filepath (not just the name!) of a unique filename/foldername in that path.
 281       * @see t3lib_TCEmain::checkValue()
 282       */
 283  	function getUniqueName($theFile, $theDest, $dontCheckForUnique=0)    {
 284          $theDest = $this->is_directory($theDest);    // $theDest is cleaned up
 285          $origFileInfo = t3lib_div::split_fileref($theFile);        // Fetches info about path, name, extention of $theFile
 286          if ($theDest)    {
 287              if ($this->getUniqueNamePrefix)    {        // Adds prefix
 288                  $origFileInfo['file']     = $this->getUniqueNamePrefix.$origFileInfo['file'];
 289                  $origFileInfo['filebody'] = $this->getUniqueNamePrefix.$origFileInfo['filebody'];
 290              }
 291  
 292                  // Check if the file exists and if not - return the filename...
 293              $fileInfo = $origFileInfo;
 294              $theDestFile = $theDest.'/'.$fileInfo['file'];        // The destinations file
 295              if (!@file_exists($theDestFile) || $dontCheckForUnique)        {    // If the file does NOT exist we return this filename
 296                  return $theDestFile;
 297              }
 298  
 299                  // 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...
 300              $theTempFileBody = preg_replace('/_[0-9][0-9]$/','',$origFileInfo['filebody']);        // This removes _xx if appended to the file
 301              $theOrigExt = $origFileInfo['realFileext'] ? '.'.$origFileInfo['realFileext'] : '';
 302  
 303              for ($a=1; $a<=($this->maxNumber+1); $a++)    {
 304                  if ($a<=$this->maxNumber)    {    // First we try to append numbers
 305                      $insert = '_'.sprintf('%02d', $a);
 306                  } else {        // .. then we try unique-strings...
 307                      $insert = '_'.substr(md5(uniqId('')),0,$this->uniquePrecision);
 308                  }
 309                  $theTestFile = $theTempFileBody.$insert.$theOrigExt;
 310                  $theDestFile = $theDest.'/'.$theTestFile;        // The destinations file
 311                  if (!@file_exists($theDestFile))        {    // If the file does NOT exist we return this filename
 312                      return $theDestFile;
 313                  }
 314              }
 315          }
 316      }
 317  
 318      /**
 319       * Checks if $thePath is a path under one of the paths in $this->mounts
 320       * See comment in the header of this class.
 321       *
 322       * @param    string        $thePath MUST HAVE a trailing '/' in order to match correctly with the mounts
 323       * @return    string        The key to the first mount found, otherwise nothing is returned.
 324       * @see init()
 325       */
 326  	function checkPathAgainstMounts($thePath)    {
 327          if ($thePath && $this->isPathValid($thePath) && is_array($this->mounts))    {
 328              reset ($this->mounts);
 329              while(list($k,$val)=each($this->mounts))    {
 330                  if (t3lib_div::isFirstPartOfStr($thePath,$val['path']))    {
 331                      return $k;
 332                  }
 333              }
 334          }
 335      }
 336  
 337      /**
 338       * Find first web folder (relative to PATH_site.'fileadmin') in filemounts array
 339       *
 340       * @return    string        The key to the first mount inside PATH_site."fileadmin" found, otherwise nothing is returned.
 341       */
 342  	function findFirstWebFolder()    {
 343          global $TYPO3_CONF_VARS;
 344  
 345          if (is_array($this->mounts))    {
 346              reset ($this->mounts);
 347              while(list($k,$val)=each($this->mounts))    {
 348                  if (t3lib_div::isFirstPartOfStr($val['path'], PATH_site.$TYPO3_CONF_VARS['BE']['fileadminDir']))    {
 349                      return $k;
 350                  }
 351              }
 352          }
 353      }
 354  
 355      /**
 356       * Removes filemount part of a path, thus blinding the position.
 357       * Takes a path, $thePath, and removes the part of the path which equals the filemount.
 358       *
 359       * @param    string        $thePath is a path which MUST be found within one of the internally set filemounts, $this->mounts
 360       * @return    string        The processed input path
 361       */
 362  	function blindPath($thePath)    {
 363          $k=$this->checkPathAgainstMounts($thePath);
 364          if ($k)    {
 365              $name='';
 366              $name.='['.$this->mounts[$k]['name'].']: ';
 367              $name.=substr($thePath,strlen($this->mounts[$k]['path']));
 368              return $name;
 369          }
 370      }
 371  
 372      /**
 373       * Find temporary folder
 374       * Finds the first $this->tempFN ('_temp_' usually) -folder in the internal array of filemounts, $this->mounts
 375       *
 376       * @return    string        Returns the path if found, otherwise nothing if error.
 377       */
 378  	function findTempFolder()    {
 379          if ($this->tempFN && is_array($this->mounts))    {
 380              reset ($this->mounts);
 381              while(list($k,$val)=each($this->mounts))    {
 382                  $tDir = $val['path'].$this->tempFN;
 383                  if (@is_dir($tDir))    {
 384                      return $tDir;
 385                  }
 386              }
 387          }
 388      }
 389  
 390  
 391  
 392  
 393  
 394  
 395  
 396  
 397  
 398  
 399  
 400      /*********************
 401       *
 402       * Cleaning functions
 403       *
 404       *********************/
 405  
 406      /**
 407       * Removes all dots, slashes and spaces after a path...
 408       *
 409       * @param    string        Input string
 410       * @return    string        Output string
 411       */
 412  	function cleanDirectoryName($theDir)    {
 413          return preg_replace('/[\/\. ]*$/','',$this->rmDoubleSlash($theDir));
 414      }
 415  
 416      /**
 417       * Converts any double slashes (//) to a single slash (/)
 418       *
 419       * @param    string        Input value
 420       * @return    string        Returns the converted string
 421       */
 422  	function rmDoubleSlash($string)    {
 423          return str_replace('//','/',$string);
 424      }
 425  
 426      /**
 427       * Returns a string which has a slash '/' appended if it doesn't already have that slash
 428       *
 429       * @param    string        Input string
 430       * @return    string        Output string with a slash in the end (if not already there)
 431       */
 432  	function slashPath($path)    {
 433          if (substr($path,-1)!='/')    {
 434              return $path.'/';
 435          }
 436          return $path;
 437      }
 438  
 439      /**
 440       * Returns a string where any character not matching [.a-zA-Z0-9_-] is substituted by '_'
 441       *
 442       * @param    string        Input string, typically the body of a filename
 443       * @param    string        Charset of the a filename (defaults to current charset; depending on context)
 444       * @return    string        Output string with any characters not matching [.a-zA-Z0-9_-] is substituted by '_'
 445       */
 446  	function cleanFileName($fileName,$charset='')    {
 447              // handle UTF-8 characters
 448          if ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'] == 'utf-8' && $GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem'])    {
 449                  // allow ".", "-", 0-9, a-z, A-Z and everything beyond U+C0 (latin capital letter a with grave)
 450              return preg_replace('/[\x00-\x2C\/\x3A-\x3F\x5B-\x60\x7B-\xBF]/u','_',trim($fileName));
 451          }
 452  
 453          if (!is_object($this->csConvObj))    {
 454              if (TYPO3_MODE=='FE')    {
 455                  $this->csConvObj = &$GLOBALS['TSFE']->csConvObj;
 456              } elseif (is_object($GLOBALS['LANG']))    {    // BE assumed:
 457                  $this->csConvObj = &$GLOBALS['LANG']->csConvObj;
 458              } else {    // The object may not exist yet, so we need to create it now. Happens in the Install Tool for example.
 459                  $this->csConvObj = &t3lib_div::makeInstance('t3lib_cs');
 460              }
 461          }
 462  
 463          if (!$charset)    {
 464              if (TYPO3_MODE=='FE')    {
 465                  $charset = $GLOBALS['TSFE']->renderCharset;
 466              } elseif (is_object($GLOBALS['LANG']))    {    // BE assumed:
 467                  $charset = $GLOBALS['LANG']->charSet;
 468              } else {    // best guess
 469                  $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset'];
 470              }
 471          }
 472  
 473          if ($charset)    {
 474              $fileName = $this->csConvObj->specCharsToASCII($charset,$fileName);
 475          }
 476  
 477          return preg_replace('/[^.[:alnum:]_-]/','_',trim($fileName));
 478      }
 479  
 480      /**
 481       * Formats an integer, $sizeInBytes, to Mb or Kb or just bytes
 482       *
 483       * @param    integer        Bytes to be formated
 484       * @return    string        Formatted with M,K or &nbsp;&nbsp; appended.
 485       */
 486  	function formatSize($sizeInBytes)    {
 487          if ($sizeInBytes>900)    {
 488              if ($sizeInBytes>900000)    {    // MB
 489                  $val = $sizeInBytes/(1024*1024);
 490                  return number_format($val, (($val<20)?1:0), '.', '').' M';
 491              } else {    // KB
 492                  $val = $sizeInBytes/(1024);
 493                  return number_format($val, (($val<20)?1:0), '.', '').' K';
 494              }
 495          } else {    // Bytes
 496              return $sizeInBytes.'&nbsp;&nbsp;';
 497          }
 498      }
 499  }
 500  
 501  
 502  
 503  if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_basicfilefunc.php'])    {
 504      include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_basicfilefunc.php']);
 505  }
 506  ?>


Généré le : Sun Nov 25 17:13:16 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics