[ Index ]

PHP Cross Reference of phpwcms V1.5.0 _r431 (28.01.12)

title

Body

[close]

/include/inc_lib/ -> functions.file.inc.php (source)

   1  <?php
   2  /*************************************************************************************
   3     Copyright notice
   4     
   5     (c) 2002-2012 Oliver Georgi <oliver@phpwcms.de> // All rights reserved.
   6   
   7     This script is part of PHPWCMS. The PHPWCMS web content management system is
   8     free software; you can redistribute it and/or modify it under the terms of
   9     the GNU General Public License as published by the Free Software Foundation;
  10     either version 2 of the License, or (at your option) any later version.
  11    
  12     The GNU General Public License can be found at http://www.gnu.org/copyleft/gpl.html
  13     A copy is found in the textfile GPL.txt and important notices to the license 
  14     from the author is found in LICENSE.txt distributed with these scripts.
  15    
  16     This script is distributed in the hope that it will be useful, but WITHOUT ANY 
  17     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  18     PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  19   
  20     This copyright notice MUST APPEAR in all copies of the script!
  21  *************************************************************************************/
  22  
  23  // ----------------------------------------------------------------
  24  // obligate check for phpwcms constants
  25  if (!defined('PHPWCMS_ROOT')) {
  26     die("You Cannot Access This Script Directly, Have a Nice Day.");
  27  }
  28  // ----------------------------------------------------------------
  29  
  30  
  31  function _getFileInfo($value, $limit='1', $mode='hash') {
  32  
  33      $sql = '';
  34  
  35      switch($mode) {
  36  
  37          case 'hash':    $sql  = "SELECT * FROM ".DB_PREPEND."phpwcms_file WHERE f_aktiv=1 AND ";
  38                          $sql .= "f_trash=0 AND f_public=1 AND ";
  39                          $sql .= "f_hash='".aporeplace($value)."'";
  40                          if( !FEUSER_LOGIN_STATUS ) {
  41                              $sql .= ' AND f_granted=0';
  42                          }
  43                          if($limit) {
  44                              $sql .= " LIMIT ".$limit;
  45                          }
  46                          break;
  47      }
  48  
  49      return _dbQuery($sql);
  50      
  51  }
  52  
  53  function dl_file_resume($file='', $fileinfo=array(), $onsuccess = false) {
  54  
  55      // function based on this one here:
  56      // http://www.php.net/manual/de/function.fread.php#63893
  57  
  58      //First, see if the file exists
  59      if (!is_file($file) && connection_status()) return false;
  60      
  61      //Gather relevent info about file
  62      $filename         = empty($fileinfo['realfname'])    ? basename($file) : $fileinfo['realfname'];
  63      $disposition    = empty($fileinfo['method'])    ? 'attachment' : $fileinfo['method'];
  64      
  65      if($disposition == 'attachment') {
  66      
  67          $fileinfo['mimetype'] = "application/force-download";
  68      
  69      }
  70      
  71      if(empty($fileinfo['mimetype']) && empty($fileinfo['extension'])) {
  72      
  73          $file_extension    = strtolower(substr(strrchr($filename,"."),1));
  74          $ctype            = isset($GLOBALS['phpwcms']['mime_types'][$file_extension]) ? $GLOBALS['phpwcms']['mime_types'][$file_extension] : 'application/force-download';
  75      
  76      } else {
  77      
  78          $ctype             = $fileinfo['mimetype'];
  79          $file_extension    = $fileinfo['extension'];
  80      
  81      }
  82  
  83      //Begin writing headers
  84      header('Cache-Control: ');
  85      header('Cache-Control: public');
  86      header('Pragma: ');
  87      
  88      //Use the switch-generated Content-Type
  89      header('Content-Type: '.$ctype);
  90      
  91      
  92      if (isset($_SERVER['HTTP_USER_AGENT']) && strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) {
  93          // workaround for IE filename bug with multiple periods / multiple dots in filename
  94          // that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe
  95          $filename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1);
  96      }
  97      
  98      
  99      //header('Accept-Ranges: bytes');
 100      
 101      $size = filesize($file);
 102  
 103      
 104      header('Content-Length: '.$size);
 105      header('Content-Transfer-Encoding: binary'.LF);
 106      header('Content-Disposition: '.$disposition.'; filename="'.$filename.'"');
 107      
 108  
 109      //reset time limit for big files
 110      @set_time_limit(0);
 111  
 112      //open the file
 113      $fp = fopen($file, 'rb');
 114  
 115      //seek to start of missing part
 116      //fseek($fp, $range);
 117  
 118      //start buffered download
 119      while(!feof($fp) && !connection_status()){
 120      
 121          print(fread($fp, 1024*8));
 122          flush();
 123          //ob_flush();
 124      }
 125      fclose($fp);
 126  
 127      return ($onsuccess && !connection_status() && !connection_aborted()) ? true : false;
 128  }
 129  
 130  // http://www.thomthom.net/blog/2007/09/php-resumable-download-server/
 131  function rangeDownload($file) {
 132   
 133      $fp = @fopen($file, 'rb');
 134   
 135      $size   = filesize($file); // File size
 136      $length = $size;           // Content length
 137      $start  = 0;               // Start byte
 138      $end    = $size - 1;       // End byte
 139      // Now that we've gotten so far without errors we send the accept range header
 140      /* At the moment we only support single ranges.
 141       * Multiple ranges requires some more work to ensure it works correctly
 142       * and comply with the spesifications: http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
 143       *
 144       * Multirange support annouces itself with:
 145       * header('Accept-Ranges: bytes');
 146       *
 147       * Multirange content must be sent with multipart/byteranges mediatype,
 148       * (mediatype = mimetype)
 149       * as well as a boundry header to indicate the various chunks of data.
 150       */
 151      header("Accept-Ranges: 0-$length");
 152      // header('Accept-Ranges: bytes');
 153      // multipart/byteranges
 154      // http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.2
 155      if (isset($_SERVER['HTTP_RANGE'])) {
 156   
 157          $c_start = $start;
 158          $c_end   = $end;
 159          // Extract the range string
 160          list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
 161          // Make sure the client hasn't sent us a multibyte range
 162          if (strpos($range, ',') !== false) {
 163   
 164              // (?) Shoud this be issued here, or should the first
 165              // range be used? Or should the header be ignored and
 166              // we output the whole content?
 167              header('HTTP/1.1 416 Requested Range Not Satisfiable');
 168              header("Content-Range: bytes $start-$end/$size");
 169              // (?) Echo some info to the client?
 170              exit;
 171          }
 172          // If the range starts with an '-' we start from the beginning
 173          // If not, we forward the file pointer
 174          // And make sure to get the end byte if spesified
 175          if ($range0 == '-') {
 176   
 177              // The n-number of the last bytes is requested
 178              $c_start = $size - substr($range, 1);
 179          }
 180          else {
 181   
 182              $range  = explode('-', $range);
 183              $c_start = $range[0];
 184              $c_end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
 185          }
 186          /* Check the range and make sure it's treated according to the specs.
 187           * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
 188           */
 189          // End bytes can not be larger than $end.
 190          $c_end = ($c_end > $end) ? $end : $c_end;
 191          // Validate the requested range and return an error if it's not correct.
 192          if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
 193   
 194              header('HTTP/1.1 416 Requested Range Not Satisfiable');
 195              header("Content-Range: bytes $start-$end/$size");
 196              // (?) Echo some info to the client?
 197              exit;
 198          }
 199          $start  = $c_start;
 200          $end    = $c_end;
 201          $length = $end - $start + 1; // Calculate new content length
 202          fseek($fp, $start);
 203          header('HTTP/1.1 206 Partial Content');
 204      }
 205      // Notify the client the byte range we'll be outputting
 206      header("Content-Range: bytes $start-$end/$size");
 207      header("Content-Length: $length");
 208   
 209      // Start buffered download
 210      $buffer = 1024 * 8;
 211      while(!feof($fp) && ($p = ftell($fp)) <= $end) {
 212   
 213          if ($p + $buffer > $end) {
 214   
 215              // In case we're only outputtin a chunk, make sure we don't
 216              // read past the length
 217              $buffer = $end - $p + 1;
 218          }
 219          set_time_limit(0); // Reset time limit for big files
 220          echo fread($fp, $buffer);
 221          flush(); // Free up memory. Otherwise large files will trigger PHP's memory limit.
 222      }
 223   
 224      fclose($fp);
 225   
 226  }
 227  
 228  
 229  
 230  ?>


Generated: Sun Jan 29 16:31:14 2012 Cross-referenced by PHPXref 0.7.1