home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / CMS / xoops-2.0.18.1.exe / xoops-2.0.18.1 / htdocs / class / uploader.php < prev    next >
Encoding:
PHP Script  |  2007-12-23  |  16.8 KB  |  521 lines

  1. <?php
  2. // $Id: uploader.php 1200 2007-12-23 00:05:58Z phppp $
  3. //  ------------------------------------------------------------------------ //
  4. //                XOOPS - PHP Content Management System                      //
  5. //                    Copyright (c) 2000 XOOPS.org                           //
  6. //                       <http://www.xoops.org/>                             //
  7. //  ------------------------------------------------------------------------ //
  8. //  This program is free software; you can redistribute it and/or modify     //
  9. //  it under the terms of the GNU General Public License as published by     //
  10. //  the Free Software Foundation; either version 2 of the License, or        //
  11. //  (at your option) any later version.                                      //
  12. //                                                                           //
  13. //  You may not change or alter any portion of this comment or credits       //
  14. //  of supporting developers from this source code or any supporting         //
  15. //  source code which is considered copyrighted (c) material of the          //
  16. //  original comment or credit authors.                                      //
  17. //                                                                           //
  18. //  This program is distributed in the hope that it will be useful,          //
  19. //  but WITHOUT ANY WARRANTY; without even the implied warranty of           //
  20. //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
  21. //  GNU General Public License for more details.                             //
  22. //                                                                           //
  23. //  You should have received a copy of the GNU General Public License        //
  24. //  along with this program; if not, write to the Free Software              //
  25. //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
  26. //  ------------------------------------------------------------------------ //
  27. // Author: Kazumi Ono (AKA onokazu)                                          //
  28. // URL: http://www.myweb.ne.jp/, http://www.xoops.org/, http://jp.xoops.org/ //
  29. // Project: The XOOPS Project                                                //
  30. // ------------------------------------------------------------------------- //
  31. /*!
  32. Example
  33.  
  34.   include_once 'uploader.php';
  35.   $allowed_mimetypes = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/x-png');
  36.   $maxfilesize = 50000;
  37.   $maxfilewidth = 120;
  38.   $maxfileheight = 120;
  39.   $uploader = new XoopsMediaUploader('/home/xoops/uploads', $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight);
  40.   if ($uploader->fetchMedia($_POST['uploade_file_name'])) {
  41.     if (!$uploader->upload()) {
  42.        echo $uploader->getErrors();
  43.     } else {
  44.        echo '<h4>File uploaded successfully!</h4>'
  45.        echo 'Saved as: ' . $uploader->getSavedFileName() . '<br />';
  46.        echo 'Full path: ' . $uploader->getSavedDestination();
  47.     }
  48.   } else {
  49.     echo $uploader->getErrors();
  50.   }
  51.  
  52. */
  53.  
  54. /**
  55.  * Upload Media files
  56.  * 
  57.  * Example of usage:
  58.  * <code>
  59.  * include_once 'uploader.php';
  60.  * $allowed_mimetypes = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/x-png');
  61.  * $maxfilesize = 50000;
  62.  * $maxfilewidth = 120;
  63.  * $maxfileheight = 120;
  64.  * $uploader = new XoopsMediaUploader('/home/xoops/uploads', $allowed_mimetypes, $maxfilesize, $maxfilewidth, $maxfileheight);
  65.  * if ($uploader->fetchMedia($_POST['uploade_file_name'])) {
  66.  *   if (!$uploader->upload()) {
  67.  *      echo $uploader->getErrors();
  68.  *   } else {
  69.  *      echo '<h4>File uploaded successfully!</h4>'
  70.  *      echo 'Saved as: ' . $uploader->getSavedFileName() . '<br />';
  71.  *      echo 'Full path: ' . $uploader->getSavedDestination();
  72.  *   }
  73.  * } else {
  74.  *   echo $uploader->getErrors();
  75.  * }
  76.  * </code>
  77.  *
  78.  * @package     kernel
  79.  * @subpackage  core
  80.  *
  81.  * @author      Kazumi Ono     <onokazu@xoops.org>
  82.  * @author      phppp
  83.  * @copyright   The Xoops Project
  84.  */
  85. class XoopsMediaUploader
  86. {
  87.     /**
  88.     * Flag indicating if unrecognized mimetypes should be allowed (use with precaution ! may lead to security issues )
  89.     **/
  90.      var $allowUnknownTypes = false;
  91.  
  92.     var $mediaName;
  93.     var $mediaType;
  94.     var $mediaSize;
  95.     var $mediaTmpName;
  96.     var $mediaError;
  97.     var $mediaRealType = '';
  98.  
  99.     var $uploadDir = '';
  100.  
  101.     var $allowedMimeTypes = array();
  102.     var $deniedMimeTypes = array("application/x-httpd-php");
  103.  
  104.     var $maxFileSize = 0;
  105.     var $maxWidth;
  106.     var $maxHeight;
  107.  
  108.     var $targetFileName;
  109.  
  110.     var $prefix;
  111.  
  112.     var $errors = array();
  113.  
  114.     var $savedDestination;
  115.  
  116.     var $savedFileName;
  117.  
  118.     var $extensionToMime = array();
  119.     var $checkImageType = true;
  120.  
  121.     var $extensionsToBeSanitized = array( 'php' , 'phtml' , 'phtm' , 'php3' , 'php4' , 'cgi' , 'pl' , 'asp', 'php5' );
  122.     // extensions needed image check (anti-IE Content-Type XSS)
  123.     var $imageExtensions = array( 1 => 'gif', 2 => 'jpg', 3 => 'png', 4 => 'swf', 5 => 'psd', 6 => 'bmp', 7 => 'tif', 8 => 'tif', 9 => 'jpc', 10 => 'jp2', 11 => 'jpx', 12 => 'jb2', 13 => 'swc', 14 => 'iff', 15 => 'wbmp', 16 => 'xbm' );
  124.     
  125.     /**
  126.      * Constructor
  127.      *
  128.      * @param   string  $uploadDir
  129.      * @param   array   $allowedMimeTypes
  130.      * @param   int     $maxFileSize
  131.      * @param   int     $maxWidth
  132.      * @param   int     $maxHeight
  133.      * @param   int     $cmodvalue
  134.      **/
  135.     function XoopsMediaUploader($uploadDir, $allowedMimeTypes, $maxFileSize=0, $maxWidth=null, $maxHeight=null)
  136.     {
  137.         @$this->extensionToMime = include XOOPS_ROOT_PATH . '/class/mimetypes.inc.php';
  138.         if ( !is_array( $this->extensionToMime ) ) {
  139.              $this->extensionToMime = array();
  140.             return false;
  141.         }
  142.         if (is_array($allowedMimeTypes)) {
  143.             $this->allowedMimeTypes =& $allowedMimeTypes;
  144.         }
  145.         $this->uploadDir = $uploadDir;
  146.         $this->maxFileSize = intval($maxFileSize);
  147.         if (isset($maxWidth)) {
  148.             $this->maxWidth = intval($maxWidth);
  149.         }
  150.         if (isset($maxHeight)) {
  151.             $this->maxHeight = intval($maxHeight);
  152.         }
  153.         
  154.         if ( ! @ include_once XOOPS_ROOT_PATH."/language/".$GLOBALS['xoopsConfig']['language']."/uploader.php" ) {
  155.             include_once XOOPS_ROOT_PATH."/language/english/uploader.php";
  156.         }
  157.     }
  158.  
  159.     /**
  160.      * Fetch the uploaded file
  161.      *
  162.      * @param   string  $media_name Name of the file field
  163.      * @param   int     $index      Index of the file (if more than one uploaded under that name)
  164.      * @return  bool
  165.      **/
  166.     function fetchMedia($media_name, $index = null)
  167.     {
  168.         if ( empty( $this->extensionToMime ) ) {
  169.             $this->setErrors( _ER_UP_MIMETYPELOAD );
  170.             return false;
  171.         }
  172.         if (!isset($_FILES[$media_name])) {
  173.             $this->setErrors(_ER_UP_FILENOTFOUND);
  174.             return false;
  175.         } elseif (is_array($_FILES[$media_name]['name']) && isset($index)) {
  176.             $index = intval($index);
  177.             $this->mediaName = (get_magic_quotes_gpc()) ? stripslashes($_FILES[$media_name]['name'][$index]) : $_FILES[$media_name]['name'][$index];
  178.             $this->mediaType = $_FILES[$media_name]['type'][$index];
  179.             $this->mediaSize = $_FILES[$media_name]['size'][$index];
  180.             $this->mediaTmpName = $_FILES[$media_name]['tmp_name'][$index];
  181.             $this->mediaError = !empty($_FILES[$media_name]['error'][$index]) ? $_FILES[$media_name]['error'][$index] : 0;
  182.         } else {
  183.             $media_name =& $_FILES[$media_name];
  184.             $this->mediaName = (get_magic_quotes_gpc()) ? stripslashes($media_name['name']) : $media_name['name'];
  185.             $this->mediaType = $media_name['type'];
  186.             $this->mediaSize = $media_name['size'];
  187.             $this->mediaTmpName = $media_name['tmp_name'];
  188.             $this->mediaError = !empty($media_name['error']) ? $media_name['error'] : 0;
  189.         }
  190.         if ( ($ext = strrpos( $this->mediaName, '.' )) !== false ) {
  191.             $ext = strtolower(substr( $this->mediaName, $ext + 1 ));
  192.             if ( isset( $this->extensionToMime[$ext] ) ) {
  193.                 $this->mediaRealType = $this->extensionToMime[$ext];
  194.             }
  195.         }
  196.         $this->errors = array();
  197.         if (intval($this->mediaSize) < 0) {
  198.             $this->setErrors(_ER_UP_INVALIDFILESIZE);
  199.             return false;
  200.         }
  201.         if ($this->mediaName == '') {
  202.             $this->setErrors( _ER_UP_FILENAMEEMPTY);
  203.             return false;
  204.         }
  205.         if ($this->mediaTmpName == 'none' || !is_uploaded_file($this->mediaTmpName)) {
  206.             $this->setErrors(_ER_UP_NOFILEUPLOADED);
  207.             return false;
  208.         }
  209.         if ($this->mediaError > 0) {
  210.             $this->setErrors(sprintf(_ER_UP_ERROROCCURRED, $this->mediaError));
  211.             return false;
  212.         }
  213.         return true;
  214.     }
  215.  
  216.     /**
  217.      * Set the target filename
  218.      * 
  219.      * @param   string  $value
  220.      **/
  221.     function setTargetFileName($value){
  222.         $this->targetFileName = strval(trim($value));
  223.     }
  224.  
  225.     /**
  226.      * Set the prefix
  227.      * 
  228.      * @param   string  $value
  229.      **/
  230.     function setPrefix($value){
  231.         $this->prefix = strval(trim($value));
  232.     }
  233.  
  234.     /**
  235.      * Get the uploaded filename
  236.      * 
  237.      * @return  string 
  238.      **/
  239.     function getMediaName()
  240.     {
  241.         return $this->mediaName;
  242.     }
  243.  
  244.     /**
  245.      * Get the type of the uploaded file
  246.      * 
  247.      * @return  string 
  248.      **/
  249.     function getMediaType()
  250.     {
  251.         return $this->mediaType;
  252.     }
  253.  
  254.     /**
  255.      * Get the size of the uploaded file
  256.      * 
  257.      * @return  int 
  258.      **/
  259.     function getMediaSize()
  260.     {
  261.         return $this->mediaSize;
  262.     }
  263.  
  264.     /**
  265.      * Get the temporary name that the uploaded file was stored under
  266.      * 
  267.      * @return  string 
  268.      **/
  269.     function getMediaTmpName()
  270.     {
  271.         return $this->mediaTmpName;
  272.     }
  273.  
  274.     /**
  275.      * Get the saved filename
  276.      * 
  277.      * @return  string 
  278.      **/
  279.     function getSavedFileName(){
  280.         return $this->savedFileName;
  281.     }
  282.  
  283.     /**
  284.      * Get the destination the file is saved to
  285.      * 
  286.      * @return  string
  287.      **/
  288.     function getSavedDestination(){
  289.         return $this->savedDestination;
  290.     }
  291.  
  292.     /**
  293.      * Check the file and copy it to the destination
  294.      * 
  295.      * @return  bool
  296.      **/
  297.     function upload($chmod = 0644)
  298.     {
  299.         if ($this->uploadDir == '') {
  300.             $this->setErrors(_ER_UP_UPLOADDIRNOTSET);
  301.             return false;
  302.         }
  303.         if (!is_dir($this->uploadDir)) {
  304.             $this->setErrors(sprintf(_ER_UP_FAILEDOPENDIR, $this->uploadDir));
  305.             return false;
  306.         }
  307.         if (!is_writeable($this->uploadDir)) {
  308.             $this->setErrors(sprintf(_ER_UP_FAILEDOPENDIRWRITE, $this->uploadDir));
  309.             return false;
  310.         }
  311.         $this->sanitizeMultipleExtensions();
  312.         
  313.         if (!$this->checkMaxFileSize()) {
  314.             return false;
  315.         }
  316.         if (!$this->checkMaxWidth()) {
  317.             return false;
  318.         }
  319.         if (!$this->checkMaxHeight()) {
  320.             return false;
  321.         }
  322.         if (!$this->checkMimeType()) {
  323.             return false;
  324.         }
  325.         if (!$this->checkImageType()) {
  326.             return false;
  327.         }
  328.         if (count($this->errors) > 0) {
  329.             return false;
  330.         }
  331.         return $this->_copyFile($chmod);
  332.     }
  333.  
  334.     /**
  335.      * Copy the file to its destination
  336.      * 
  337.      * @return  bool 
  338.      **/
  339.     function _copyFile($chmod)
  340.     {
  341.         $matched = array();
  342.         if (!preg_match("/\.([a-zA-Z0-9]+)$/", $this->mediaName, $matched)) {
  343.             $this->setErrors(_ER_UP_INVALIDFILENAME);
  344.             return false;
  345.         }
  346.         if (isset($this->targetFileName)) {
  347.             $this->savedFileName = $this->targetFileName;
  348.         } elseif (isset($this->prefix)) {
  349.             $this->savedFileName = uniqid($this->prefix).'.'.strtolower($matched[1]);
  350.         } else {
  351.             $this->savedFileName = strtolower($this->mediaName);
  352.         }
  353.         $this->savedDestination = $this->uploadDir.'/'.$this->savedFileName;
  354.         if (!move_uploaded_file($this->mediaTmpName, $this->savedDestination)) {
  355.             $this->setErrors(sprintf(_ER_UP_FAILEDSAVEFILE, $this->savedDestination));
  356.             return false;
  357.         }
  358.         // Check IE XSS before returning success
  359.         $ext = strtolower( substr( strrchr( $this->savedDestination , '.' ) , 1 ) ) ;
  360.         if( in_array( $ext , $this->imageExtensions ) ) {
  361.             $info = @getimagesize( $this->savedDestination ) ;
  362.             if( $info === false || $this->imageExtensions[ (int)$info[2] ] != $ext ) {
  363.                 $this->setErrors( _ER_UP_SUSPICIOUSREFUSED );
  364.                 @unlink( $this->savedDestination );
  365.                 return false;
  366.             }
  367.         }
  368.         @chmod($this->savedDestination, $chmod);
  369.         return true;
  370.     }
  371.  
  372.     /**
  373.      * Is the file the right size?
  374.      * 
  375.      * @return  bool 
  376.      **/
  377.     function checkMaxFileSize()
  378.     {
  379.         if (!isset($this->maxFileSize)) {
  380.             return true;
  381.         }
  382.         if ($this->mediaSize > $this->maxFileSize) {
  383.             $this->setErrors(sprintf(_ER_UP_FILESIZETOOLARGE, $this->maxFileSize, $this->mediaSize));
  384.             return false;
  385.         }
  386.         return true;
  387.     }
  388.  
  389.     /**
  390.      * Is the picture the right width?
  391.      * 
  392.      * @return  bool 
  393.      **/
  394.     function checkMaxWidth()
  395.     {
  396.         if (!isset($this->maxWidth)) {
  397.             return true;
  398.         }
  399.         if (false !== $dimension = getimagesize($this->mediaTmpName)) {
  400.             if ($dimension[0] > $this->maxWidth) {
  401.                 $this->setErrors(sprintf(_ER_UP_FILEWIDTHTOOLARGE, $this->maxWidth, $dimension[0]));
  402.                 return false;
  403.             }
  404.         } else {
  405.             trigger_error(sprintf(_ER_UP_FAILEDFETCHIMAGESIZE, $this->mediaTmpName), E_USER_WARNING);
  406.         }
  407.         return true;
  408.     }
  409.  
  410.     /**
  411.      * Is the picture the right height?
  412.      * 
  413.      * @return  bool 
  414.      **/
  415.     function checkMaxHeight()
  416.     {
  417.         if (!isset($this->maxHeight)) {
  418.             return true;
  419.         }
  420.         if (false !== $dimension = getimagesize($this->mediaTmpName)) {
  421.             if ($dimension[1] > $this->maxHeight) {
  422.                 $this->setErrors(sprintf(_ER_UP_FILEHEIGHTTOOLARGE, $this->maxHeight, $dimension[1]));
  423.                 return false;
  424.             }
  425.         } else {
  426.             trigger_error(sprintf(_ER_UP_FAILEDFETCHIMAGESIZE, $this->mediaTmpName), E_USER_WARNING);
  427.         }
  428.         return true;
  429.     }
  430.  
  431.     /**
  432.      * Check whether or not the uploaded file type is allowed
  433.      *
  434.      * @return  bool
  435.      **/
  436.     function checkMimeType()
  437.     {
  438.         if ( empty( $this->mediaRealType ) && empty($this->allowUnknownTypes) ) {
  439.             $this->setErrors( _ER_UP_UNKNOWNFILETYPEREJECTED );
  440.             return false;
  441.         }
  442.  
  443.         if ( ( !empty($this->allowedMimeTypes) && !in_array($this->mediaRealType, $this->allowedMimeTypes) ) 
  444.              || ( !empty($this->deniedMimeTypes) && in_array($this->mediaRealType, $this->deniedMimeTypes) ) ) {
  445.             $this->setErrors(sprintf(_ER_UP_MIMETYPENOTALLOWED, $this->mediaType));
  446.             return false;
  447.         }
  448.         
  449.         return true;
  450.     }
  451.  
  452.     /**
  453.      * Check whether or not the uploaded image type is valid
  454.      *
  455.      * @return  bool
  456.      **/
  457.     function checkImageType()
  458.     {
  459.         if(empty($this->checkImageType)) return true;
  460.  
  461.         if( ("image" == substr($this->mediaType, 0, strpos($this->mediaType, "/"))) || 
  462.             (!empty($this->mediaRealType) && "image" == substr($this->mediaRealType, 0, strpos($this->mediaRealType, "/")))
  463.         ){
  464.             if ( ! ( $info = @getimagesize( $this->mediaTmpName ) ) ) {
  465.                 $this->setErrors(_ER_UP_INVALIDIMAGEFILE);
  466.                 return false;
  467.             }
  468.         }
  469.         return true;
  470.     }
  471.  
  472.     /**
  473.      * Sanitize executable filename with multiple extensions
  474.      *
  475.      **/
  476.     function sanitizeMultipleExtensions()
  477.     {
  478.         if(empty($this->extensionsToBeSanitized)) return;
  479.         $patterns = array();
  480.         $replaces = array();
  481.         foreach($this->extensionsToBeSanitized as $ext){
  482.             $patterns[] = "/\.".preg_quote($ext)."\./i";
  483.             $replaces[] = "_".$ext.".";
  484.         }
  485.         $this->mediaName = preg_replace($patterns, $replaces, $this->mediaName);
  486.     }
  487.  
  488.     /**
  489.      * Add an error
  490.      * 
  491.      * @param   string  $error
  492.      **/
  493.     function setErrors($error)
  494.     {
  495.         $this->errors[] = trim($error);
  496.     }
  497.  
  498.     /**
  499.      * Get generated errors
  500.      *
  501.      * @param    bool    $ashtml Format using HTML?
  502.      * 
  503.      * @return    array|string    Array of array messages OR HTML string
  504.      */
  505.     function &getErrors($ashtml = true)
  506.     {
  507.         if (!$ashtml) {
  508.             return $this->errors;
  509.         } else {
  510.             $ret = '';
  511.             if (count($this->errors) > 0) {
  512.                 $ret = '<h4>'._ER_UP_ERRORSRETURNED.'</h4>';
  513.                 foreach ($this->errors as $error) {
  514.                     $ret .= $error.'<br />';
  515.                 }
  516.             }
  517.             return $ret;
  518.         }
  519.     }
  520. }
  521. ?>