home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 June / ENTER.ISO / files / xampp-win32-1.4.5-installer.exe / xampp / Upload.php < prev    next >
Encoding:
PHP Script  |  2004-03-24  |  22.7 KB  |  679 lines

  1. <?php
  2. // **********************************************
  3. //
  4. // This software is licensed by the LGPL
  5. // -> http://www.gnu.org/copyleft/lesser.txt
  6. // (c) 2001 by Tomas Von Veschler Cox
  7. //
  8. // **********************************************
  9. //
  10. // $Id: Upload.php,v 1.23 2002/05/28 15:33:36 cox Exp $
  11.  
  12. /*
  13. * Pear File Uploader class. Easy and secure managment of files
  14. * submitted via HTML Forms.
  15. *
  16. * @see http://vulcanonet.com/soft/index.php?pack=uploader
  17. * @author Tomas V.V.Cox <cox@vulcanonet.com>
  18. *
  19. * Leyend:
  20. * - you can add error msgs in your language in the HTTP_Upload_Error class
  21. *
  22. * TODO:
  23. * - addapt the class to new upload features of the 4.2 (?) release
  24. *   (the new error entry in HTTP_POST_FILES)
  25. * - try to think a way of having all the Error system in other
  26. *   file and only include it when an error ocurrs
  27. *
  28. * -- Note for users of PHP > 4.1 --
  29. *
  30. * Due the fact that PHP now doesn't register the HTTP_POST_FILES if no
  31. * uploads are done, the class is not able to give verbose information
  32. * about what happens. To check that you have to use the new isMissing()
  33. * method avaible from the $upload object too. For ex:
  34. *
  35. * $upload = new HTTP_Upload('en');
  36. * $missing = $upload->isMissing();
  37. * if (!$missing) {
  38. *    <code for manage files>
  39. * } else {
  40. *    die ($missing->getMessage());
  41. * }
  42. *
  43. * -- Notes --
  44. */
  45.  
  46. require_once 'PEAR.php';
  47.  
  48. /**
  49. * Error Class for HTTP_Upload
  50. *
  51. * @author Tomas V.V.Cox <cox@vulcanonet.com>
  52. * @package HTTP
  53. * @access public
  54. */
  55. class HTTP_Upload_Error extends PEAR
  56. {
  57.     /**
  58.     * Selected language for error messages
  59.     * @var string
  60.     */
  61.     var $lang = 'en';
  62.  
  63.     /**
  64.     * Constructor
  65.     *
  66.     * Creates a new PEAR_Error
  67.     *
  68.     * @param string $lang The language selected for error code messages
  69.     * @access public
  70.     */
  71.     function HTTP_Upload_Error($lang = null)
  72.     {
  73.         $this->lang = ($lang !== null) ? $lang : $this->lang;
  74.         global $HTTP_POST_VARS;
  75.         $maxsize = (isset($HTTP_POST_VARS['MAX_FILE_SIZE'])) ? $HTTP_POST_VARS['MAX_FILE_SIZE'] : null;
  76.         $ini_size = ini_get('upload_max_filesize');
  77.         if (empty($maxsize) || ($maxsize > $ini_size)) {
  78.             $maxsize = $ini_size;
  79.         }
  80.         // XXXXX Add here error messages in your language
  81.         $this->error_codes = array(
  82.             'TOO_LARGE' => array(
  83.                 'es' => "Fichero demasiado largo. El maximo permitido es: $maxsize bytes",
  84.                 'en' => "File size too large. The maximum permitted size is: $maxsize bytes",
  85.                 'de' => "Datei zu groß. Die zulässige Maximalgröße ist: $maxsize bytes",
  86.                 'nl' => "Het bestand is te groot, de maximale grootte is: $maxsize bytes",
  87.                 'fr' => "Le fichier est trop gros. La taille maximum autorisée est: $maxsize bytes",
  88.                 'it' => "Il file é troppo grande. Il massimo permesso é: $maxsize bytes"
  89.                 ),
  90.             'MISSING_DIR' => array(
  91.                 'es' => 'Falta directorio destino',
  92.                 'en' => 'Missing destination directory',
  93.                 'de' => 'Kein Zielverzeichnis definiert',
  94.                 'nl' => 'Geen bestemmings directory.',
  95.                 'fr' => 'Le répertoire de destination n\'est pas défini',
  96.                 'it' => 'Manca la directory di destinazione'
  97.                 ),
  98.             'IS_NOT_DIR' => array(
  99.                 'es' => 'El directorio destino no existe o es un fichero regular',
  100.                 'en' => 'The destination directory doesn\'t exist or is a regular file',
  101.                 'de' => 'Das angebene Zielverzeichnis existiert nicht oder ist eine Datei',
  102.                 'nl' => 'De doeldirectory bestaat niet, of is een gewoon bestand',
  103.                 'fr' => 'Le répertoire de destination n\'existe pas ou il s\'agit d\'un fichier régulier',
  104.                 'it' => 'La directory di destinazione non esiste o é un file'
  105.                 ),
  106.             'NO_WRITE_PERMS' => array(
  107.                 'es' => 'El directorio destino no tiene permisos de escritura',
  108.                 'en' => 'The destination directory doesn\'t have write perms',
  109.                 'de' => 'Fehlende Schreibrechte für das Zielverzeichnis',
  110.                 'nl' => 'Geen toestemming om te schrijven in de doeldirectory.',
  111.                 'fr' => 'Le répertoire de destination n\'a pas les droits en écriture.',
  112.                 'it' => 'Non si hanno i permessi di scrittura sulla directory di destinazione'
  113.                 ),
  114.             'NO_USER_FILE' => array(
  115.                 'es' => 'No se ha escogido fichero para el upload',
  116.                 'en' => 'You haven\'t selected any file for uploading',
  117.                 'de' => 'Es wurde keine Datei fⁿr den Upload ausgewählt',
  118.                 'nl' => 'Er is geen bestand opgegeven om te uploaden.',
  119.                 'fr' => 'Vous n\'avez pas sélectionné de fichier à envoyer.',
  120.                 'it' => 'Nessun file selezionato per l\'upload'
  121.                 ),
  122.             'BAD_FORM' => array(
  123.                 'es' => 'El formulario no contiene METHOD="post" ENCTYPE="multipart/form-data" requerido',
  124.                 'en' => 'The html form doesn\'t contain the required METHOD="post" ENCTYPE="multipart/form-data"',
  125.                 'de' => 'Das HTML-Formular enthält nicht die Angabe METHOD="post" ENCTYPE="multipart/form-data" '.
  126.                         'im >form<-Tag',
  127.                 'nl' => 'Het HTML-formulier bevat niet de volgende benodigde '.
  128.                         'eigenschappen: method="post" enctype="multipart/form-data"',
  129.                 'fr' => 'Le formulaire HTML ne contient pas les attributs requis : '.
  130.                         ' method="post" enctype="multipart/form-data"',
  131.                 'it' => 'Il modulo HTML non contiene gli attributi richiesti: "'.
  132.                         ' method="post" enctype="multipart/form-data"'
  133.                 ),
  134.             'E_FAIL_COPY' => array(
  135.                 'es' => 'Fallo al copiar el fichero temporal',
  136.                 'en' => 'Failed to copy the temporary file',
  137.                 'de' => 'Temporäre Datei konnte nicht kopiert werden',
  138.                 'nl' => 'Het tijdelijke bestand kon niet gekopieerd worden',
  139.                 'fr' => 'L\'enregistrement du fichier temporaire a Θchoué',
  140.                 'it' => 'Copia del file temporaneo fallita'
  141.                 ),
  142.             'FILE_EXISTS' => array(
  143.                 'es' => 'El fichero destino ya existe',
  144.                 'en' => 'The destination file already exists',
  145.                 'de' => 'Die zu erzeugende Datei existiert bereits',
  146.                 'nl' => 'Het doelbestand bestaat al',
  147.                 'fr' => 'Le fichier de destination existe déjà',
  148.                 'it' => 'File destinazione già esistente'
  149.                 ),
  150.             'CANNOT_OVERWRITE' => array(
  151.                 'es' => 'El fichero destino ya existe y no se puede sobreescribir',
  152.                 'en' => 'The destination file already exists and could not be overwritten',
  153.                 'de' => 'Die zu erzeugende Datei existiert bereits und konnte nicht überschrieben werden',
  154.                 'nl' => 'Het doelbestand bestaat al, en kon niet worden overschreven',
  155.                 'fr' => 'Le fichier de destination existe déjà et ne peux pas être remplacé',
  156.                 'it' => 'File destinazione già esistente e non si può sovrascrivere'
  157.                 ),
  158.             'NOT_ALLOWED_EXTENSION' => array(
  159.                 'es' => 'Extension de fichero no permitida',
  160.                 'en' => 'Not permitted file extension',
  161.                 'de' => 'Unerlaubte Dateiendung',
  162.                 'nl' => 'Niet toegestane bestands-extensie.',
  163.                 'fr' => 'Le fichier a une extension non autorisée.',
  164.                 'it' => 'Estensione del File non permessa'
  165.                 )
  166.         );
  167.     }
  168.     /**
  169.     * returns the error code
  170.     *
  171.     * @param    string $e_code  type of error
  172.     * @return   string          Error message
  173.     */
  174.     function errorCode($e_code)
  175.     {
  176.         if (isset($this->lang) &&
  177.             !empty($this->error_codes[$e_code][$this->lang]))
  178.         {
  179.             $msg = $this->error_codes[$e_code][$this->lang];
  180.         } else {
  181.             $msg = $e_code;
  182.         }
  183.         return 'Upload Error: '. $msg;
  184.     }
  185.  
  186.     /**
  187.     * Overwrites the PEAR::raiseError method
  188.     *
  189.     * @param    string $e_code      type of error
  190.     * @return   object PEAR_Error   a PEAR-Error object
  191.     * @access   public
  192.     */
  193.     function raiseError($e_code)
  194.     {
  195.         return PEAR::raiseError($this->errorCode($e_code), $e_code);
  196.     }
  197. }
  198.  
  199. /**
  200. * This class provides an advanced file uploader system
  201. * for file uploads made from html forms
  202. *
  203. * @author   Tomas V.V.Cox <cox@vulcanonet.com>
  204. * @package  HTTP
  205. * @access   public
  206. */
  207. class HTTP_Upload extends HTTP_Upload_Error
  208. {
  209.     /**
  210.     * Contains an array of "uploaded files" objects
  211.     * @var array
  212.     */
  213.     var $files = array();
  214.  
  215.     /**
  216.     * Constructor
  217.     *
  218.     * @param string $lang Language to use for reporting errors
  219.     * @see Upload_Error::error_codes
  220.     * @access public
  221.     */
  222.     function HTTP_Upload($lang = null)
  223.     {
  224.         $this->HTTP_Upload_Error($lang);
  225.         global $HTTP_POST_FILES, $HTTP_SERVER_VARS;
  226.         $this->post_files   = $HTTP_POST_FILES;
  227.         $this->content_type = $HTTP_SERVER_VARS['CONTENT_TYPE'];
  228.     }
  229.  
  230.     /**
  231.     * Get files
  232.     *
  233.     * @param mixed $file If:
  234.     *    - not given, function will return array of upload_file objects
  235.     *    - is int, will return the $file position in upload_file objects array
  236.     *    - is string, will return the upload_file object corresponding
  237.     *        to $file name of the form. For ex:
  238.     *        if form is <input type="file" name="userfile">
  239.     *        to get this file use: $upload->getFiles('userfile')
  240.     *
  241.     * @return mixed array or object (see @param $file above) or Pear_Error
  242.     * @access public
  243.     */
  244.     function &getFiles($file = null)
  245.     {
  246.         //build only once for multiple calls
  247.         if (!isset($this->is_built)) {
  248.             $this->files = $this->_buildFiles();
  249.             if (PEAR::isError($this->files)) {
  250.                 return $this->files;
  251.             }
  252.             $this->is_built = true;
  253.         }
  254.         if ($file !== null) {
  255.             if (is_int($file)) {
  256.                 $pos = 0;
  257.                 foreach ($this->files as $key => $obj) {
  258.                     if ($pos == $file) {
  259.                         return $obj;
  260.                     }
  261.                     $pos++;
  262.                 }
  263.             } elseif (is_string($file) && isset($this->files[$file])) {
  264.                 return $this->files[$file];
  265.             }
  266.             return $this->raiseError('requested file not found'); // XXXX
  267.         }
  268.         return $this->files;
  269.     }
  270.  
  271.     /**
  272.     * Creates the list of the uploaded file
  273.     *
  274.     * @return array of HTTP_Upload_File objects for every file
  275.     */
  276.     function &_buildFiles()
  277.     {
  278.         // Form method check
  279.         if (!ereg('^multipart/form-data', $this->content_type)) {
  280.                 return $this->raiseError('BAD_FORM');
  281.         }
  282.         // In 4.1 HTTP_POST_FILES isn't initialized when no uploads
  283.         if (function_exists('version_compare') && version_compare(phpversion(), '4.1', 'ge')) {
  284.             $error = $this->isMissing();
  285.             if (PEAR::isError($error)) {
  286.                 return $error;
  287.             }
  288.         }
  289.  
  290.         // Parse $HTTP_POST_FILES
  291.         $files = array();
  292.         foreach ($this->post_files as $userfile => $value) {
  293.             if (is_array($value['name'])) {
  294.                 foreach ($value['name'] as $key => $val) {
  295.                     $name = basename($value['name'][$key]);
  296.                     $tmp_name = $value['tmp_name'][$key];
  297.                     $size = $value['size'][$key];
  298.                     $type = $value['type'][$key];
  299.                     $formname = $userfile . "[$key]";
  300.                     $files[$formname] = new HTTP_Upload_File($name, $tmp_name,
  301.                                             $formname, $type, $size, $this->lang);
  302.                 }
  303.             // One file
  304.             } else {
  305.                 $name = basename($value['name']);
  306.                 $tmp_name = $value['tmp_name'];
  307.                 $size = $value['size'];
  308.                 $type = $value['type'];
  309.                 $formname = $userfile;
  310.                 $files[$formname] = new HTTP_Upload_File($name, $tmp_name,
  311.                                             $formname, $type, $size, $this->lang);
  312.             }
  313.         }
  314.         return $files;
  315.     }
  316.  
  317.     /**
  318.     * Checks if the user submited or not some file
  319.     *
  320.     * @return mixed False when are files or PEAR_Error when no files
  321.     * @access public
  322.     * @see Read the note in the source code about this function
  323.     */
  324.     function isMissing()
  325.     {
  326.         if (empty($this->post_files) || count($this->post_files) < 1) {
  327.             return $this->raiseError('NO_USER_FILE');
  328.         }
  329.         return false;
  330.  
  331.     }
  332. }
  333.  
  334. /**
  335. * This class provides functions to work with the uploaded file
  336. *
  337. * @author   Tomas V.V.Cox <cox@vulcanonet.com>
  338. * @package  HTTP
  339. * @access   public
  340. */
  341. class HTTP_Upload_File extends HTTP_Upload_Error
  342. {
  343.     /**
  344.     * If the random seed was initialized before or not
  345.     * @var  boolean;
  346.     */
  347.     var $_seeded = 0;
  348.  
  349.     /**
  350.     * Assoc array with file properties
  351.     * @var array
  352.     */
  353.     var $upload = array();
  354.  
  355.     /**
  356.     * If user haven't selected a mode, by default 'safe' will be used
  357.     * @var boolean
  358.     */
  359.     var $mode_name_selected = false;
  360.  
  361.     /**
  362.     * It's a common security risk in pages who has the upload dir
  363.     * under the document root (remember the hack of the Apache web?)
  364.     *
  365.     * @var array
  366.     * @access private
  367.     * @see HTTP_Upload_File::setValidExtensions()
  368.     */
  369.     var $_extensions_check = array('php', 'phtm', 'phtml', 'php3', 'inc');
  370.  
  371.     /**
  372.     * @see HTTP_Upload_File::setValidExtensions()
  373.     * @var string
  374.     * @access private
  375.     */
  376.     var $_extensions_mode  = 'deny';
  377.  
  378.     /**
  379.     * Constructor
  380.     *
  381.     * @param   string  $name       destination file name
  382.     * @param   string  $tmp        temp file name
  383.     * @param   string  $formname   name of the form
  384.     * @param   string  $type       Mime type of the file
  385.     * @param   string  $size       size of the file
  386.     * @param   string  $lang       used language for errormessages
  387.     * @access  public
  388.     */
  389.     function HTTP_Upload_File($name=null, $tmp=null,  $formname=null,
  390.                                $type=null, $size=null, $lang=null)
  391.     {
  392.         $this->HTTP_Upload_Error($lang);
  393.         $error = null;
  394.         $ext   = null;
  395.         if (empty($name)) {
  396.             $error = 'NO_USER_FILE';
  397.         } elseif ($tmp == 'none') {
  398.             $error = 'TOO_LARGE';
  399.         } else {
  400.             // strpos needed to detect files without extension
  401.             if (($pos = strrpos($name, '.')) !== false) {
  402.                 $ext = substr ($name, $pos + 1);
  403.             }
  404.         }
  405.  
  406.         global $HTTP_POST_VARS;
  407.         // Seems that PHP 4.1.1 doesn't handle the MAX_FILE_SIZE correctly
  408.         // or I didn't find the new way
  409.         if (isset($HTTP_POST_VARS['MAX_FILE_SIZE']) &&
  410.             $size > $HTTP_POST_VARS['MAX_FILE_SIZE'])
  411.         {
  412.             $error = 'TOO_LARGE';
  413.         }
  414.  
  415.         $this->upload = array(
  416.             'real'      => $name,
  417.             'name'      => $name,
  418.             'form_name' => $formname,
  419.             'ext'       => $ext,
  420.             'tmp_name'  => $tmp,
  421.             'size'      => $size,
  422.             'type'      => $type,
  423.             'error'     => $error
  424.         );
  425.     }
  426.  
  427.     /**
  428.     * Sets the name of the destination file
  429.     *
  430.     * @param string $mode     A valid mode: 'uniq', 'safe' or 'real' or a file name
  431.     * @param string $prepend  A string to prepend to the name
  432.     * @param string $append   A string to append to the name
  433.     *
  434.     * @return string The modified name of the destination file
  435.     * @access public
  436.     */
  437.     function setName($mode, $prepend=null, $append=null)
  438.     {
  439.         switch ($mode) {
  440.             case 'uniq':
  441.                 $name = $this->nameToUniq();
  442.                 $this->upload['ext'] = $this->nameToSafe($this->upload['ext'], 10);
  443.                 $name .= '.' . $this->upload['ext'];
  444.                 break;
  445.             case 'safe':
  446.                 $name = $this->nameToSafe($this->upload['real']);
  447.                 if (($pos = strrpos($name, '.')) !== false) {
  448.                     $this->upload['ext'] = substr($name, $pos + 1);
  449.                 } else {
  450.                     $this->upload['ext'] = '';
  451.                 }
  452.                 break;
  453.             case 'real':
  454.                 $name = $this->upload['real'];
  455.                 break;
  456.             default:
  457.                 $name = $mode;
  458.         }
  459.         $this->upload['name'] = $prepend . $name . $append;
  460.         $this->mode_name_selected = true;
  461.         return $this->upload['name'];
  462.     }
  463.  
  464.     /**
  465.     * Unique file names in the form: 9022210413b75410c28bef.html
  466.     * @see HTTP_Upload_File::setName()
  467.     */
  468.     function nameToUniq()
  469.     {
  470.         if (! $this->_seeded) {
  471.             srand((double) microtime() * 1000000);
  472.             $this->_seeded = 1;
  473.         }
  474.         $uniq = uniqid(rand());
  475.         return $uniq;
  476.     }
  477.  
  478.     /**
  479.     * Format a file name to be safe
  480.     *
  481.     * @param    string $file   The string file name
  482.     * @param    int    $maxlen Maximun permited string lenght
  483.     * @return   string Formatted file name
  484.     * @see HTTP_Upload_File::setName()
  485.     */
  486.     function nameToSafe($name, $maxlen=250)
  487.     {
  488.         $noalpha = 'ßΘφ≤·αΦ∞≥∙Σδ∩÷ⁿ┴╔═╙┌└╚╠╥┘─╦╧╓▄ΓΩε⌠√┬╩╬╘█±τ╟@';
  489.         $alpha =   'aeiouaeiouaeiouAEIOUAEIOUAEIOUaeiouAEIOUncCa';
  490.         $name = substr ($name, 0, $maxlen);
  491.         $name = strtr ($name, $noalpha, $alpha);
  492.         // not permitted chars are replaced with "_"
  493.         return ereg_replace ('[^a-zA-Z0-9,._\+\()\-]', '_', $name);
  494.     }
  495.  
  496.     /**
  497.     * The upload was valid
  498.     *
  499.     * @return bool If the file was submitted correctly
  500.     * @access public
  501.     */
  502.     function isValid()
  503.     {
  504.         if ($this->upload['error'] === null) {
  505.             return true;
  506.         }
  507.         return false;
  508.     }
  509.  
  510.     /**
  511.     * User haven't submit a file
  512.     *
  513.     * @return bool If the user submitted a file or not
  514.     * @access public
  515.     */
  516.     function isMissing()
  517.     {
  518.         if ($this->upload['error'] == 'NO_USER_FILE') {
  519.             return true;
  520.         }
  521.         return false;
  522.     }
  523.  
  524.     /**
  525.     * Some error occured during upload (most common due a file size problem,
  526.     * like max size exceeded or 0 bytes long).
  527.     * @return bool If there were errors submitting the file (probably
  528.     *              because the file excess the max permitted file size)
  529.     * @access public
  530.     */
  531.     function isError()
  532.     {
  533.         if ($this->upload['error'] == 'TOO_LARGE') {
  534.             return true;
  535.         }
  536.         return false;
  537.     }
  538.  
  539.     /**
  540.     * Moves the uploaded file to its destination directory.
  541.     *
  542.     * @param    string  $dir_dest  Destination directory
  543.     * @param    bool    $overwrite Overwrite if destination file exists?
  544.     * @return   mixed   True on success or Pear_Error object on error
  545.     * @access public
  546.     */
  547.     function moveTo($dir_dest, $overwrite=true)
  548.     {
  549.         if (!$this->isValid()) {
  550.             return $this->raiseError($this->upload['error']);
  551.         }
  552.  
  553.         //Valid extensions check
  554.         if (!$this->_evalValidExtensions()) {
  555.             return $this->raiseError('NOT_ALLOWED_EXTENSION');
  556.         }
  557.  
  558.         $err_code = $this->_chk_dir_dest($dir_dest);
  559.         if ($err_code !== false) {
  560.             return $this->raiseError($err_code);
  561.         }
  562.         // Use 'safe' mode by default if no other was selected
  563.         if (!$this->mode_name_selected) {
  564.             $this->setName('safe');
  565.         }
  566.  
  567.         $name_dest = $dir_dest . DIRECTORY_SEPARATOR . $this->upload['name'];
  568.  
  569.         if (@is_file($name_dest)) {
  570.             if ($overwrite !== true) {
  571.                 return $this->raiseError('FILE_EXISTS');
  572.             } elseif (!is_writable($name_dest)) {
  573.                 return $this->raiseError('CANNOT_OVERWRITE');
  574.             }
  575.         }
  576.         // Copy the file and let php clean the tmp
  577.         if (!@copy($this->upload['tmp_name'], $name_dest)) {
  578.             return $this->raiseError('E_FAIL_MOVE');
  579.         }
  580.         @chmod($name_dest, 0660);
  581.         return $this->getProp('name');
  582.     }
  583.  
  584.     /**
  585.     * Check for a valid destination dir
  586.     *
  587.     * @param    string  $dir_dest Destination dir
  588.     * @return   mixed   False on no errors or error code on error
  589.     */
  590.     function _chk_dir_dest($dir_dest)
  591.     {
  592.         if (!$dir_dest) {
  593.             return 'MISSING_DIR';
  594.         }
  595.         if (!@is_dir ($dir_dest)) {
  596.             return 'IS_NOT_DIR';
  597.         }
  598.         if (!is_writeable ($dir_dest)) {
  599.             return 'NO_WRITE_PERMS';
  600.         }
  601.         return false;
  602.     }
  603.     /**
  604.     * Retrive properties of the uploaded file
  605.     * @param string $name   The property name. When null an assoc array with
  606.     *                       all the properties will be returned
  607.     * @return mixed         A string or array
  608.     * @see HTTP_Upload_File::HTTP_Upload_File()
  609.     * @access public
  610.     */
  611.     function getProp($name=null)
  612.     {
  613.         if ($name === null) {
  614.             return $this->upload;
  615.         }
  616.         return $this->upload[$name];
  617.     }
  618.  
  619.     /**
  620.     * Returns a error message, if a error occured
  621.     * (deprecated) Use getMessage() instead
  622.     * @return string    a Error message
  623.     * @access public
  624.     */
  625.     function errorMsg()
  626.     {
  627.         return $this->errorCode($this->upload['error']);
  628.     }
  629.  
  630.     /**
  631.     * Returns a error message, if a error occured
  632.     * @return string    a Error message
  633.     * @access public
  634.     */
  635.     function getMessage()
  636.     {
  637.         return $this->errorCode($this->upload['error']);
  638.     }
  639.  
  640.     /**
  641.     * Function to restrict the valid extensions on file uploads
  642.     *
  643.     * @param array $exts File extensions to validate
  644.     * @param string $mode The type of validation:
  645.     *                       1) 'deny'   Will deny only the supplied extensions
  646.     *                       2) 'accept' Will accept only the supplied extensions
  647.     *                                   as valid
  648.     * @access public
  649.     */
  650.     function setValidExtensions($exts, $mode = 'deny')
  651.     {
  652.         $this->_extensions_check = $exts;
  653.         $this->_extensions_mode  = $mode;
  654.     }
  655.  
  656.     /**
  657.     * Evaluates the validity of the extensions set by setValidExtensions
  658.     *
  659.     * @return bool False on non valid extension, true if they are valid
  660.     * @access private
  661.     */
  662.     function _evalValidExtensions()
  663.     {
  664.         $exts = $this->_extensions_check;
  665.         settype($exts, 'array');
  666.         if ($this->_extensions_mode == 'deny') {
  667.             if (in_array($this->getProp('ext'), $exts)) {
  668.                 return false;
  669.             }
  670.         // mode == 'accept'
  671.         } else {
  672.             if (!in_array($this->getProp('ext'), $exts)) {
  673.                 return false;
  674.             }
  675.         }
  676.         return true;
  677.     }
  678. }
  679. ?>