HTTP_Upload
[ class tree: HTTP_Upload ] [ index: HTTP_Upload ] [ all elements ]

Source for file Upload.php

Documentation is available at Upload.php

  1. <?php
  2. // ********************************************** //
  3. // This software is licensed by the LGPL
  4. // -> http://www.gnu.org/copyleft/lesser.txt 
  5. // (c) 2001- 2004 by Tomas Von Veschler Cox //
  6. // ********************************************** //
  7. // $Id$
  8.  
  9. /**
  10.  * Pear File Uploader class. Easy and secure managment of files
  11.  * submitted via HTML Forms.
  12.  *
  13.  * Leyend:
  14.  * - you can add error msgs in your language in the HTTP_Upload_Error class
  15.  *
  16.  * TODO:
  17.  * - try to think a way of having all the Error system in other
  18.  *   file and only include it when an error ocurrs
  19.  *
  20.  * -- Notes for users HTTP_Upload >= 0.9.0 --
  21.  *
  22.  *  Error detection was enhanced, so you no longer need to
  23.  *  check for PEAR::isError() in $upload->getFiles() or call
  24.  *  $upload->isMissing(). Instead you'll
  25.  *  get the error when do a check for $file->isError().
  26.  *
  27.  *  Example:
  28.  *
  29.  *  $upload = new HTTP_Upload('en');
  30.  *  $file = $upload->getFiles('i_dont_exist_in_form_definition');
  31.  *  if ($file->isError()) {
  32.  *      die($file->getMessage());
  33.  *  }
  34.  *
  35.  *  --
  36.  *
  37.  */
  38.  
  39. require_once 'PEAR.php';
  40.  
  41. /**
  42.  * defines default chmod
  43.  */
  44. define('HTTP_UPLOAD_DEFAULT_CHMOD'0660);
  45.  
  46. /**
  47.  * Error Class for HTTP_Upload
  48.  *
  49.  * @author  Tomas V.V.Cox <cox@idecnet.com>
  50.  * @see http://vulcanonet.com/soft/index.php?pack=uploader
  51.  * @package HTTP_Upload
  52.  * @category 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.      * Whether HTML entities shall be encoded automatically
  65.      * @var boolean 
  66.      */
  67.     var $html = false;
  68.  
  69.     /**
  70.      * PHP5 Constructor
  71.      *
  72.      * Creates a new PEAR_Error
  73.      *
  74.      * @param string $lang The language selected for error code messages
  75.      * @access public
  76.      */
  77.     function __construct($lang = null$html = false)
  78.     {
  79.         $this->lang = ($lang !== null$lang $this->lang;
  80.         $this->html = ($html !== false$html $this->html;
  81.         $raw_size ini_get('upload_max_filesize');
  82.         $ini_size intval($raw_size);
  83.         switch (strtoupper(substr($raw_size-1))) {
  84.             case 'G'$ini_size *= 1024;
  85.             case 'M'$ini_size *= 1024;
  86.             case 'K'$ini_size *= 1024;
  87.         }
  88.  
  89.         if (function_exists('version_compare'&&
  90.             version_compare(phpversion()'4.1''ge')) {
  91.             $maxsize (isset($_POST['MAX_FILE_SIZE'])) ?
  92.                 $_POST['MAX_FILE_SIZE': null;
  93.         else {
  94.             global $HTTP_POST_VARS;
  95.             $maxsize (isset($HTTP_POST_VARS['MAX_FILE_SIZE'])) ?
  96.                 $HTTP_POST_VARS['MAX_FILE_SIZE': null;
  97.         }
  98.  
  99.         if (empty($maxsize|| ($maxsize $ini_size)) {
  100.             $maxsize $ini_size;
  101.         }
  102.         $this->_maxsize $maxsize;
  103.  
  104.         $this->_loadLanguage('en');
  105.         $this->_loadLanguage($lang);
  106.     }
  107.  
  108.     /**
  109.      * PHP4 Constructor
  110.      *
  111.      * @see __construct()
  112.      */
  113.     function HTTP_Upload_Error($lang = null$html = false)
  114.     {
  115.         self::__construct($lang$html);
  116.     }
  117.  
  118.     /**
  119.      * returns the error code
  120.      *
  121.      * @param    string $e_code  type of error
  122.      * @return   string          Error message
  123.      */
  124.     function errorCode($e_code)
  125.     {
  126.         if (!empty($this->error_codes[$this->lang][$e_code])) {
  127.             $msg $this->html ?
  128.                 html_entity_decode($this->error_codes[$this->lang][$e_code]:
  129.                 $this->error_codes[$this->lang][$e_code];
  130.         else {
  131.             $msg $e_code;
  132.         }
  133.  
  134.         if (!empty($this->error_codes[$this->lang]['ERROR'])) {
  135.             $error $this->error_codes[$this->lang]['ERROR'];
  136.         else {
  137.             $error $this->error_codes['en']['ERROR'];
  138.         }
  139.         return $error.' '.$msg;
  140.     }
  141.  
  142.     /**
  143.      * Overwrites the PEAR::raiseError method
  144.      *
  145.      * @param    string $e_code      type of error
  146.      * @return   object PEAR_Error   a PEAR-Error object
  147.      * @access   public
  148.      */
  149.     function raiseError($e_code)
  150.     {
  151.         return PEAR::raiseError($this->errorCode($e_code)$e_code);
  152.     }
  153.  
  154.  
  155.     /**
  156.      * Loads language strings into error codes variable
  157.      *
  158.      * @param string $lang Language code (2-letter or pt_BR)
  159.      *
  160.      * @return mixed PEAR_Error on error, boolean true if all went well
  161.      */
  162.     function _loadLanguage($lang)
  163.     {
  164.         //prepare some variables
  165.         $maxsize $this->_maxsize;
  166.  
  167.         //when running from svn
  168.         $local dirname(__FILE__'/../data/' $lang '.php';
  169.         if (file_exists($local)) {
  170.             include $local;
  171.         else {
  172.             include_once 'PEAR/Config.php';
  173.             $dataf = PEAR_Config::singleton()->get('data_dir')
  174.                 . '/HTTP_Upload/' $lang '.php';
  175.             if (!file_exists($dataf)) {
  176.                 //that's a bad error here
  177.                 return PEAR::raiseError('Language file could not be loaded');
  178.             }
  179.             include $dataf;
  180.         }
  181.  
  182.         if (!isset($errorCodes[$lang])) {
  183.             return PEAR::raiseError(
  184.                 'No language found in ' $lang ' language file'
  185.             );
  186.         }
  187.         $this->error_codes[$lang$errorCodes[$lang];
  188.         return true;
  189.     }
  190. }
  191.  
  192. /**
  193.  * This class provides an advanced file uploader system
  194.  * for file uploads made from html forms
  195.  *
  196.  * @author  Tomas V.V.Cox <cox@idecnet.com>
  197.  * @see http://vulcanonet.com/soft/index.php?pack=uploader
  198.  * @package  HTTP_Upload
  199.  * @category HTTP
  200.  * @access   public
  201.  */
  202. {
  203.     /**
  204.      * Contains an array of "uploaded files" objects
  205.      * @var array 
  206.      */
  207.     var $files = array();
  208.     
  209.     /**
  210.      * Whether the files array has already been built or not
  211.      * @var int 
  212.      * @access private
  213.      */
  214.     var $is_built = false;
  215.  
  216.     /**
  217.      * Contains the desired chmod for uploaded files
  218.      * @var int 
  219.      * @access private
  220.      */
  221.     var $_chmod = HTTP_UPLOAD_DEFAULT_CHMOD;
  222.  
  223.     /**
  224.      * Specially used if the naming mode is 'seq'
  225.      * Contains file naming information
  226.      * 
  227.      * @var array 
  228.      * @access private
  229.      */
  230.     var $_modeNameSeq = array(
  231.         'flag' => false,
  232.         'prepend' => '',
  233.         'append' => '',
  234.     );
  235.  
  236.     /**
  237.      * PHP5 Constructor
  238.      *
  239.      * @param string $lang Language to use for reporting errors
  240.      * @see Upload_Error::error_codes
  241.      * @access public
  242.      */
  243.     function __construct($lang = null)
  244.     {
  245.         parent::__construct($lang);
  246.         if (function_exists('version_compare'&&
  247.             version_compare(phpversion()'4.1''ge'))
  248.         {
  249.             $this->post_files $_FILES;
  250.             if (isset($_SERVER['CONTENT_TYPE'])) {
  251.                 $this->content_type $_SERVER['CONTENT_TYPE'];
  252.             }
  253.         else {
  254.             global $HTTP_POST_FILES$HTTP_SERVER_VARS;
  255.             $this->post_files $HTTP_POST_FILES;
  256.             if (isset($HTTP_SERVER_VARS['CONTENT_TYPE'])) {
  257.                 $this->content_type $HTTP_SERVER_VARS['CONTENT_TYPE'];
  258.             }
  259.         }
  260.     }
  261.  
  262.     /**
  263.      * PHP4 Constructor
  264.      *
  265.      * @see __constructor
  266.      */
  267.     function HTTP_Upload($lang = null)
  268.     {
  269.         self::__construct($lang);
  270.     }
  271.  
  272.     /**
  273.      * Get files
  274.      *
  275.      * @param mixed $file If:
  276.      *     - not given, function will return array of upload_file objects
  277.      *     - is int, will return the $file position in upload_file objects array
  278.      *     - is string, will return the upload_file object corresponding
  279.      *         to $file name of the form. For ex:
  280.      *         if form is <input type="file" name="userfile">
  281.      *         to get this file use: $upload->getFiles('userfile')
  282.      *
  283.      * @return mixed array or object (see @param $file above) or Pear_Error
  284.      * @access public
  285.      */
  286.     function &getFiles($file = null)
  287.     {
  288.         //build only once for multiple calls
  289.         if (!$this->is_built{
  290.             $files &$this->_buildFiles();
  291.             if (PEAR::isError($files)) {
  292.                 // there was an error with the form.
  293.                 // Create a faked upload embedding the error
  294.                 $files_code $files->getCode();
  295.                 $this->files['_error'=  &new HTTP_Upload_File(
  296.                                                        '_error'null,
  297.                                                        nullnull,
  298.                                                        null$files_code,
  299.                                                        $this->lang$this->_chmod);
  300.             else {
  301.                 $this->files = $files;
  302.             }
  303.             $this->is_built = true;
  304.         }
  305.         if ($file !== null{
  306.             if (is_int($file)) {
  307.                 $pos = 0;
  308.                 foreach ($this->files as $obj{
  309.                     if ($pos == $file{
  310.                         return $obj;
  311.                     }
  312.                     $pos++;
  313.                 }
  314.             elseif (is_string($file&& isset($this->files[$file])) {
  315.                 return $this->files[$file];
  316.             }
  317.             if (isset($this->files['_error'])) {
  318.                 return $this->files['_error'];
  319.             else {
  320.                 // developer didn't specify this name in the form
  321.                 // warn him about it with a faked upload
  322.                 $huf =&  new HTTP_Upload_File(
  323.                                              '_error'null,
  324.                                              nullnull,
  325.                                              null'DEV_NO_DEF_FILE',
  326.                                              $this->lang);
  327.                 return $huf;
  328.             }
  329.         }
  330.         return $this->files;
  331.     }
  332.  
  333.     /**
  334.      * Creates the list of the uploaded file
  335.      *
  336.      * @return array of HTTP_Upload_File objects for every file
  337.      */
  338.     function &_buildFiles()
  339.     {
  340.         // Form method check
  341.         if (!isset($this->content_type||
  342.             strpos($this->content_type'multipart/form-data'!== 0)
  343.         {
  344.             $error =$this->raiseError('BAD_FORM');
  345.             return $error;
  346.         }
  347.         // In 4.1 $_FILES isn't initialized when no uploads
  348.         // XXX (cox) afaik, in >= 4.1 and < 4.3 only
  349.         if (function_exists('version_compare'&&
  350.             version_compare(PHP_VERSION'4.1''ge'&&
  351.             version_compare(PHP_VERSION'4.3''lt'))
  352.         {
  353.             $error $this->isMissing();
  354.             if (PEAR::isError($error)) {
  355.                 return $error;
  356.             }
  357.         }
  358.  
  359.         // map error codes from 4.2.0 $_FILES['userfile']['error']
  360.         if (function_exists('version_compare'&&
  361.             version_compare(phpversion()'4.2.0''ge')) {
  362.             $uploadError = array(
  363.                 1 => 'TOO_LARGE',
  364.                 2 => 'TOO_LARGE',
  365.                 3 => 'PARTIAL',
  366.                 4 => 'NO_USER_FILE'
  367.                 );
  368.         }
  369.  
  370.  
  371.         // Parse $_FILES (or $HTTP_POST_FILES)
  372.         $files = array();
  373.         foreach ($this->post_files as $userfile => $value{
  374.             if (is_array($value['name'])) {
  375.                 foreach ($value['name'as $key => $val{
  376.                     $err $value['error'][$key];
  377.                     if (isset($err&& $err !== 0 && isset($uploadError[$err])) {
  378.                         $error $uploadError[$err];
  379.                     else {
  380.                         $error = null;
  381.                     }
  382.                     $name basename($value['name'][$key]);
  383.                     $tmp_name $value['tmp_name'][$key];
  384.                     $size $value['size'][$key];
  385.                     $type $value['type'][$key];
  386.                     $formname $userfile . "[$key]";
  387.                     $files[$formname= new HTTP_Upload_File($name$tmp_name,
  388.                                                              $formname$type$size$error$this->lang$this->_chmod);
  389.                 }
  390.                 // One file
  391.             else {
  392.                 $err $value['error'];
  393.                 if (isset($err&& $err !== 0 && isset($uploadError[$err])) {
  394.                     $error $uploadError[$err];
  395.                 else {
  396.                     $error = null;
  397.                 }
  398.                 $name basename($value['name']);
  399.                 $tmp_name $value['tmp_name'];
  400.                 $size $value['size'];
  401.                 $type $value['type'];
  402.                 $formname $userfile;
  403.                 $files[$formname= new HTTP_Upload_File($name$tmp_name,
  404.                                                          $formname$type$size$error$this->lang$this->_chmod);
  405.             }
  406.         }
  407.         return $files;
  408.     }
  409.  
  410.     /**
  411.      * Checks if the user submited or not some file
  412.      *
  413.      * @return mixed False when are files or PEAR_Error when no files
  414.      * @access public
  415.      * @see Read the note in the source code about this function
  416.      */
  417.     function isMissing()
  418.     {
  419.         if (count($this->post_files< 1{
  420.             $error =$this->raiseError('NO_USER_FILE');
  421.             return $error;
  422.         }
  423.         //we also check if at least one file has more than 0 bytes :)
  424.         $files = array();
  425.         $size = 0;
  426.         $error = null;
  427.  
  428.         foreach ($this->post_files as $userfile => $value{
  429.             if (is_array($value['name'])) {
  430.                 foreach ($value['name'as $key => $val{
  431.                     $size += $value['size'][$key];
  432.                 }
  433.             elseif (!empty($value['name'])) {  //one file
  434.                 $size += $value['size'];
  435.                 $error $value['error'];
  436.             }
  437.         }
  438.         if ($error !== null && $error != 2 && $size == 0{
  439.             $error =$this->raiseError('NO_USER_FILE');
  440.             return $error;
  441.         }
  442.         return false;
  443.     }
  444.  
  445.     /**
  446.      * Sets the chmod to be used for uploaded files
  447.      *
  448.      * @param int Desired mode
  449.      */
  450.     function setChmod($mode)
  451.     {
  452.         $this->_chmod $mode;
  453.     }
  454. }
  455.  
  456. /**
  457.  * This class provides functions to work with the uploaded file
  458.  *
  459.  * @author  Tomas V.V.Cox <cox@idecnet.com>
  460.  * @see http://vulcanonet.com/soft/index.php?pack=uploader
  461.  * @package  HTTP_Upload
  462.  * @category HTTP
  463.  * @access   public
  464.  */
  465. {
  466.     /**
  467.      * Assoc array with file properties
  468.      * @var array 
  469.      */
  470.     var $upload = array();
  471.  
  472.     /**
  473.      * If user haven't selected a mode, by default 'safe' will be used
  474.      * @var boolean 
  475.      */
  476.     var $mode_name_selected = false;
  477.  
  478.     /**
  479.      * It's a common security risk in pages who has the upload dir
  480.      * under the document root (remember the hack of the Apache web?)
  481.      *
  482.      * @var array 
  483.      * @access private
  484.      * @see HTTP_Upload_File::setValidExtensions()
  485.      */
  486.     var $_extensionsCheck = array('php''phtm''phtml''php3''inc');
  487.  
  488.     /**
  489.      * @see HTTP_Upload_File::setValidExtensions()
  490.      * @var string 
  491.      * @access private
  492.      */
  493.     var $_extensionsMode  'deny';
  494.  
  495.     /**
  496.      * Whether to use case-sensitive extension checks or not
  497.      * @see HTTP_Upload_File::setValidExtensions()
  498.      * @var bool 
  499.      * @access private
  500.      */
  501.      var $_extensionsCaseSensitive = true;
  502.  
  503.     /**
  504.      * Contains the desired chmod for uploaded files
  505.      * @var int 
  506.      * @access private
  507.      */
  508.     var $_chmod = HTTP_UPLOAD_DEFAULT_CHMOD;
  509.  
  510.     /**
  511.      * PHP5 Constructor
  512.      *
  513.      * @param   string  $name       destination file name
  514.      * @param   string  $tmp        temp file name
  515.      * @param   string  $formname   name of the form
  516.      * @param   string  $type       Mime type of the file
  517.      * @param   string  $size       size of the file
  518.      * @param   string  $error      error on upload
  519.      * @param   string  $lang       used language for errormessages
  520.      * @access  public
  521.      */
  522.     function __construct($name = null$tmp = null,  $formname = null,
  523.                               $type = null$size = null$error = null,
  524.                               $lang = null$chmod = HTTP_UPLOAD_DEFAULT_CHMOD)
  525.     {
  526.         parent::__construct($lang);
  527.         $ext = null;
  528.  
  529.         if (empty($name)
  530.             || ($error != 'TOO_LARGE' && $error != 'DEV_NO_DEF_FILE' && $size == 0)
  531.         {
  532.             $error 'NO_USER_FILE';
  533.         elseif ($tmp == 'none' || $name == '_error' && $error == 'DEV_NO_DEF_FILE'{
  534.             $error 'TOO_LARGE';
  535.         else {
  536.             // strpos needed to detect files without extension
  537.             if (($pos strrpos($name'.')) !== false{
  538.                 $ext substr($name$pos + 1);
  539.             }
  540.         }
  541.  
  542.         if (function_exists('version_compare'&&
  543.             version_compare(phpversion()'4.1''ge')) {
  544.             if (isset($_POST['MAX_FILE_SIZE']&&
  545.                 $size $_POST['MAX_FILE_SIZE']{
  546.                 $error 'TOO_LARGE';
  547.             }
  548.         else {
  549.             global $HTTP_POST_VARS;
  550.             if (isset($HTTP_POST_VARS['MAX_FILE_SIZE']&&
  551.                 $size $HTTP_POST_VARS['MAX_FILE_SIZE']{
  552.                 $error 'TOO_LARGE';
  553.             }
  554.         }
  555.  
  556.         $this->upload = array(
  557.             'real'      => $name,
  558.             'name'      => $name,
  559.             'form_name' => $formname,
  560.             'ext'       => $ext,
  561.             'tmp_name'  => $tmp,
  562.             'size'      => $size,
  563.             'type'      => $type,
  564.             'error'     => $error
  565.         );
  566.  
  567.         $this->_chmod $chmod;
  568.     }
  569.  
  570.     /**
  571.      * PHP4 Constructor
  572.      *
  573.      * @see __construct
  574.      */
  575.     function HTTP_Upload_File($name = null$tmp = null,  $formname = null,
  576.                               $type = null$size = null$error = null,
  577.                               $lang = null$chmod = HTTP_UPLOAD_DEFAULT_CHMOD)
  578.     {
  579.         self::__construct($name$tmp$formname$type$size$error$lang$chmod);
  580.     }
  581.  
  582.     /**
  583.      * Sets the name of the destination file
  584.      *
  585.      * @param string $mode     A valid mode: 'uniq', 'seq', 'safe' or 'real' or a file name
  586.      * @param string $prepend  A string to prepend to the name
  587.      * @param string $append   A string to append to the name
  588.      *
  589.      * @return string The modified name of the destination file
  590.      * @access public
  591.      */
  592.     function setName($mode$prepend = null$append = null)
  593.     {
  594.         switch ($mode{
  595.             case 'uniq':
  596.                 $name $this->nameToUniq();
  597.                 $this->upload['ext'$this->nameToSafe($this->upload['ext']10);
  598.                 $name .= '.' $this->upload['ext'];
  599.                 break;
  600.             case 'safe':
  601.                 $name $this->nameToSafe($this->upload['real']);
  602.                 if (($pos strrpos($name'.')) !== false{
  603.                     $this->upload['ext'substr($name$pos + 1);
  604.                 else {
  605.                     $this->upload['ext''';
  606.                 }
  607.                 break;
  608.             case 'real':
  609.                 $name $this->upload['real'];
  610.                 break;
  611.             case 'seq':
  612.                 $this->_modeNameSeq['flag'= true;
  613.                 $this->_modeNameSeq['prepend'$prepend;
  614.                 $this->_modeNameSeq['append'$append;
  615.                 break;
  616.             default:
  617.                 $name $mode;
  618.         }
  619.         $this->upload['name'$prepend $name $append;
  620.         $this->mode_name_selected = true;
  621.         return $this->upload['name'];
  622.     }
  623.  
  624.     /**
  625.      * Sequence file names in the form: userGuide[1].pdf, userGuide[2].pdf ...
  626.      *
  627.      * @param string $dir  Destination directory
  628.      */
  629.     function nameToSeq($dir)
  630.     {
  631.         //Check if a file with the same name already exists
  632.         $name $dir . DIRECTORY_SEPARATOR . $this->upload['real'];
  633.         if (!@is_file($name)) {
  634.             return $this->upload['real'];
  635.         else {
  636.             //we need to strip out the extension and the '.' of the file
  637.             //e.g 'userGuide.pdf' becomes 'userGuide'
  638.             $baselength strlen($this->upload['real']strlen($this->upload['ext']- 1;
  639.             $basename substr$this->upload['real'],0$baselength );
  640.  
  641.             //here's the pattern we're looking for
  642.             $pattern '/(\[)([[:digit:]]+)(\])$/';
  643.  
  644.             //just incase the original filename had a sequence, we take it out 
  645.             // e.g: 'userGuide[3]' should become 'userGuide'
  646.             $basename =  preg_replace($pattern''$basename);
  647.             
  648.             /*
  649.              * attempt to find a unique sequence file name
  650.              */
  651.             $i = 1;
  652.             
  653.             while (true{
  654.                 $filename $basename '[' $i '].' $this->upload['ext'];
  655.                 $check $dir . DIRECTORY_SEPARATOR . $filename;
  656.                 if (!@is_file($check)) {
  657.                     return $filename;
  658.                 }
  659.                 $i++;
  660.             }
  661.         }
  662.     }
  663.  
  664.     /**
  665.      * Unique file names in the form: 9022210413b75410c28bef.html
  666.      * @see HTTP_Upload_File::setName()
  667.      */
  668.     function nameToUniq()
  669.     {
  670.         $uniq uniqid(rand());
  671.         return $uniq;
  672.     }
  673.  
  674.     /**
  675.      * Format a file name to be safe
  676.      *
  677.      * @param    string $file   The string file name
  678.      * @param    int    $maxlen Maximun permited string lenght
  679.      * @return   string Formatted file name
  680.      * @see HTTP_Upload_File::setName()
  681.      */
  682.     function nameToSafe($name$maxlen=250)
  683.     {
  684.         $noalpha ;
  685.         $alpha   'AEIOUYaeiouyAEIOUaeiouAEIOUaeiouAEIOUaeiouyAaOoAaNnCcaooaTtAa';
  686.  
  687.         $name substr($name0$maxlen);
  688.         $name strtr($name$noalpha$alpha);
  689.         // not permitted chars are replaced with "_"
  690.         return preg_replace('/[^a-zA-Z0-9,._\+\()\-]/''_'$name);
  691.     }
  692.  
  693.     /**
  694.      * The upload was valid
  695.      *
  696.      * @return bool If the file was submitted correctly
  697.      * @access public
  698.      */
  699.     function isValid()
  700.     {
  701.         if ($this->upload['error'=== null{
  702.             return true;
  703.         }
  704.         return false;
  705.     }
  706.  
  707.     /**
  708.      * User haven't submit a file
  709.      *
  710.      * @return bool If the user submitted a file or not
  711.      * @access public
  712.      */
  713.     function isMissing()
  714.     {
  715.         if ($this->upload['error'== 'NO_USER_FILE'{
  716.             return true;
  717.         }
  718.         return false;
  719.     }
  720.  
  721.     /**
  722.      * Some error occured during upload (most common due a file size problem,
  723.      * like max size exceeded or 0 bytes long).
  724.      * @return bool If there were errors submitting the file (probably
  725.      *               because the file excess the max permitted file size)
  726.      * @access public
  727.      */
  728.     function hasError()
  729.     {
  730.         if (in_array($this->upload['error']array('TOO_LARGE''BAD_FORM','DEV_NO_DEF_FILE'))) {
  731.             return true;
  732.         }
  733.         return false;
  734.     }
  735.  
  736.     /**
  737.      * Moves the uploaded file to its destination directory.
  738.      *
  739.      * @param  string  $dir  Destination directory
  740.      * @param  bool    $overwrite Overwrite if destination file exists?
  741.      * @return mixed   True on success or PEAR_Error object on error
  742.      * @access public
  743.      */
  744.     function moveTo($dir$overwrite = true)
  745.     {
  746.         if (!$this->isValid()) {
  747.             $error =$this->raiseError($this->upload['error']);
  748.             return $error;
  749.         }
  750.  
  751.         //Valid extensions check
  752.         if (!$this->_evalValidExtensions()) {
  753.             $error =$this->raiseError('NOT_ALLOWED_EXTENSION');
  754.             return $error;
  755.         }
  756.  
  757.         $err_code $this->_chkDirDest($dir);
  758.         if ($err_code !== false{
  759.             $error =$this->raiseError($err_code);
  760.             return $error;
  761.         }
  762.         // Use 'safe' mode by default if no other was selected
  763.         if (!$this->mode_name_selected{
  764.             $this->setName('safe');
  765.         }
  766.  
  767.         //test to see if we're working with sequence naming mode
  768.         if (isset($this->_modeNameSeq&& isset($this->_modeNameSeq['flag']&& $this->_modeNameSeq['flag'=== true{
  769.             $this->upload['name'$this->_modeNameSeq['prepend'$this->nameToSeq($dir$this->_modeNameSeq['append'];
  770.         }
  771.  
  772.         $name $dir . DIRECTORY_SEPARATOR . $this->upload['name'];
  773.  
  774.         if (@is_file($name)) {
  775.             if ($overwrite !== true{
  776.                 $error =$this->raiseError('FILE_EXISTS');
  777.                 return $error;
  778.             elseif (!is_writable($name)) {
  779.                 $error =$this->raiseError('CANNOT_OVERWRITE');
  780.                 return $error;
  781.             }
  782.         }
  783.  
  784.         // copy the file and let php clean the tmp
  785.         if (!@move_uploaded_file($this->upload['tmp_name']$name)) {
  786.             $error =$this->raiseError('E_FAIL_MOVE');
  787.             return $error
  788.         }
  789.         @chmod($name$this->_chmod);
  790.         $prop =$this->getProp('name');
  791.         return $prop;
  792.     }
  793.  
  794.     /**
  795.      * Check for a valid destination dir
  796.      *
  797.      * @param    string  $dir_dest Destination dir
  798.      * @return   mixed   False on no errors or error code on error
  799.      */
  800.     function _chkDirDest($dir_dest)
  801.     {
  802.         if (!$dir_dest{
  803.             return 'MISSING_DIR';
  804.         }
  805.         if (!@is_dir($dir_dest)) {
  806.             return 'IS_NOT_DIR';
  807.         }
  808.         if (!is_writeable($dir_dest)) {
  809.             return 'NO_WRITE_PERMS';
  810.         }
  811.         return false;
  812.     }
  813.     /**
  814.      * Retrive properties of the uploaded file
  815.      * @param string $name   The property name. When null an assoc array with
  816.      *                        all the properties will be returned
  817.      * @return mixed         A string or array
  818.      * @see HTTP_Upload_File::HTTP_Upload_File()
  819.      * @access public
  820.      */
  821.     function getProp($name = null)
  822.     {
  823.         if ($name === null{
  824.             return $this->upload;
  825.         }
  826.         return $this->upload[$name];
  827.     }
  828.  
  829.     /**
  830.      * Returns a error message, if a error occured
  831.      * (deprecated) Use getMessage() instead
  832.      * @return string    a Error message
  833.      * @access public
  834.      */
  835.     function errorMsg()
  836.     {
  837.         return $this->errorCode($this->upload['error']);
  838.     }
  839.  
  840.     /**
  841.      * Returns a error message, if a error occured
  842.      * @return string    a Error message
  843.      * @access public
  844.      */
  845.     function getMessage()
  846.     {
  847.         return $this->errorCode($this->upload['error']);
  848.     }
  849.  
  850.     /**
  851.      * Returns an array with all valid file extensions.
  852.      *
  853.      * @return array Array of extensions without dot.
  854.      *
  855.      * @access public
  856.      */
  857.     function getValidExtensions()
  858.     {
  859.         return $this->_extensionsCheck;
  860.     }
  861.  
  862.     /**
  863.      * Function to restrict the valid extensions on file uploads.
  864.      * Restrictions are applied to the name of the file on the user's
  865.      * disk, not the destination file name used at moveTo().
  866.      *
  867.      * @param array $exts File extensions to validate
  868.      * @param string $mode The type of validation:
  869.      *                        1) 'deny'   Will deny only the supplied extensions
  870.      *                        2) 'accept' Will accept only the supplied extensions
  871.      *                                    as valid
  872.      * @param bool $case_sensitive whether extension check is case sensitive.
  873.      *                              When it is case insensitive, the extension
  874.      *                              is lowercased before compared to the array
  875.      *                              of valid extensions.
  876.      * @access public
  877.      */
  878.     function setValidExtensions($exts$mode 'deny'$case_sensitive = null)
  879.     {
  880.         $this->_extensionsCheck $exts;
  881.         $this->_extensionsMode  $mode;
  882.         if ($case_sensitive != null{
  883.             $this->_extensionsCaseSensitive  $case_sensitive;
  884.         }
  885.     }
  886.  
  887.     /**
  888.      * Evaluates the validity of the extensions set by setValidExtensions.
  889.      * Checks the validity of the file extension of the original filename
  890.      * the user used for the file on his disk.
  891.      *
  892.      * @return bool False on non valid extension, true if they are valid
  893.      * @access private
  894.      */
  895.     function _evalValidExtensions()
  896.     {
  897.         $exts $this->_extensionsCheck;
  898.         settype($exts'array');
  899.         $ext $this->getProp('ext');
  900.         if (!$this->_extensionsCaseSensitive{
  901.             $ext strtolower($ext);
  902.         }
  903.         if ($this->_extensionsMode == 'deny'{
  904.             if (in_array($ext$exts)) {
  905.                 return false;
  906.             }
  907.         // mode == 'accept'
  908.         else {
  909.             if (!in_array($ext$exts)) {
  910.                 return false;
  911.             }
  912.         }
  913.         return true;
  914.     }
  915. }

Documentation generated on Mon, 11 Mar 2019 16:04:24 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.