[ Index ]
 

Code source de GeekLog 1.4.1

Accédez au Source d'autres logiciels libres

title

Body

[fermer]

/system/classes/ -> upload.class.php (source)

   1  <?php
   2  
   3  /* Reminder: always indent with 4 spaces (no tabs). */
   4  // +---------------------------------------------------------------------------+
   5  // | Geeklog 1.4                                                               |
   6  // +---------------------------------------------------------------------------+
   7  // | upload.class.php                                                          |
   8  // |                                                                           |
   9  // | Geeklog file upload class library.                                        |
  10  // +---------------------------------------------------------------------------+
  11  // | Copyright (C) 2002-2006 by the following authors:                         |
  12  // |                                                                           |
  13  // | Authors: Tony Bibbs       - tony@tonybibbs.com                            |
  14  // |          Dirk Haun        - dirk@haun-online.de                           |
  15  // +---------------------------------------------------------------------------+
  16  // |                                                                           |
  17  // | This program is free software; you can redistribute it and/or             |
  18  // | modify it under the terms of the GNU General Public License               |
  19  // | as published by the Free Software Foundation; either version 2            |
  20  // | of the License, or (at your option) any later version.                    |
  21  // |                                                                           |
  22  // | This program is distributed in the hope that it will be useful,           |
  23  // | but WITHOUT ANY WARRANTY; without even the implied warranty of            |
  24  // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             |
  25  // | GNU General Public License for more details.                              |
  26  // |                                                                           |
  27  // | You should have received a copy of the GNU General Public License         |
  28  // | along with this program; if not, write to the Free Software Foundation,   |
  29  // | Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.           |
  30  // |                                                                           |
  31  // +---------------------------------------------------------------------------+
  32  //
  33  // $Id: upload.class.php,v 1.47 2006/09/09 12:52:06 dhaun Exp $
  34  
  35  /**
  36  * This class will allow you to securely upload one or more files from a form
  37  * submitted via POST method.  Please read documentation as there are a number of
  38  * security related features that will come in handy for you.
  39  *
  40  * @author       Tony Bibbs <tony@tonybibbs.com>
  41  *
  42  */
  43  class upload
  44  {
  45      /**
  46      * @access private
  47      */
  48      var $_errors = array();               // Array
  49      /**
  50      * @access private
  51      */
  52      var $_warnings = array();             // Array
  53      /**
  54      * @access private
  55      */
  56      var $_debugMessages = array();        // Array
  57      /**
  58      * @access private
  59      */
  60      var $_allowedMimeTypes = array();     // Array
  61      /**
  62      * @access private
  63      */
  64      var $_availableMimeTypes = array();   // Array
  65      /**
  66      * @access private
  67      */
  68      var $_filesToUpload = array();        // Array
  69      /**
  70      * @access private
  71      */
  72      var $_currentFile = array();          // Array
  73      /**
  74      * @access private
  75      */
  76      var $_allowedIPS = array();           // Array
  77      /**
  78      * @access private
  79      */
  80      var $_uploadedFiles = array();        // Array
  81      /**
  82      * @access private
  83      */
  84      var $_maxImageWidth = 300;            // Pixels
  85      /**
  86      * @access private
  87      */
  88      var $_maxImageHeight = 300;           // Pixels
  89      /**
  90      * @access private
  91      */
  92      var $_maxFileSize = 1048576;          // Long, in bytes
  93      /**
  94      * @access private
  95      */
  96      var $_pathToMogrify = '';             // String
  97      /**
  98      * @access private
  99      */
 100      var $_pathToNetPBM= '';               // String
 101      /**
 102      * @access private
 103      */
 104      var $_imageLib = '';                 // Integer
 105      /**
 106      * @access private
 107      */
 108      var $_autoResize = false;             // boolean
 109      /**
 110      * @access private
 111      */
 112      var $_keepOriginalImage = false;      // boolean
 113      /**
 114      * @access private
 115      */
 116      var $_maxFileUploadsPerForm = 5;
 117      /**
 118      * @access private
 119      */
 120      var $_fileUploadDirectory = '';       // String
 121      /**
 122      * @access private
 123      */
 124      var $_fileNames = '';                 // String
 125      /**
 126      * @access private
 127      */
 128      var $_permissions = '';               // String
 129      /**
 130      * @access private
 131      */
 132      var $_logFile = '';                   // String
 133      /**
 134      * @access private
 135      */
 136      var $_doLogging = false;              // Boolean
 137      /**
 138      * @access private
 139      */
 140      var $_continueOnError = false;        // Boolean
 141      /**
 142      * @access private
 143      */
 144      var $_debug = false;                  // Boolean
 145      /**
 146      * @access private
 147      */
 148      var $_limitByIP = false;              // Boolean
 149      /**
 150      * @access private
 151      */
 152      var $_numSuccessfulUploads = 0;       // Integer
 153      /**
 154      * @access private
 155      */
 156      var $_imageIndex = 0;                 // Integer
 157  
 158      /**
 159      * @access private
 160      */
 161      var $_wasResized = false;             // Boolean
 162  
 163  
 164      /**
 165      * Constructor
 166      *
 167      */
 168      function upload()
 169      {
 170          $this->_setAvailableMimeTypes();
 171      }
 172  
 173      // PRIVATE METHODS
 174  
 175      /**
 176      * Adds a warning that was encountered
 177      *
 178      * @access   private
 179      * @param    string  $warningText     Text of warning
 180      *
 181      */
 182      function _addWarning($warningText)
 183      {
 184          $nwarnings = count($this->_warnings);
 185          $nwarnings = $nwarnings + 1;
 186          $this->_warnings[$nwarnings] = $warningText;
 187          if ($this->loggingEnabled()) {
 188              $this->_logItem('Warning',$warningText);
 189          }
 190      }
 191  
 192      /**
 193      * Adds an error that was encountered
 194      *
 195      * @access   private
 196      * @param    string      $errorText      Text of error
 197      *
 198      */
 199      function _addError($errorText)
 200      {
 201          $nerrors = count($this->_errors);
 202          $nerrors = $nerrors + 1;
 203          $this->_errors[$nerrors] = $errorText;
 204          if ($this->loggingEnabled()) {
 205              $this->_logItem('Error',$errorText);
 206          }
 207      }
 208  
 209      /**
 210      * Adds a debug message
 211      *
 212      * @access   private
 213      * @param        string      $debugText      Text of debug message
 214      *
 215      */
 216      function _addDebugMsg($debugText)
 217      {
 218          $nmsgs = count($this->_debugMessages);
 219          $nmsgs = $nmsgs + 1;
 220          $this->_debugMessages[$nmsgs] = $debugText;
 221          if ($this->loggingEnabled()) {
 222              $this->_logItem('Debug',$debugText);
 223          }
 224      }
 225  
 226      /**
 227      * Logs an item to the log file
 228      *
 229      * @access   private
 230      * @param    string      $logtype    can be 'warning' or 'error'
 231      * @param    string      $text       Text to log to log file
 232      * @return   boolean     Whether or not we successfully logged an item
 233      *
 234      */
 235      function _logItem($logtype, $text)
 236      {
 237          $timestamp = strftime("%c");
 238          if (!$file = fopen($this->_logFile, 'a')) {
 239              // couldn't open log file for writing so let's disable logging and add an error
 240              $this->setLogging(false);
 241              $this->_addError('Error writing to log file: ' . $this->_logFile . '.  Logging has been disabled');
 242              return false;
 243          }
 244          fputs ($file, "$timestamp - $logtype: $text \n");
 245          fclose($file);
 246          return true;
 247      }
 248  
 249      /**
 250      * Defines superset of available Mime types.
 251      *
 252      * @access   private
 253      * @param    array   $mimeTypes  string array of valid mime types this object will accept
 254      *
 255      */
 256      function _setAvailableMimeTypes($mimeTypes = array())
 257      {
 258          if (sizeof($mimeTypes) == 0) {
 259              $this->_availableMimeTypes =
 260              array(
 261                  'application/x-gzip-compressed'     => '.tar.gz,.tgz',
 262                  'application/x-zip-compressed'         => '.zip',
 263                  'application/x-tar'                    => '.tar',
 264                  'text/plain'                        => '.phps,.txt,.inc',
 265                  'text/html'                            => '.html,.htm',
 266                  'image/bmp'                         => '.bmp,.ico',
 267                  'image/gif'                         => '.gif',
 268                  'image/pjpeg'                        => '.jpg,.jpeg',
 269                  'image/jpeg'                        => '.jpg,.jpeg',
 270                  'image/png'                            => '.png',
 271                  'image/x-png'                        => '.png',
 272                  'audio/mpeg'                        => '.mp3',
 273                  'audio/wav'                            => '.wav',
 274                  'application/pdf'                    => '.pdf',
 275                  'application/x-shockwave-flash'     => '.swf',
 276                  'application/msword'                => '.doc',
 277                  'application/vnd.ms-excel'            => '.xls',
 278                  'application/octet-stream'            => '.fla,.psd'
 279              );
 280          } else {
 281              $this->_availableMimeTypes = $mimeTypes;
 282          }
 283      }
 284  
 285      /**
 286      * Checks if current file is an image
 287      *
 288      * @access private
 289      * @return boolean   returns true if file is an image, otherwise false
 290      */
 291      function _isImage()
 292      {
 293          if (strpos ($this->_currentFile['type'], 'image/') === 0) {
 294              $isImage = true;
 295          } else {
 296              $isImage = false;
 297          }
 298          if ($this->_debug) {
 299              $msg = 'File, ' . $this->_currentFile['name'] . ' is of mime type '
 300                  . $this->_currentFile['type'];
 301              if (!$isImage) {
 302                  $msg .= ' and is NOT an image file.';
 303              } else {
 304                  $msg .= ' and IS an image file.';
 305              }
 306              $this->_addDebugMsg($msg);
 307          }
 308  
 309          return $isImage;
 310      }
 311  
 312      /**
 313      * Verifies the file size meets specified size limitations
 314      *
 315      * @access private
 316      * @return boolean   returns true of file size is within our limits otherwise false
 317      */
 318      function _fileSizeOk()
 319      {
 320          if ($this->_debug) {
 321              $this->_addDebugMsg('File size for ' . $this->_currentFile['name'] . ' is ' . $this->_currentFile['size'] . ' bytes');
 322          }
 323  
 324          if ($this->_currentFile['size'] > $this->_maxFileSize) {
 325              return false;
 326          } else {
 327              return true;
 328          }
 329      }
 330  
 331      /**
 332      * Checks to see if file is an image and, if so, whether or not
 333      * it meets width and height limitations
 334      *
 335      * @access   private
 336      * @return   boolean     returns true if image height/width meet our limitations otherwise false
 337      *
 338      */
 339      function _imageSizeOK($doResizeCheck=true)
 340      {
 341          if (!$this->_isImage()) {
 342              return true;
 343          }
 344  
 345          $imageInfo = $this->_getImageDimensions($this->_currentFile['tmp_name']);
 346  
 347          $sizeOK = true;
 348  
 349          if ($this->_debug) {
 350              $this->_addDebugMsg('Max allowed width = ' . $this->_maxImageWidth . ', Image width = ' . $imageInfo['width']);
 351              $this->_addDebugMsg('Max allowed height = ' . $this->_maxImageHeight . ', Image height = ' . $imageInfo['height']);
 352          }
 353  
 354          // If user set _autoResize then ignore these settings and try to resize on upload
 355          if (($doResizeCheck AND !($this->_autoResize)) OR (!($doResizeCheck))) {
 356              if ($imageInfo['width'] > $this->_maxImageWidth) {
 357                  $sizeOK = false;
 358                  if ($doResizeCheck) {
 359                      $this->_addError('Image, ' . $this->_currentFile['name'] . ' does not meet width limitations (is: ' . $imageInfo['width'] . ', max: ' . $this->_maxImageWidth . ')');
 360                  }
 361              }
 362  
 363              if ($imageInfo['height'] > $this->_maxImageHeight) {
 364                  $sizeOK = false;
 365                  if ($doResizeCheck) {
 366                      $this->_addError('Image, ' . $this->_currentFile['name'] . ' does not meet height limitations (is: ' . $imageInfo['height'] . ', max: ' . $this->_maxImageHeight . ')');
 367                  }
 368              }
 369          }
 370  
 371          if ($this->_debug) {
 372              $this->_addDebugMsg('File, ' . $this->_currentFile['name'] . ' has a width of '
 373                  . $imageInfo['width'] . ' and a height of ' . $imageInfo['height']);
 374          }
 375  
 376          return $sizeOK;
 377      }
 378  
 379      /**
 380      * Gets the width and height of an image
 381      *
 382      * @access private
 383      * @return array     Array with width and height of current image
 384      */
 385      function _getImageDimensions()
 386      {
 387          $dimensions = GetImageSize($this->_currentFile['tmp_name']);
 388          if ($this->_debug) {
 389              $this->_addDebugMsg('in _getImageDimensions I got a width of ' . $dimensions[0] . ', and a height of ' . $dimensions[1]);
 390          }
 391          return array('width' => $dimensions[0], 'height' => $dimensions[1]);
 392      }
 393  
 394      /**
 395      * Calculate the factor to scale images with if they're not meeting
 396      * the size restrictions.
 397      *
 398      * @access   private
 399      * @param    int     $width      width of the unscaled image
 400      * @param    int     $height     height of the unscaled image
 401      * @return   double              resize factor
 402      *
 403      */
 404      function _calcSizefactor ($width, $height)
 405      {
 406          if (($width > $this->_maxImageWidth) ||
 407                  ($height > $this->_maxImageHeight)) {
 408              if (($width > $this->_maxImageWidth) && ($width > $height)) {
 409                  $sizefactor = (double) ($this->_maxImageWidth / $width);
 410              } else {
 411                  $sizefactor = (double) ($this->_maxImageHeight / $height);
 412              }
 413          } else {
 414              $sizefactor = 1.0;
 415          }
 416  
 417          return $sizefactor;
 418      }
 419  
 420      /**
 421      * Keep the original (unscaled) image file, if configured.
 422      *
 423      * @access   private
 424      * @param    string  $filename   name of uploaded file
 425      * @return   bool                true: okay, false: an error occured
 426      *
 427      */
 428      function _keepOriginalFile ($filename)
 429      {
 430          if ($this->_keepOriginalImage) {
 431              $lFilename_large = substr_replace ($this->_getDestinationName (),
 432                  '_original.', strrpos ($this->_getDestinationName (), '.'), 1);
 433              $lFilename_large_complete = $this->_fileUploadDirectory . '/'
 434                                        .  $lFilename_large;
 435              if (!copy ($filename, $lFilename_large_complete)) {
 436                  $this->_addError ("Couldn't copy $filename to $lFilename_large_complete.  You'll need to remove both files.");
 437                  $this->printErrors ();
 438  
 439                  return false;
 440              }
 441          }
 442  
 443          return true;
 444      }
 445  
 446      /**
 447      * Gets destination file name for current file
 448      *
 449      * @access private
 450      * @return string    returns destination file name
 451      *
 452      */
 453      function _getDestinationName()
 454      {
 455          if (is_array($this->_fileNames)) {
 456              $name = $this->_fileNames[$this->_imageIndex];
 457          }
 458  
 459          if (empty($name)) {
 460              $name = $this->_currentFile['name'];
 461          }
 462  
 463          return $name;
 464      }
 465  
 466      /**
 467      * Gets permissions for a file.  This is used to do a chmod
 468      *
 469      * @access   private
 470      * @return   string  returns final permisisons for current file
 471      *
 472      */
 473      function _getPermissions()
 474      {
 475          if (is_array($this->_permissions)) {
 476              if (count($this->_permissions) > 1) {
 477                  $perms = $this->_permissions[$this->_imageIndex];
 478              } else {
 479                  $perms = $this->_permissions[0];
 480              }
 481          }
 482  
 483          if (empty($perms)) {
 484              $perms = '';
 485          }
 486  
 487          return $perms;
 488      }
 489  
 490      /**
 491      * This function actually completes the upload of a file
 492      *
 493      * @access   private
 494      * @return   boolean     true if copy succeeds otherwise false
 495      *
 496      */
 497      function _copyFile()
 498      {
 499          if (!is_writable($this->_fileUploadDirectory)) {
 500              // Developer didn't check return value of setPath() method which would
 501              // have told them the upload directory was not writable.  Error out now
 502              $this->_addError('Specified upload directory, ' . $this->_fileUploadDirectory . ' exists but is not writable');
 503              return false;
 504          }
 505          $sizeOK = true;
 506          if (!($this->_imageSizeOK(false)) AND $this->_autoResize) {
 507              $imageInfo = $this->_getImageDimensions($this->_currentFile['tmp_name']);
 508              if ($imageInfo['width'] > $this->_maxImageWidth) {
 509                  $sizeOK = false;
 510              }
 511  
 512              if ($imageInfo['height'] > $this->_maxImageHeight) {
 513                  $sizeOK = false;
 514              }
 515          }
 516          $returnMove = move_uploaded_file($this->_currentFile['tmp_name'], $this->_fileUploadDirectory . '/' . $this->_getDestinationName());
 517          if (!($sizeOK)) {
 518              // OK, resize
 519              $sizefactor = $this->_calcSizefactor ($imageInfo['width'],
 520                                                    $imageInfo['height']);
 521              $newwidth = (int) ($imageInfo['width'] * $sizefactor);
 522              $newheight = (int) ($imageInfo['height'] * $sizefactor);
 523              $this->_addDebugMsg ('Going to resize image to ' . $newwidth . 'x'
 524                                   . $newheight . ' using ' . $this->_imageLib);
 525  
 526              if ($this->_imageLib == 'imagemagick') {
 527                  $newsize = $newwidth . 'x' . $newheight;
 528                  $cmd = $this->_pathToMogrify . ' -resize '. $newsize . ' "' . $this->_fileUploadDirectory . '/' . $this->_getDestinationName() . '" 2>&1';
 529                  $this->_addDebugMsg('Attempting to resize with this command (imagemagick): ' . $cmd);
 530  
 531                  $filename = $this->_fileUploadDirectory . '/'
 532                              . $this->_getDestinationName ();
 533                  if (!$this->_keepOriginalFile ($filename)) {
 534                      exit;
 535                  }
 536  
 537                  exec($cmd, $mogrify_output, $retval);
 538  
 539              } elseif ($this->_imageLib == 'netpbm') {
 540  
 541                  $cmd = $this->_pathToNetPBM;
 542                  $filename = $this->_fileUploadDirectory . '/' . $this->_getDestinationName();
 543                  $cmd_end = " '" . $filename . "' | " . $this->_pathToNetPBM . 'pnmscale -xsize=' . $newwidth . ' -ysize=' . $newheight . ' | ' . $this->_pathToNetPBM;
 544                  // convert to pnm, resize, convert back
 545                  if (eregi ('\.png', $filename)) {
 546                      $tmpfile = $this->_fileUploadDirectory . '/tmp.png';
 547                      $cmd .= 'pngtopnm ' . $cmd_end . 'pnmtopng > ' . $tmpfile;
 548                  } else if (eregi ('\.(jpg|jpeg)', $filename)) {
 549                      $tmpfile = $this->_fileUploadDirectory . '/tmp.jpg';
 550                      $cmd .= 'jpegtopnm ' . $cmd_end . 'pnmtojpeg > ' . $tmpfile;
 551                  }  else if (eregi ('\.gif', $filename)) {
 552                      $tmpfile = $this->_fileUploadDirectory . '/tmp.gif';
 553                      $cmd .= 'giftopnm ' . $cmd_end . 'ppmquant 256 | '
 554                           . $this->_pathToNetPBM . 'ppmtogif > ' . $tmpfile;
 555                  } else {
 556                      $this->_addError ("Image format of file $filename is not supported.");
 557                      $this->printErrors ();
 558                      exit;
 559                  }
 560                  $this->_addDebugMsg('Attempting to resize with this command (netpbm): ' . $cmd);
 561                  exec($cmd, $netpbm_output, $retval);
 562  
 563                  if (!$this->_keepOriginalFile ($filename)) {
 564                      exit;
 565                  }
 566  
 567                  // Move tmp file to actual file
 568                  if (!copy($tmpfile,$filename)) {
 569                      $this->_addError("Couldn't copy $tmpfile to $filename.  You'll need remove both files");
 570                      $this->printErrors();
 571                      exit;
 572                  } else {
 573                      // resize with netpbm worked, now remove tmpfile
 574                      if (!unlink($tmpfile)) {
 575                          $this->_addError("Couldn't delete $tmpfile.  You'll need to remove it manually");
 576                          $this->printErrors();
 577                          exit;
 578                      }
 579                  }
 580  
 581              } elseif ($this->_imageLib == 'gdlib') {
 582  
 583                  $filename = $this->_fileUploadDirectory . '/'
 584                            . $this->_getDestinationName();
 585  
 586                  if (!$this->_keepOriginalFile ($filename)) {
 587                      exit;
 588                  }
 589  
 590                  if (($this->_currentFile['type'] == 'image/png') OR
 591                      ($this->_currentFile['type'] == 'image/x-png')) {
 592                      if (!function_exists ('imagecreatefrompng')) {
 593                          $this->_addError ('Sorry, this version of the GD library does not support PNG images.');
 594                          $this->printErrors ();
 595                          exit;
 596                      }
 597                      if (!$image_source = imagecreatefrompng ($filename)) {
 598                          $this->_addError ('Could not create image from PNG: '
 599                                            . $filename);
 600                          $this->printErrors ();
 601                          exit;
 602                      }
 603                  } elseif (($this->_currentFile['type'] == 'image/jpeg') OR
 604                            ($this->_currentFile['type'] == 'image/pjpeg')) {
 605                      if (!function_exists ('imagecreatefromjpeg')) {
 606                          $this->_addError ('Sorry, this version of the GD library does not support JPEG images.');
 607                          $this->printErrors ();
 608                          exit;
 609                      }
 610                      if (!$image_source = imagecreatefromjpeg ($filename)) {
 611                          $this->_addError ('Could not create image from JPEG: '
 612                                            . $filename);
 613                          $this->printErrors ();
 614                          exit;
 615                      }
 616                  } elseif ($this->_currentFile['type'] == 'image/gif') {
 617                      if (!function_exists ('imagecreatefromgif')) {
 618                          $this->_addError ('Sorry, this version of the GD library does not support GIF images.');
 619                          $this->printErrors ();
 620                          exit;
 621                      }
 622                      if (!$image_source = imagecreatefromgif ($filename)) {
 623                          $this->_addError ('Could not create image from GIF: '
 624                                            . $filename);
 625                          $this->printErrors ();
 626                          exit;
 627                      }
 628                  } else {
 629                      $this->_addError ('MIME type ' . $this->_currentFile['type']
 630                                        . ' not supported.');
 631                      $this->printErrors ();
 632                      exit;
 633                  }
 634  
 635                  // do resize
 636                  $sizefactor = $this->_calcSizefactor ($imageInfo['width'],
 637                                                        $imageInfo['height']);
 638                  $this->_addDebugMsg ('Resizing image, factor=' . $sizefactor);
 639                  $newwidth = (int) ($imageInfo['width'] * $sizefactor);
 640                  $newheight = (int) ($imageInfo['height'] * $sizefactor);
 641                  $newsize = $newwidth . 'x' . $newheight;
 642  
 643                  // ImageCreateTrueColor may throw a fatal error on some PHP
 644                  // versions when GD2 is not installed. Ugly workaround, but
 645                  // there seems to be no better way. Also see the discussion at
 646                  // http://php.net/ImageCreateTrueColor
 647                  $image_dest = @ImageCreateTrueColor($newwidth, $newheight);
 648                  if (!$image_dest) {
 649                      $thumb = imagecreate ($newwidth, $newheight);
 650                      imageJPEG ($thumb, $filename);
 651                      imagedestroy ($thumb);
 652                      $image_dest = @imagecreatefromjpeg ($filename);
 653                      unlink ($filename);
 654                  }
 655  
 656                  imagecopyresized ($image_dest, $image_source, 0, 0, 0, 0,
 657                                    $newwidth, $newheight, $imageInfo['width'],
 658                                    $imageInfo['height']);
 659                  if (($this->_currentFile['type'] == 'image/png') OR
 660                      ($this->_currentFile['type'] == 'image/x-png')) {
 661                      if (!imagepng ($image_dest, $filename)) {
 662                          $this->_addError ('Could not create PNG: ' . $filename);
 663                          $this->printErrors ();
 664                          exit;
 665                      }
 666                  } elseif (($this->_currentFile['type'] == 'image/jpeg') OR
 667                            ($this->_currentFile['type'] == 'image/pjpeg')) {
 668                      if (!imagejpeg ($image_dest, $filename)) {
 669                          $this->_addError ('Could not create JPEG: '. $filename);
 670                          $this->printErrors ();
 671                          exit;
 672                      }
 673                  } elseif ($this->_currentFile['type'] == 'image/gif') {
 674                      if (!imagegif ($image_dest, $filename)) {
 675                          $this->_addError ('Could not create GIF: ' . $filename);
 676                          $this->printErrors ();
 677                          exit;
 678                      }
 679                  }
 680              }
 681  
 682              if ($retval > 0) {
 683                  if ($this->_imageLib == 'imagemagick') {
 684                      $this->_addError ('Image, ' . $this->_currentFile['name']
 685                          . ' had trouble being resized: ' . $mogrify_output[0]);
 686                  } elseif ($this->_imageLib == 'netpbm') {
 687                      $this->_addError ('Image, ' . $this->_currentFile['name']
 688                          . ' had trouble being resized: ' . $netpbm_output[0]);
 689                  }
 690                  $this->printErrors();
 691                  exit;
 692              } else {
 693                  $this->_addDebugMsg ('Image, ' . $this->_currentFile['name'] . ' was resized from ' . $imageInfo['width'] . 'x' . $imageInfo['height'] . ' to ' . $newsize);
 694              }
 695          }
 696          $returnChmod = true;
 697          $perms = $this->_getPermissions();
 698          if (!empty($perms)) {
 699              $returnChmod = chmod ($this->_fileUploadDirectory . '/' . $this->_getDestinationName (), octdec ($perms));
 700          }
 701  
 702          if ($returnMove AND $returnChmod) {
 703              return true;
 704          } else {
 705              if (!$returnMove) {
 706                  $this->_addError('Upload of ' . $this->_currentFile['name'] . ' failed.');
 707              }
 708  
 709              if (!$returnChmod) {
 710                  $this->_addError('Chmod of ' . $this->_currentFile['name'] . ' to ' . $perms . ' failed');
 711              }
 712  
 713              return false;
 714          }
 715      }
 716  
 717      /**
 718      * Sets the path to where the mogrify ImageMagic function is
 719      *
 720      * @param     string    $path_to_mogrify    Absolute path to mogrify
 721      * @return    boolean   True if set, false otherwise
 722      *
 723      */
 724      function setMogrifyPath($path_to_mogrify)
 725      {
 726          $this->_imageLib = 'imagemagick';
 727          $this->_pathToMogrify = $path_to_mogrify;
 728          return true;
 729      }
 730  
 731      /**
 732      * Sets the path to where the netpbm utilities are
 733      *
 734      * @param     string    $path_to_netpbm    Absolute path to netpbm dir
 735      * @return    boolean   True if set, false otherwise
 736      *
 737      */
 738      function setNetPBM($path_to_netpbm)
 739      {
 740          $this->_imageLib = 'netpbm';
 741          $this->_pathToNetPBM = $path_to_netpbm;
 742          return true;
 743      }
 744  
 745      /**
 746      * Configure upload to use GD library
 747      *
 748      * @return    boolean   True if set, false otherwise
 749      *
 750      */
 751      function setGDLib()
 752      {
 753          $this->_imageLib = 'gdlib';
 754          return true;
 755      }
 756  
 757      /**
 758      * Sets mode to automatically resize images that are either too wide or
 759      * too tall
 760      *
 761      * @param    boolean    $switch  True to turn on, false to turn off
 762      *
 763      */
 764      function setAutomaticResize($switch)
 765      {
 766          $this->_autoResize = $switch;
 767      }
 768  
 769      /**
 770      * Allows you to override default max file size
 771      *
 772      * @param    int     $size_in_bytes      Max. size for uploaded files
 773      * @return   boolean true if we set it OK, otherwise false
 774      *
 775      */
 776      function setMaxFileSize($size_in_bytes)
 777      {
 778          if (!is_numeric($size_in_bytes)) {
 779              return false;
 780          }
 781          $this->_maxFileSize = $size_in_bytes;
 782          return true;
 783      }
 784  
 785      /**
 786      * Allows you to override default max. image dimensions
 787      *
 788      * @param    int    $width_pixels    Max. width allowed
 789      * @param    int    $height_pixels   Max. height allowed
 790      * @return   boolean true if we set values OK, otherwise false
 791      *
 792      */
 793      function setMaxDimensions($width_pixels, $height_pixels)
 794      {
 795          if (!is_numeric($width_pixels) AND !is_numeric($height_pixels)) {
 796              return false;
 797          }
 798  
 799          $this->_maxImageWidth = $width_pixels;
 800          $this->_maxImageHeight = $height_pixels;
 801  
 802          return true;
 803      }
 804  
 805      /**
 806      * Sets the max number of files that can be uploaded per form
 807      *
 808      * @param     int       $maxfiles    Maximum number of files to allow. Default is 5
 809      * @return    boolean   True if set, false otherwise
 810      *
 811      */
 812      function setMaxFileUploads($maxfiles)
 813      {
 814          $this->_maxFileUploadsPerForm = $maxfiles;
 815          return true;
 816      }
 817  
 818      /**
 819      * Allows you to keep the original (unscaled) image.
 820      *
 821      * @param    boolean   $keepit   true = keep original, false = don't
 822      * @return   boolean   true if we set values OK, otherwise false
 823      *
 824      */
 825      function keepOriginalImage ($keepit)
 826      {
 827          $this->_keepOriginalImage = $keepit;
 828  
 829          return true;
 830      }
 831  
 832      /**
 833      * Extra security option that forces all attempts to upload a file to be done
 834      * so from a set of VERY specific IP's.  This is only good for those who are
 835      * paranoid
 836      *
 837      * @param    array   $validIPS   Array of valid IP addresses to allow file uploads from
 838      * @return   boolean returns true if we successfully limited the IP's, otherwise false
 839      */
 840      function limitByIP($validIPS = array('127.0.0.1'))
 841      {
 842          if (is_array($validIPS)) {
 843              $this->_limitByIP = true;
 844              $this->_allowedIPS = $validIPS;
 845              return true;
 846          } else {
 847              $this->_addError('Bad call to method limitByIP(), must pass array of valid IP addresses');
 848              return false;
 849          }
 850      }
 851  
 852      /**
 853      * Allows you to specify whether or not to continue processing other files
 854      * when an error occurs or exit immediately. Default is to exit immediately
 855      *
 856      * NOTE: this only affects the actual file upload process.
 857      *
 858      * @param    boolean     $switch     true or false
 859      *
 860      */
 861      function setContinueOnError($switch)
 862      {
 863          if ($switch) {
 864              $this->_continueOnError = true;
 865          } else {
 866              $this->_continueOnError = false;
 867          }
 868      }
 869  
 870      /**
 871      * Sets log file
 872      *
 873      * @param    string  $fileName   fully qualified path to log files
 874      * @return   boolean returns true if we set the log file, otherwise false
 875      *
 876      */
 877      function setLogFile($logFile = '')
 878      {
 879          if (empty($logFile) OR !file_exists($logFile)) {
 880              // Log file doesn't exist, produce warning
 881              $this->_addWarning('Log file, ' . $logFile . ' does not exists, setLogFile() method failed');
 882              $this->_doLogging = false;
 883              return false;
 884          }
 885          $this->_logFile = $logFile;
 886          return true;
 887      }
 888  
 889      /**
 890      * Enables/disables logging of errors and warnings
 891      *
 892      * @param    boolean     $switch     flag, true or false
 893      *
 894      */
 895      function setLogging($switch)
 896      {
 897          if ($switch AND !empty($this->_logFile)) {
 898              $this->_doLogging = true;
 899          } else {
 900              if ($switch AND empty($this->_logFile)) {
 901                  $this->_addWarning('Unable to enable logging because no log file was set.  Use setLogFile() method');
 902              }
 903              $this->_doLogging = false;
 904          }
 905      }
 906  
 907      /**
 908      * Returns whether or not logging is enabled
 909      *
 910      * @return   boolean returns true if logging is enabled otherwise false
 911      *
 912      */
 913      function loggingEnabled()
 914      {
 915          return $this->_doLogging;
 916      }
 917  
 918      /**
 919      * Will force the debug messages in this class to be
 920      * printed
 921      *
 922      * @param    boolean     $switch     flag, true or false
 923      *
 924      */
 925      function setDebug($switch)
 926      {
 927          if ($switch) {
 928              $this->_debug = true;
 929              // setting debugs implies logging is on too
 930              $this->setLogging(true);
 931          } else {
 932              $this->_debug = false;
 933          }
 934      }
 935  
 936      /**
 937      * This function will print any errors out.  This is useful in debugging
 938      *
 939      * @param    boolean     $verbose    whether or not to print immediately or return only a string
 940      * @return   string  if $verbose is false it returns all errors otherwise just an empty string
 941      *
 942      */
 943      function printErrors($verbose=true)
 944      {
 945          if (isset($this->_errors) AND is_array($this->_errors)) {
 946              $retval = '';
 947              reset($this->_errors);
 948              $nerrors = count($this->_errors);
 949              for ($i = 1; $i <= $nerrors; $i++) {
 950                  if ($verbose) {
 951                      print current($this->_errors) . "<BR>\n";
 952                  } else {
 953                      $retval .= current($this->_errors) . "<BR>\n";
 954                  }
 955                  next($this->_errors);
 956              }
 957              return $retval;
 958          }
 959      }
 960  
 961      /**
 962      * This function will print any warnings out.  This is useful in debugging
 963      *
 964      */
 965      function printWarnings()
 966      {
 967          if (isset($this->_warnings) AND is_array($this->_warnings)) {
 968              reset($this->_warnings);
 969              $nwarnings = count($this->_warnings);
 970              for ($i = 1; $i <= $nwarnings; $i++) {
 971                  print current($this->_warnings) . "<BR>\n";
 972                  next($this->_warnings);
 973              }
 974          }
 975      }
 976  
 977      /**
 978      * This function will print any debmug messages out.
 979      *
 980      */
 981      function printDebugMsgs()
 982      {
 983          if (isset($this->_debugMessages) AND is_array($this->_debugMessages)) {
 984              reset($this->_debugMessages);
 985              $nmsgs = count($this->_debugMessages);
 986              for ($i = 1; $i <= $nmsgs; $i++) {
 987                  print current($this->_debugMessages) . "<BR>\n";
 988                  next($this->_debugMessages);
 989              }
 990          }
 991      }
 992  
 993      /**
 994      * Returns if any errors have been encountered thus far
 995      *
 996      * @return   boolean returns true if there were errors otherwise false
 997      *
 998      */
 999      function areErrors()
1000      {
1001          if (count($this->_errors) > 0) {
1002              return true;
1003          } else {
1004              return false;
1005          }
1006      }
1007  
1008      /**
1009      * Sets allowed mime types for this instance
1010      *
1011      * @param    array   allowedMimeTypes        Array of allowed mime types
1012      *
1013      */
1014      function setAllowedMimeTypes($mimeTypes = array())
1015      {
1016          $this->_allowedMimeTypes = $mimeTypes;
1017      }
1018  
1019      /**
1020      * Gets allowed mime types for this instance
1021      *
1022      * @return   array   Returns array of allowed mime types
1023      *
1024      */
1025      function getAllowedMimeTypes()
1026      {
1027          return $this->_allowedMimeTypes;
1028      }
1029  
1030      /**
1031      * Checks to see that mime type for current file is allowed for upload
1032      *
1033      * @return   boolean     true if current file's mime type is allowed otherwise false
1034      *
1035      */
1036      function checkMimeType()
1037      {
1038          $sc = strpos ($this->_currentFile['type'], ';');
1039          if ($sc > 0) {
1040              $this->_currentFile['type'] = substr ($this->_currentFile['type'], 0, $sc);
1041          }
1042          $mimeTypes = $this->getAllowedMimeTypes ();
1043          foreach ($mimeTypes as $mimeT => $extList) {
1044              if ($mimeT == $this->_currentFile['type']) {
1045                  $extensions = explode (',', $extList);
1046                  $fileName = $this->_currentFile['name'];
1047                  foreach ($extensions as $ext) {
1048                      if (strcasecmp (substr ($fileName, -strlen ($ext)), $ext) == 0) {
1049                          return true;
1050                      }
1051                  }
1052              }
1053          }
1054          $this->_addError ('Mime type, ' . $this->_currentFile['type']
1055                            . ', or extension of ' . $this->_currentFile['name']
1056                            . ' not in list of allowed types.');
1057          return false;
1058      }
1059  
1060      /**
1061      * Sets file upload path
1062      *
1063      * @param    string  $uploadDir  Directory on server to store uploaded files
1064      * @return   boolean returns true if we successfully set path otherwise false
1065      *
1066      */
1067      function setPath($uploadDir)
1068      {
1069          if (!is_dir($uploadDir)) {
1070              $this->_addError('Specified upload directory, ' . $uploadDir . ' is not a valid directory');
1071              return false;
1072          }
1073  
1074          if (!is_writable($uploadDir)) {
1075              $this->_addError('Specified upload directory, ' . $uploadDir . ' exists but is not writable');
1076              return false;
1077          }
1078  
1079          $this->_fileUploadDirectory = $uploadDir;
1080  
1081          return true;
1082      }
1083  
1084      /**
1085      * Returns directory to upload to
1086      *
1087      * @return   string  returns path to file upload directory
1088      *
1089      */
1090      function getPath()
1091      {
1092          return $this->_fileUploadDirectory;
1093      }
1094  
1095      /**
1096      * Sets file name(s) for files
1097      *
1098      * This function will set the name of any files uploaded.  If the
1099      * number of file names sent doesn't match the number of uploaded
1100      * files a warning will be generated but processing will continue
1101      *
1102      * @param    string|array    $fileNames      A string or string array of file names
1103      *
1104      */
1105      function setFileNames($fileNames = 'geeklog_uploadedfile')
1106      {
1107          if (isset($fileNames) AND is_array($fileNames)) {
1108              // this is an array of file names, set them
1109              $this->_fileNames = $fileNames;
1110          } else {
1111              $this->_fileNames = array($fileNames);
1112          }
1113      }
1114  
1115      /**
1116      * Changes permissions for uploaded files.  If only one set of perms is
1117      * sent then they are applied to all uploaded files.  If more then one set
1118      * of perms is sent (i.e. $perms is an array) then permissions are applied
1119      * one by one.  Any files not having an associated permissions will be
1120      * left alone.  NOTE: this is meant to be called BEFORE you do the upload
1121      * and ideally is called right after setFileNames()
1122      *
1123      * @param    string|array    $perms      A string or string array of file permissions
1124      *
1125      */
1126      function setPerms($perms)
1127      {
1128          if (isset($perms) AND is_array($perms)) {
1129              // this is an array of file names, set them
1130              $this->_permissions = $perms;
1131          } else {
1132              $this->_permissions = array($perms);
1133          }
1134      }
1135  
1136      /**
1137      * Returns how many actual files were sent for upload.  NOTE: this will
1138      * ignore HTML file fields that were left blank.
1139      *
1140      * @return   int returns number of files were sent to be uploaded
1141      *
1142      */
1143      function numFiles()
1144      {
1145          if (empty($this->_filesToUpload)) {
1146              $this->_filesToUpload = $_FILES;
1147          }
1148  
1149          $fcount = 0;
1150  
1151          for ($i = 1; $i <= count($_FILES); $i++) {
1152              $curFile = current($this->_filesToUpload);
1153  
1154              // Make sure file field on HTML form wasn't empty
1155              if (!empty($curFile['name'])) {
1156                  $fcount++;
1157              }
1158              next($this->_filesToUpload);
1159          }
1160          reset($_FILES);
1161  
1162          return $fcount;
1163      }
1164  
1165      /**
1166      * Uploads any posted files.
1167      *
1168      * @return   boolean returns true if no errors were encountered otherwise false
1169      */
1170      function uploadFiles()
1171      {
1172          // Before we do anything, let's see if we are limiting file uploads by
1173          // IP address and, if so, verify the poster is originating from one of
1174          // those places
1175          if ($this->_limitByIP) {
1176              if (!in_array($_SERVER['REMOTE_ADDR'], $this->_allowedIPS)) {
1177                  $this->_addError('The IP, ' . $_SERVER['REMOTE_ADDR'] . ' is not in the list of '
1178                      . 'accepted IP addresses.  Refusing to allow file upload(s)');
1179                  return false;
1180              }
1181          }
1182  
1183          $this->_filesToUpload = $_FILES;
1184          $numFiles = count($this->_filesToUpload);
1185  
1186          // For security sake, check to make sure a DOS isn't happening by making
1187          // sure there is a limit of the number of files being uploaded
1188          if ($numFiles > $this->_maxFileUploadsPerForm) {
1189              $this->_addError('Max. number of files you can upload from a form is '
1190                  . $this->_maxFileUploadsPerForm . ' and you sent ' . $numFiles);
1191              return false;
1192          }
1193  
1194          // Verify upload directory is valid
1195          if (!$this->_fileUploadDirectory) {
1196              $this->_addError('No Upload Directory Specified, use setPath() method');
1197          }
1198  
1199          // Verify allowed mime types exist
1200          if (!$this->_allowedMimeTypes) {
1201              $this->_addError('No allowed mime types specified, use setAllowedMimeTypes() method');
1202          }
1203  
1204          for ($i = 1; $i <= $numFiles; $i++) {
1205  
1206              $this->_currentFile = current($_FILES);
1207  
1208              // Make sure file field on HTML form wasn't empty before proceeding
1209              if (!empty($this->_currentFile['name'])) {
1210                  // Verify file meets size limitations
1211                  if (!$this->_fileSizeOk()) {
1212                      $this->_addError('File, ' . $this->_currentFile['name'] . ', is bigger than the ' . $this->_maxFileSize . ' byte limit');
1213                  }
1214  
1215                  // If all systems check, do the upload
1216                  if ($this->checkMimeType() AND $this->_imageSizeOK() AND !$this->areErrors()) {
1217                      if ($this->_copyFile()) {
1218                          $this->_uploadedFiles[] = $this->_fileUploadDirectory . '/' . $this->_getDestinationName();
1219                      }
1220                  }
1221  
1222                  $this->_currentFile = array();
1223  
1224                  if ($this->areErrors() AND !$this->_continueOnError) {
1225                      return false;
1226                  }
1227  
1228                  $this->_imageIndex++;
1229              } else {
1230                  // No file name specified...send as warning.
1231                  $this->_addWarning('File #' . $i . ' on the HTML form was empty...ignoring it and continuing');
1232              }
1233              next($_FILES);
1234          }
1235  
1236          // This function returns false if any errors were encountered
1237          if ($this->areErrors()) {
1238              return false;
1239          } else {
1240              return true;
1241          }
1242      }
1243  }
1244  
1245  ?>


Généré le : Wed Nov 21 12:27:40 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics