home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / phpMyAdmin / libraries / File.class.php < prev    next >
Encoding:
PHP Script  |  2008-06-23  |  25.7 KB  |  881 lines

  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4.  * file upload functions
  5.  *
  6.  * @version $Id: File.class.php 11205 2008-04-22 11:26:24Z nijel $
  7.  */
  8.  
  9. /**
  10.  *
  11.  * @todo replace error messages with localized string
  12.  * @todo when uploading a file into a blob field, should we also consider using
  13.  *       chunks like in import? UPDATE `table` SET `field` = `field` + [chunk]
  14.  */
  15. class PMA_File
  16. {
  17.     /**
  18.      * @var string the temporary file name
  19.      * @access protected
  20.      */
  21.     var $_name = null;
  22.  
  23.     /**
  24.      * @var string the content
  25.      * @access protected
  26.      */
  27.     var $_content = null;
  28.  
  29.     /**
  30.      * @var string the error message
  31.      * @access protected
  32.      */
  33.     var $_error_message = '';
  34.  
  35.     /**
  36.      * @var bool whether the file is temporary or not
  37.      * @access protected
  38.      */
  39.     var $_is_temp = false;
  40.  
  41.     /**
  42.      * @var string type of compression
  43.      * @access protected
  44.      */
  45.     var $_compression = null;
  46.  
  47.     /**
  48.      * @var integer
  49.      */
  50.     var $_offset = 0;
  51.  
  52.     /**
  53.      * @var integer size of chunk to read with every step
  54.      */
  55.     var $_chunk_size = 32768;
  56.  
  57.     /**
  58.      * @var resource file handle
  59.      */
  60.     var $_handle = null;
  61.  
  62.     /**
  63.      * @var boolean whether to decompress content before returning
  64.      */
  65.     var $_decompress = false;
  66.  
  67.     /**
  68.      * @var string charset of file
  69.      */
  70.     var $_charset = null;
  71.  
  72.     /**
  73.      * old PHP 4 style constructor
  74.      *
  75.      * @see     PMA_File::__construct()
  76.      * @uses    PMA_File::__construct()
  77.      * @access  public
  78.      */
  79.     function PMA_File($name = false)
  80.     {
  81.         $this->__construct($name);
  82.     }
  83.  
  84.     /**
  85.      * constructor
  86.      *
  87.      * @access  public
  88.      * @uses    PMA_File::setName()
  89.      * @param   string  $name   file name
  90.      */
  91.     function __construct($name = false)
  92.     {
  93.         if ($name) {
  94.             $this->setName($name);
  95.         }
  96.     }
  97.  
  98.     /**
  99.      * destructor
  100.      *
  101.      * @see     PMA_File::cleanUp()
  102.      * @access  public
  103.      * @uses    PMA_File::cleanUp()
  104.      */
  105.     function __destruct()
  106.     {
  107.         $this->cleanUp();
  108.     }
  109.  
  110.     /**
  111.      * deletes file if it is temporary, usally from a moved upload file
  112.      *
  113.      * @access  public
  114.      * @uses    PMA_File::delet()
  115.      * @uses    PMA_File::isTemp()
  116.      * @return  boolean success
  117.      */
  118.     function cleanUp()
  119.     {
  120.         if ($this->isTemp()) {
  121.             return $this->delete();
  122.         }
  123.  
  124.         return true;
  125.     }
  126.  
  127.     /**
  128.      * deletes the file
  129.      *
  130.      * @access  public
  131.      * @uses    PMA_File::getName()
  132.      * @uses    unlink()
  133.      * @return  boolean success
  134.      */
  135.     function delete()
  136.     {
  137.         return unlink($this->getName());
  138.     }
  139.  
  140.     /**
  141.      * checks or sets the temp flag for this file
  142.      * file objects with temp flags are deleted with object destruction
  143.      *
  144.      * @access  public
  145.      * @uses    PMA_File::$_is_temp to set and read it
  146.      * @param   boolean sets the temp flag
  147.      * @return  boolean PMA_File::$_is_temp
  148.      */
  149.     function isTemp($is_temp = null)
  150.     {
  151.         if (null !== $is_temp) {
  152.             $this->_is_temp = (bool) $is_temp;
  153.         }
  154.  
  155.         return $this->_is_temp;
  156.     }
  157.  
  158.     /**
  159.      * accessor
  160.      *
  161.      * @access  public
  162.      * @uses    PMA_File::$_name
  163.      * @param   string  $name   file name
  164.      * @access  public
  165.      */
  166.     function setName($name)
  167.     {
  168.         $this->_name = trim($name);
  169.     }
  170.  
  171.     /**
  172.      * @access  public
  173.      * @uses    PMA_File::getName()
  174.      * @uses    PMA_File::isUploaded()
  175.      * @uses    PMA_File::checkUploadedFile()
  176.      * @uses    PMA_File::isReadable()
  177.      * @uses    PMA_File::$_content
  178.      * @uses    function_exists()
  179.      * @uses    file_get_contents()
  180.      * @uses    filesize()
  181.      * @uses    fread()
  182.      * @uses    fopen()
  183.      * @uses    bin2hex()
  184.      * @return  string  binary file content
  185.      */
  186.     function getContent($as_binary = true, $offset = 0, $length = null)
  187.     {
  188.         if (null === $this->_content) {
  189.             if ($this->isUploaded() && ! $this->checkUploadedFile()) {
  190.                 return false;
  191.             }
  192.  
  193.             if (! $this->isReadable()) {
  194.                 return false;
  195.             }
  196.  
  197.             if (function_exists('file_get_contents')) {
  198.                 $this->_content = file_get_contents($this->getName());
  199.             } elseif ($size = filesize($this->getName())) {
  200.                 $this->_content = fread(fopen($this->getName(), 'rb'), $size);
  201.             }
  202.         }
  203.  
  204.         if (! empty($this->_content) && $as_binary) {
  205.             return '0x' . bin2hex($this->_content);
  206.         }
  207.  
  208.         if (null !== $length) {
  209.             return substr($this->_content, $offset, $length);
  210.         } elseif ($offset > 0) {
  211.             return substr($this->_content, $offset);
  212.         }
  213.  
  214.         return $this->_content;
  215.     }
  216.  
  217.     /**
  218.      * @access  public
  219.      * @uses    PMA_File::getName()
  220.      * @uses    is_uploaded_file()
  221.      */
  222.     function isUploaded()
  223.     {
  224.         return is_uploaded_file($this->getName());
  225.     }
  226.  
  227.     /**
  228.      * accessor
  229.      *
  230.      * @access  public
  231.      * @uses    PMA_File::$name as return value
  232.      * @return  string  PMA_File::$_name
  233.      */
  234.     function getName()
  235.     {
  236.         return $this->_name;
  237.     }
  238.  
  239.     /**
  240.      * @todo replace error message with localized string
  241.      * @access  public
  242.      * @uses    PMA_File::isUploaded()
  243.      * @uses    PMA_File::setName()
  244.      * @uses    PMA_File::$_error_message
  245.      * @param   string  name of file uploaded
  246.      * @return  boolean success
  247.      */
  248.     function setUploadedFile($name)
  249.     {
  250.         $this->setName($name);
  251.  
  252.         if (! $this->isUploaded()) {
  253.             $this->setName(null);
  254.             $this->_error_message = 'not an uploaded file';
  255.             return false;
  256.         }
  257.  
  258.         return true;
  259.     }
  260.  
  261.     /**
  262.      * @access  public
  263.      * @uses    PMA_File::fetchUploadedFromTblChangeRequestMultiple()
  264.      * @uses    PMA_File::setUploadedFile()
  265.      * @uses    PMA_File::$_error_message
  266.      * @uses    $GLOBALS['strUploadErrorIniSize']
  267.      * @uses    $GLOBALS['strUploadErrorFormSize']
  268.      * @uses    $GLOBALS['strUploadErrorPartial']
  269.      * @uses    $GLOBALS['strUploadErrorNoTempDir']
  270.      * @uses    $GLOBALS['strUploadErrorCantWrite']
  271.      * @uses    $GLOBALS['strUploadErrorExtension']
  272.      * @uses    $GLOBALS['strUploadErrorUnknown']
  273.      * @uses    $_FILES
  274.      * @param   string  $key    a numeric key used to identify the different rows
  275.      * @param   string  $primary_key
  276.      * @return  boolean success
  277.      */
  278.     function setUploadedFromTblChangeRequest($key, $primary = null)
  279.     {
  280.         if (! isset($_FILES['fields_upload_' . $key])) {
  281.             return false;
  282.         }
  283.  
  284.         $file = $_FILES['fields_upload_' . $key];
  285.         if (null !== $primary) {
  286.             $file = PMA_File::fetchUploadedFromTblChangeRequestMultiple($file, $primary);
  287.         }
  288.  
  289.         // check for file upload errors
  290.         switch ($file['error']) {
  291.             // cybot_tm: we do not use the PHP constants here cause not all constants
  292.             // are defined in all versions of PHP - but the correct constants names
  293.             // are given as comment
  294.             case 0: //UPLOAD_ERR_OK:
  295.                 return $this->setUploadedFile($file['tmp_name']);
  296.                 break;
  297.             case 4: //UPLOAD_ERR_NO_FILE:
  298.                 break;
  299.             case 1: //UPLOAD_ERR_INI_SIZE:
  300.                 $this->_error_message = $GLOBALS['strUploadErrorIniSize'];
  301.                 break;
  302.             case 2: //UPLOAD_ERR_FORM_SIZE:
  303.                 $this->_error_message = $GLOBALS['strUploadErrorFormSize'];
  304.                 break;
  305.             case 3: //UPLOAD_ERR_PARTIAL:
  306.                 $this->_error_message = $GLOBALS['strUploadErrorPartial'];
  307.                 break;
  308.             case 6: //UPLOAD_ERR_NO_TMP_DIR:
  309.                 $this->_error_message = $GLOBALS['strUploadErrorNoTempDir'];
  310.                 break;
  311.             case 7: //UPLOAD_ERR_CANT_WRITE:
  312.                 $this->_error_message = $GLOBALS['strUploadErrorCantWrite'];
  313.                 break;
  314.             case 8: //UPLOAD_ERR_EXTENSION:
  315.                 $this->_error_message = $GLOBALS['strUploadErrorExtension'];
  316.                 break;
  317.             default:
  318.                 $this->_error_message = $GLOBALS['strUploadErrorUnknown'];
  319.         } // end switch
  320.  
  321.         return false;
  322.     }
  323.  
  324.     /**
  325.      * strips some dimension from the multi-dimensional array from $_FILES
  326.      *
  327.      * <code>
  328.      * $file['name']['multi_edit'][$primary] = [value]
  329.      * $file['type']['multi_edit'][$primary] = [value]
  330.      * $file['size']['multi_edit'][$primary] = [value]
  331.      * $file['tmp_name']['multi_edit'][$primary] = [value]
  332.      * $file['error']['multi_edit'][$primary] = [value]
  333.      *
  334.      * // becomes:
  335.      *
  336.      * $file['name'] = [value]
  337.      * $file['type'] = [value]
  338.      * $file['size'] = [value]
  339.      * $file['tmp_name'] = [value]
  340.      * $file['error'] = [value]
  341.      * </code>
  342.      *
  343.      * @todo re-check if requirements changes to PHP >= 4.2.0
  344.      * @access  public
  345.      * @static
  346.      * @param   array   $file       the array
  347.      * @param   string  $primary
  348.      * @return  array
  349.      */
  350.     function fetchUploadedFromTblChangeRequestMultiple($file, $primary)
  351.     {
  352.         $new_file = array(
  353.             'name' => $file['name']['multi_edit'][$primary],
  354.             'type' => $file['type']['multi_edit'][$primary],
  355.             'size' => $file['size']['multi_edit'][$primary],
  356.             'tmp_name' => $file['tmp_name']['multi_edit'][$primary],
  357.             //'error' => $file['error']['multi_edit'][$primary],
  358.         );
  359.  
  360.         // ['error'] exists since PHP 4.2.0
  361.         if (isset($file['error'])) {
  362.             $new_file['error'] = $file['error']['multi_edit'][$primary];
  363.         }
  364.  
  365.         return $new_file;
  366.     }
  367.  
  368.     /**
  369.      * sets the name if the file to the one selected in the tbl_change form
  370.      *
  371.      * @access  public
  372.      * @uses    $_REQUEST
  373.      * @uses    PMA_File::setLocalSelectedFile()
  374.      * @uses    is_string()
  375.      * @param   string  $key    a numeric key used to identify the different rows
  376.      * @param   string  $primary_key
  377.      * @return  boolean success
  378.      */
  379.     function setSelectedFromTblChangeRequest($key, $primary = null)
  380.     {
  381.         if (null !== $primary) {
  382.             if (! empty($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary])
  383.              && is_string($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary])) {
  384.                 // ... whether with multiple rows ...
  385.                 return $this->setLocalSelectedFile($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary]);
  386.             } else {
  387.                 return false;
  388.             }
  389.         } elseif (! empty($_REQUEST['fields_uploadlocal_' . $key])
  390.          && is_string($_REQUEST['fields_uploadlocal_' . $key])) {
  391.             return $this->setLocalSelectedFile($_REQUEST['fields_uploadlocal_' . $key]);
  392.         }
  393.  
  394.          return false;
  395.     }
  396.  
  397.     /**
  398.      * @access  public
  399.      * @uses    PMA_File->$_error_message as return value
  400.      * @return  string  error message
  401.      */
  402.     function getError()
  403.     {
  404.         return $this->_error_message;
  405.     }
  406.  
  407.     /**
  408.      * @access  public
  409.      * @uses    PMA_File->$_error_message to check it
  410.      * @return  boolean whether an error occured or not
  411.      */
  412.     function isError()
  413.     {
  414.         return ! empty($this->_error_message);
  415.     }
  416.  
  417.     /**
  418.      * checks the superglobals provided if the tbl_change form is submitted
  419.      * and uses the submitted/selected file
  420.      *
  421.      * @access  public
  422.      * @uses    PMA_File::setUploadedFromTblChangeRequest()
  423.      * @uses    PMA_File::setSelectedFromTblChangeRequest()
  424.      * @param   string  $key    a numeric key used to identify the different rows
  425.      * @param   string  $primary_key
  426.      * @return  boolean success
  427.      */
  428.     function checkTblChangeForm($key, $primary_key)
  429.     {
  430.         if ($this->setUploadedFromTblChangeRequest($key, $primary_key)) {
  431.             // well done ...
  432.             $this->_error_message = '';
  433.             return true;
  434. /*
  435.         } elseif ($this->setUploadedFromTblChangeRequest($key)) {
  436.             // well done ...
  437.             $this->_error_message = '';
  438.             return true;
  439. */
  440.         } elseif ($this->setSelectedFromTblChangeRequest($key, $primary_key)) {
  441.             // well done ...
  442.             $this->_error_message = '';
  443.             return true;
  444. /*
  445.         } elseif ($this->setSelectedFromTblChangeRequest($key)) {
  446.             // well done ...
  447.             $this->_error_message = '';
  448.             return true;
  449. */
  450.         }
  451.         // all failed, whether just no file uploaded/selected or an error
  452.  
  453.         return false;
  454.     }
  455.  
  456.     /**
  457.      *
  458.      * @access  public
  459.      * @uses    $GLOBALS['strFileCouldNotBeRead']
  460.      * @uses    PMA_File::setName()
  461.      * @uses    PMA_securePath()
  462.      * @uses    PMA_userDir()
  463.      * @uses    $GLOBALS['cfg']['UploadDir']
  464.      * @param   string  $name
  465.      * @return  boolean success
  466.      */
  467.     function setLocalSelectedFile($name)
  468.     {
  469.         if (empty($GLOBALS['cfg']['UploadDir'])) return false;
  470.  
  471.         $this->setName(PMA_userDir($GLOBALS['cfg']['UploadDir']) . PMA_securePath($name));
  472.         if (! $this->isReadable()) {
  473.             $this->_error_message = $GLOBALS['strFileCouldNotBeRead'];
  474.             $this->setName(null);
  475.             return false;
  476.         }
  477.  
  478.         return true;
  479.     }
  480.  
  481.     /**
  482.      * @access  public
  483.      * @uses    PMA_File::getName()
  484.      * @uses    is_readable()
  485.      * @uses    ob_start()
  486.      * @uses    ob_end_clean()
  487.      * @return  boolean whether the file is readable or not
  488.      */
  489.     function isReadable()
  490.     {
  491.         // surpress warnings from beeing displayed, but not from beeing logged
  492.         // any file access outside of open_basedir will issue a warning
  493.         ob_start();
  494.         $is_readable = is_readable($this->getName());
  495.         ob_end_clean();
  496.         return $is_readable;
  497.     }
  498.  
  499.     /**
  500.      * If we are on a server with open_basedir, we must move the file
  501.      * before opening it. The FAQ 1.11 explains how to create the "./tmp"
  502.      * directory - if needed
  503.      *
  504.      * @todo replace error message with localized string
  505.      * @todo move check of $cfg['TempDir'] into PMA_Config?
  506.      * @access  public
  507.      * @uses    $cfg['TempDir']
  508.      * @uses    $GLOBALS['strFieldInsertFromFileTempDirNotExists']
  509.      * @uses    PMA_File::isReadable()
  510.      * @uses    PMA_File::getName()
  511.      * @uses    PMA_File::setName()
  512.      * @uses    PMA_File::isTemp()
  513.      * @uses    PMA_File::$_error_message
  514.      * @uses    is_dir()
  515.      * @uses    mkdir()
  516.      * @uses    chmod()
  517.      * @uses    is_writable()
  518.      * @uses    basename()
  519.      * @uses    move_uploaded_file()
  520.      * @uses    ob_start()
  521.      * @uses    ob_end_clean()
  522.      * @return  boolean whether uploaded fiel is fine or not
  523.      */
  524.     function checkUploadedFile()
  525.     {
  526.         if ($this->isReadable()) {
  527.             return true;
  528.         }
  529.  
  530.         /**
  531.          * it is not important if open_basedir is set - we just cannot read the file
  532.          * so we try to move it
  533.         if ('' != ini_get('open_basedir')) {
  534.          */
  535.  
  536.         // check tmp dir config
  537.         if (empty($GLOBALS['cfg']['TempDir'])) {
  538.             $GLOBALS['cfg']['TempDir'] = 'tmp/';
  539.         }
  540.  
  541.         // surpress warnings from beeing displayed, but not from beeing logged
  542.         ob_start();
  543.         // check tmp dir
  544.         if (! is_dir($GLOBALS['cfg']['TempDir'])) {
  545.             // try to create the tmp directory
  546.             if (@mkdir($GLOBALS['cfg']['TempDir'], 0777)) {
  547.                 chmod($GLOBALS['cfg']['TempDir'], 0777);
  548.             } else {
  549.                 // create tmp dir failed
  550.                 $this->_error_message = $GLOBALS['strFieldInsertFromFileTempDirNotExists'];
  551.                 ob_end_clean();
  552.                 return false;
  553.             }
  554.         }
  555.         ob_end_clean();
  556.  
  557.         if (! is_writable($GLOBALS['cfg']['TempDir'])) {
  558.             // cannot create directory or access, point user to FAQ 1.11
  559.             $this->_error_message = $GLOBALS['strFieldInsertFromFileTempDirNotExists'];
  560.             return false;
  561.         }
  562.  
  563.         $new_file_to_upload = $GLOBALS['cfg']['TempDir'] . '/' . basename($this->getName());
  564.  
  565.         // surpress warnings from beeing displayed, but not from beeing logged
  566.         // any file access outside of open_basedir will issue a warning
  567.         ob_start();
  568.         $move_uploaded_file_result = move_uploaded_file($this->getName(), $new_file_to_upload);
  569.         ob_end_clean();
  570.         if (! $move_uploaded_file_result) {
  571.             $this->_error_message = 'error while moving uploaded file';
  572.             return false;
  573.         }
  574.  
  575.         $this->setName($new_file_to_upload);
  576.         $this->isTemp(true);
  577.  
  578.         if (! $this->isReadable()) {
  579.             $this->_error_message = 'cannot read (moved) upload file';
  580.             return false;
  581.         }
  582.  
  583.         return true;
  584.     }
  585.  
  586.     /**
  587.      * Detects what compression filse uses
  588.      *
  589.      * @todo    move file read part into readChunk() or getChunk()
  590.      * @todo    add support for compression plugins
  591.      * @uses    $GLOBALS['strFileCouldNotBeRead']
  592.      * @uses    PMA_File::$_compression to set it
  593.      * @uses    PMA_File::getName()
  594.      * @uses    fopen()
  595.      * @uses    fread()
  596.      * @uses    strlen()
  597.      * @uses    fclose()
  598.      * @uses    chr()
  599.      * @uses    substr()
  600.      * @access  protected
  601.      * @return  string MIME type of compression, none for none
  602.      */
  603.     function _detectCompression()
  604.     {
  605.         // surpress warnings from beeing displayed, but not from beeing logged
  606.         // f.e. any file access outside of open_basedir will issue a warning
  607.         ob_start();
  608.         $file = fopen($this->getName(), 'rb');
  609.         ob_end_clean();
  610.  
  611.         if (! $file) {
  612.             $this->_error_message = $GLOBALS['strFileCouldNotBeRead'];
  613.             return false;
  614.         }
  615.  
  616.         /**
  617.          * @todo
  618.          * get registered plugins for file compression
  619.  
  620.         foreach (PMA_getPlugins($type = 'compression') as $plugin) {
  621.             if (call_user_func_array(array($plugin['classname'], 'canHandle'), array($this->getName()))) {
  622.                 $this->setCompressionPlugin($plugin);
  623.                 break;
  624.             }
  625.         }
  626.          */
  627.  
  628.         $test = fread($file, 4);
  629.         $len = strlen($test);
  630.         fclose($file);
  631.  
  632.         if ($len >= 2 && $test[0] == chr(31) && $test[1] == chr(139)) {
  633.             $this->_compression = 'application/gzip';
  634.         } elseif ($len >= 3 && substr($test, 0, 3) == 'BZh') {
  635.             $this->_compression = 'application/bzip2';
  636.         } elseif ($len >= 4 && $test == "PK\003\004") {
  637.             $this->_compression = 'application/zip';
  638.         } else {
  639.             $this->_compression = 'none';
  640.         }
  641.  
  642.         return $this->_compression;
  643.     }
  644.  
  645.     /**
  646.      * whether the content should be decompressed before returned
  647.      */
  648.     function setDecompressContent($decompress)
  649.     {
  650.         $this->_decompress = (bool) $decompress;
  651.     }
  652.  
  653.     function getHandle()
  654.     {
  655.         if (null === $this->_handle) {
  656.             $this->open();
  657.         }
  658.         return $this->_handle;
  659.     }
  660.  
  661.     function setHandle($handle)
  662.     {
  663.         $this->_handle = $handle;
  664.     }
  665.  
  666.     /**
  667.      *
  668.      */
  669.     function open()
  670.     {
  671.         if (! $this->_decompress) {
  672.             $this->_handle = @fopen($this->getName(), 'r');
  673.         }
  674.  
  675.         switch ($this->getCompression()) {
  676.             case false:
  677.                 return false;
  678.             case 'application/bzip2':
  679.                 if ($GLOBALS['cfg']['BZipDump'] && @function_exists('bzopen')) {
  680.                     $this->_handle = @bzopen($this->getName(), 'r');
  681.                 } else {
  682.                     $this->_error_message = sprintf($GLOBALS['strUnsupportedCompressionDetected'], $this->getCompression());
  683.                     return false;
  684.                 }
  685.                 break;
  686.             case 'application/gzip':
  687.                 if ($GLOBALS['cfg']['GZipDump'] && @function_exists('gzopen')) {
  688.                     $this->_handle = @gzopen($this->getName(), 'r');
  689.                 } else {
  690.                     $this->_error_message = sprintf($GLOBALS['strUnsupportedCompressionDetected'], $this->getCompression());
  691.                     return false;
  692.                 }
  693.                 break;
  694.             case 'application/zip':
  695.                 if ($GLOBALS['cfg']['GZipDump'] && @function_exists('gzinflate')) {
  696.                     include_once './libraries/unzip.lib.php';
  697.                     $this->_handle = new SimpleUnzip();
  698.                     $this->_handle->ReadFile($this->getName());
  699.                     if ($this->_handle->Count() == 0) {
  700.                         $this->_error_message = $GLOBALS['strNoFilesFoundInZip'];
  701.                         return false;
  702.                     } elseif ($this->_handle->GetError(0) != 0) {
  703.                         $this->_error_message = $GLOBALS['strErrorInZipFile'] . ' ' . $this->_handle->GetErrorMsg(0);
  704.                         return false;
  705.                     } else {
  706.                         $this->content_uncompressed = $this->_handle->GetData(0);
  707.                     }
  708.                     // We don't need to store it further
  709.                     $this->_handle = null;
  710.                 } else {
  711.                     $this->_error_message = sprintf($GLOBALS['strUnsupportedCompressionDetected'], $this->getCompression());
  712.                     return false;
  713.                 }
  714.                 break;
  715.             case 'none':
  716.                 $this->_handle = @fopen($this->getName(), 'r');
  717.                 break;
  718.             default:
  719.                 $this->_error_message = sprintf($GLOBALS['strUnsupportedCompressionDetected'], $this->getCompression());
  720.                 return false;
  721.                 break;
  722.         }
  723.  
  724.  
  725.     }
  726.  
  727.     function getCharset()
  728.     {
  729.         return $this->_charset;
  730.     }
  731.  
  732.     function setCharset($charset)
  733.     {
  734.         $this->_charset = $charset;
  735.     }
  736.  
  737.     /**
  738.      * @uses    PMA_File::$_compression as return value
  739.      * @uses    PMA_File::detectCompression()
  740.      * @return  string MIME type of compression, none for none
  741.      * @access  public
  742.      */
  743.     function getCompression()
  744.     {
  745.         if (null === $this->_compression) {
  746.             return $this->_detectCompression();
  747.         }
  748.  
  749.         return $this->_compression;
  750.     }
  751.  
  752.     /**
  753.      * advances the file pointer in the file handle by $length bytes/chars
  754.      *
  755.      * @param   integer $length numbers of chars/bytes to skip
  756.      * @return  boolean
  757.      */
  758.     function advanceFilePointer($length)
  759.     {
  760.         while ($length > 0) {
  761.             // Disable read progresivity, otherwise we eat all memory!
  762.             $read_multiply = 1; // required?
  763.             $this->getNextChunk($length);
  764.             $length -= $this->getChunkSize();
  765.         }
  766.     }
  767.  
  768.     /**
  769.      * http://bugs.php.net/bug.php?id=29532
  770.      * bzip reads a maximum of 8192 bytes on windows systems
  771.      *
  772.      */
  773.     function getNextChunk($max_size = null)
  774.     {
  775.         if (null !== $max_size) {
  776.             $size = min($max_size, $this->getChunkSize());
  777.         } else {
  778.             $size = $this->getChunkSize();
  779.         }
  780.  
  781.         // $result = $this->handler->getNextChunk($size);
  782.         $result = '';
  783.         switch ($this->getCompression()) {
  784.             case 'application/bzip2':
  785.                 $result = '';
  786.                 while (strlen($result) < $size - 8192 && ! feof($this->getHandle())) {
  787.                     $result .= bzread($this->getHandle(), $size);
  788.                 }
  789.                 break;
  790.             case 'application/gzip':
  791.                 $result = gzread($this->getHandle(), $size);
  792.                 break;
  793.             case 'application/zip':
  794.                 include_once './libraries/unzip.lib.php';
  795.                 $import_handle = new SimpleUnzip();
  796.                 $import_handle->ReadFile($this->getName());
  797.                 if ($import_handle->Count() == 0) {
  798.                     $this->_error_message = $GLOBALS['strNoFilesFoundInZip'];
  799.                     return false;
  800.                 } elseif ($import_handle->GetError(0) != 0) {
  801.                     $this->_error_message = $GLOBALS['strErrorInZipFile']
  802.                         . ' ' . $import_handle->GetErrorMsg(0);
  803.                     return false;
  804.                 } else {
  805.                     $result = $import_handle->GetData(0);
  806.                 }
  807.                 break;
  808.             case 'none':
  809.                 $result = fread($this->getHandle(), $size);
  810.                 break;
  811.             default:
  812.                 return false;
  813.         }
  814.  
  815.         echo $size . ' - ';
  816.         echo strlen($result) . ' - ';
  817.         echo (@$GLOBALS['__len__'] += strlen($result)) . ' - ';
  818.         echo $this->_error_message;
  819.         echo '<hr />';
  820.  
  821.         if ($GLOBALS['charset_conversion']) {
  822.             $result = PMA_convert_string($this->getCharset(), $GLOBALS['charset'], $result);
  823.         } else {
  824.             /**
  825.              * Skip possible byte order marks (I do not think we need more
  826.              * charsets, but feel free to add more, you can use wikipedia for
  827.              * reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
  828.              *
  829.              * @todo BOM could be used for charset autodetection
  830.              */
  831.             if ($this->getOffset() === 0) {
  832.                 // UTF-8
  833.                 if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
  834.                     $result = substr($result, 3);
  835.                 // UTF-16 BE, LE
  836.                 } elseif (strncmp($result, "\xFE\xFF", 2) == 0
  837.                  || strncmp($result, "\xFF\xFE", 2) == 0) {
  838.                     $result = substr($result, 2);
  839.                 }
  840.             }
  841.         }
  842.  
  843.         $this->_offset += $size;
  844.         if (0 === $result) {
  845.             return true;
  846.         }
  847.         return $result;
  848.     }
  849.  
  850.     function getOffset()
  851.     {
  852.         return $this->_offset;
  853.     }
  854.  
  855.     function getChunkSize()
  856.     {
  857.         return $this->_chunk_size;
  858.     }
  859.  
  860.     function setChunkSize($chunk_size)
  861.     {
  862.         $this->_chunk_size = (int) $chunk_size;
  863.     }
  864.  
  865.     function getContentLength()
  866.     {
  867.         return strlen($this->_content);
  868.     }
  869.  
  870.     function eof()
  871.     {
  872.         if ($this->getHandle()) {
  873.             return feof($this->getHandle());
  874.         } else {
  875.             return ($this->getOffset() >= $this->getContentLength());
  876.         }
  877.  
  878.     }
  879. }
  880. ?>
  881.