Ticket #538: 538-jZipCreator.diff

File 538-jZipCreator.diff, 14.4 kB (added by Julien, 4 months ago)

patch based on a wrapper for a class from phpMyAdmin

  • build/manifests/jelix-lib.mn

    old new  
    703703! WSDLException.class.php 
    704704! WSDLStruct.class.php 
    705705! WSException.class.php 
     706 
     707cd lib/zip 
     708  zip.lib.php 
  • lib/zip/zip.lib.php

    old new  
     1<?php 
     2/** 
     3 * Zip file creation class. 
     4 * Makes zip files. 
     5 * 
     6 * Based on : 
     7 * 
     8 *  http://www.zend.com/codex.php?id=535&single=1 
     9 *  By Eric Mueller <eric@themepark.com> 
     10 * 
     11 *  http://www.zend.com/codex.php?id=470&single=1 
     12 *  by Denis125 <webmaster@atlant.ru> 
     13 * 
     14 *  a patch from Peter Listiak <mlady@users.sourceforge.net> for last modified 
     15 *  date and time of the compressed file 
     16 * 
     17 * Official ZIP file format: http://www.pkware.com/appnote.txt 
     18 * 
     19 * @access  public 
     20 */ 
     21class zipfile 
     22{ 
     23    /** 
     24     * Array to store compressed data 
     25     * 
     26     * @var  array    $datasec 
     27     */ 
     28    var $datasec      = array(); 
     29 
     30    /** 
     31     * Central directory 
     32     * 
     33     * @var  array    $ctrl_dir 
     34     */ 
     35    var $ctrl_dir     = array(); 
     36 
     37    /** 
     38     * End of central directory record 
     39     * 
     40     * @var  string   $eof_ctrl_dir 
     41     */ 
     42    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; 
     43 
     44    /** 
     45     * Last offset position 
     46     * 
     47     * @var  integer  $old_offset 
     48     */ 
     49    var $old_offset   = 0; 
     50 
     51 
     52    /** 
     53     * Converts an Unix timestamp to a four byte DOS date and time format (date 
     54     * in high two bytes, time in low two bytes allowing magnitude comparison). 
     55     * 
     56     * @param  integer  the current Unix timestamp 
     57     * 
     58     * @return integer  the current date in a four byte DOS format 
     59     * 
     60     * @access private 
     61     */ 
     62    function unix2DosTime($unixtime = 0) { 
     63        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime); 
     64 
     65        if ($timearray['year'] < 1980) { 
     66            $timearray['year']    = 1980; 
     67            $timearray['mon']     = 1; 
     68            $timearray['mday']    = 1; 
     69            $timearray['hours']   = 0; 
     70            $timearray['minutes'] = 0; 
     71            $timearray['seconds'] = 0; 
     72        } // end if 
     73 
     74        return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | 
     75                ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); 
     76    } // end of the 'unix2DosTime()' method 
     77 
     78 
     79    /** 
     80     * Adds "file" to archive 
     81     * 
     82     * @param  string   file contents 
     83     * @param  string   name of the file in the archive (may contains the path) 
     84     * @param  integer  the current timestamp 
     85     * 
     86     * @access public 
     87     */ 
     88    function addFile($data, $name, $time = 0) 
     89    { 
     90        $name     = str_replace('\\', '/', $name); 
     91 
     92        $dtime    = dechex($this->unix2DosTime($time)); 
     93        $hexdtime = '\x' . $dtime[6] . $dtime[7] 
     94                  . '\x' . $dtime[4] . $dtime[5] 
     95                  . '\x' . $dtime[2] . $dtime[3] 
     96                  . '\x' . $dtime[0] . $dtime[1]; 
     97        eval('$hexdtime = "' . $hexdtime . '";'); 
     98 
     99        $fr   = "\x50\x4b\x03\x04"; 
     100        $fr   .= "\x14\x00";            // ver needed to extract 
     101        $fr   .= "\x00\x00";            // gen purpose bit flag 
     102        $fr   .= "\x08\x00";            // compression method 
     103        $fr   .= $hexdtime;             // last mod time and date 
     104 
     105        // "local file header" segment 
     106        $unc_len = strlen($data); 
     107        $crc     = crc32($data); 
     108        $zdata   = gzcompress($data); 
     109        $zdata   = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug 
     110        $c_len   = strlen($zdata); 
     111        $fr      .= pack('V', $crc);             // crc32 
     112        $fr      .= pack('V', $c_len);           // compressed filesize 
     113        $fr      .= pack('V', $unc_len);         // uncompressed filesize 
     114        $fr      .= pack('v', strlen($name));    // length of filename 
     115        $fr      .= pack('v', 0);                // extra field length 
     116        $fr      .= $name; 
     117 
     118        // "file data" segment 
     119        $fr .= $zdata; 
     120 
     121        // "data descriptor" segment (optional but necessary if archive is not 
     122        // served as file) 
     123        // nijel(2004-10-19): this seems not to be needed at all and causes 
     124        // problems in some cases (bug #1037737) 
     125        //$fr .= pack('V', $crc);                 // crc32 
     126        //$fr .= pack('V', $c_len);               // compressed filesize 
     127        //$fr .= pack('V', $unc_len);             // uncompressed filesize 
     128 
     129        // add this entry to array 
     130        $this -> datasec[] = $fr; 
     131 
     132        // now add to central directory record 
     133        $cdrec = "\x50\x4b\x01\x02"; 
     134        $cdrec .= "\x00\x00";                // version made by 
     135        $cdrec .= "\x14\x00";                // version needed to extract 
     136        $cdrec .= "\x00\x00";                // gen purpose bit flag 
     137        $cdrec .= "\x08\x00";                // compression method 
     138        $cdrec .= $hexdtime;                 // last mod time & date 
     139        $cdrec .= pack('V', $crc);           // crc32 
     140        $cdrec .= pack('V', $c_len);         // compressed filesize 
     141        $cdrec .= pack('V', $unc_len);       // uncompressed filesize 
     142        $cdrec .= pack('v', strlen($name)); // length of filename 
     143        $cdrec .= pack('v', 0);             // extra field length 
     144        $cdrec .= pack('v', 0);             // file comment length 
     145        $cdrec .= pack('v', 0);             // disk number start 
     146        $cdrec .= pack('v', 0);             // internal file attributes 
     147        $cdrec .= pack('V', 32);            // external file attributes - 'archive' bit set 
     148 
     149        $cdrec .= pack('V', $this -> old_offset); // relative offset of local header 
     150        $this -> old_offset += strlen($fr); 
     151 
     152        $cdrec .= $name; 
     153 
     154        // optional extra field, file comment goes here 
     155        // save to central directory 
     156        $this -> ctrl_dir[] = $cdrec; 
     157    } // end of the 'addFile()' method 
     158 
     159 
     160    /** 
     161     * Dumps out file 
     162     * 
     163     * @return  string  the zipped file 
     164     * 
     165     * @access public 
     166     */ 
     167    function file() 
     168    { 
     169        $data    = implode('', $this -> datasec); 
     170        $ctrldir = implode('', $this -> ctrl_dir); 
     171 
     172        return 
     173            $data . 
     174            $ctrldir . 
     175            $this -> eof_ctrl_dir . 
     176            pack('v', sizeof($this -> ctrl_dir)) .  // total # of entries "on this disk" 
     177            pack('v', sizeof($this -> ctrl_dir)) .  // total # of entries overall 
     178            pack('V', strlen($ctrldir)) .           // size of central dir 
     179            pack('V', strlen($data)) .              // offset to start of central dir 
     180            "\x00\x00";                             // .zip file comment length 
     181    } // end of the 'file()' method 
     182 
     183} // end of the 'zipfile' class 
     184 
     185?> 
  • lib/jelix/utils/jZipCreator.class.php

    old new  
    33 * @package    jelix 
    44 * @subpackage utils 
    55 * @author     Laurent Jouanneau 
     6 * @contributor Julien Issler 
    67 * @copyright  2006 Laurent Jouanneau 
     8 * @copyright  2008 Julien Issler 
    79 * @link       http://www.jelix.org 
    810 * @licence    GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html 
    911 */ 
    1012 
     13// need zipfile class from phpMyAdmin 
     14require_once(LIB_PATH.'zip/zip.lib.php'); 
     15 
    1116/** 
    1217 * Class to create a zip file. 
    1318 * @package    jelix 
    1419 * @subpackage utils 
    1520 * @link http://www.pkware.com/business_and_developers/developer/appnote/ Official ZIP file format 
    1621 */ 
    17 class jZipCreator
     22class jZipCreator
    1823 
    19     /** 
    20      * contains all file records 
    21      * @var  array $fileRecords 
    22      */ 
    23     protected $fileRecords = array(); 
     24    protected $_zipfile; 
    2425 
    25     /** 
    26      * Contains the central directory 
    27      * @var  array $centralDirectory 
    28      */ 
    29     protected $centralDirectory = array(); 
     26    public function __construct(){ 
     27        $this->_zipfile = new zipfile(); 
     28    } 
    3029 
    3130    /** 
    32      * Offset of the central directory 
    33      * @var  integer  $centralDirOffset 
    34      */ 
    35     protected $centralDirOffset   = 0; 
    36  
    37     /** 
    3831     * adds a physical file to the zip archive 
    3932     * 
    4033     * @param  string  $filename  the path of the physical file you want to add 
    4134     * @param  string  $zipPath  the path of the file inside the zip archive 
    4235     */ 
    43     public function addFile($filename, $zipFileName=''){ 
     36    public function addFile($filename,$zipFileName=''){ 
    4437        if($zipFileName == '') $zipFileName = $filename; 
    4538        if(file_exists($filename)){ 
    46             $this->addContentFile($zipFileName, file_get_contents($filename), filemtime($filename)); 
     39            $this->_zipfile->addFile(file_get_contents($filename),$zipFileName,filemtime($filename)); 
    4740        }else{ 
    4841            throw new jException('jelix~errors.file.notexists', $filename); 
    4942        } 
     
    8477     * @param  string   $content    the content of the file 
    8578     * @param  integer  $filetime   the time modification of the file 
    8679     */ 
    87     public function addContentFile($zipFileName, $content, $filetime = 0){ 
    88  
    89         // converts unix timestamp to dos binary format 
    90         if($filetime == 0) 
    91             $filetime = mktime(); 
    92         elseif($filetime < 315529200) // 01/01/1980 
    93             $filetime = 315529200; 
    94  
    95         $dt = getdate($filetime); 
    96  
    97         $filetime =  pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
    98                 ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
    99  
    100         /* 
    101         generation of the file record 
    102  
    103         file record: 
    104          - local file header signature     4 bytes  (0x04034b50) 
    105          - version needed to extract       2 bytes  14 
    106          - general purpose bit flag        2 bytes  0 
    107          - compression method              2 bytes  0x8 
    108          - last mod file time              2 bytes (fileinfo) 
    109          - last mod file date              2 bytes (fileinfo) 
    110          - crc-32                          4 bytes (fileinfo) 
    111          - compressed size                 4 bytes (fileinfo) 
    112          - uncompressed size               4 bytes (fileinfo) 
    113          - file name length                2 bytes (fileinfo) 
    114          - extra field length              2 bytes (here 0) (fileinfo) 
    115          - file name (variable size) 
    116          - extra field (variable size)      (here nothing) 
    117          - compressed content 
    118         */ 
    119         $zipFileName     = str_replace('\\', '/', $zipFileName); 
    120  
    121         $zippedcontent    = substr(gzcompress($content), 2, -4); // compress and fix crc bug 
    122  
    123         $fileinfo  = $filetime.pack('V', crc32($content)); 
    124         $fileinfo .= pack('V', strlen($zippedcontent)). pack('V', strlen($content)); 
    125         $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 
    126  
    127         $filerecord   = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00"; 
    128         $filerecord .= $fileinfo.$zipFileName.$zippedcontent; 
    129  
    130         $this->fileRecords[] = $filerecord; 
    131  
    132  
    133         /* 
    134          register the file into the central directory record 
    135          it contains an header for each file 
    136            - central file header signature   4 bytes  (0x02014b50) 
    137            - version made by                 2 bytes  0=DOS 
    138            - version needed to extract       2 bytes  0x14 
    139            - general purpose bit flag        2 bytes  0 
    140            - compression method              2 bytes  0x8 
    141            - last mod file time              2 bytes (fileinfo) 
    142            - last mod file date              2 bytes (fileinfo) 
    143            - crc-32                          4 bytes (fileinfo) 
    144            - compressed size                 4 bytes (fileinfo) 
    145            - uncompressed size               4 bytes (fileinfo) 
    146            - file name length                2 bytes (fileinfo) 
    147            - extra field length              2 bytes   0 (fileinfo) 
    148            - file comment length             2 bytes   0 
    149            - disk number start               2 bytes   0 
    150            - internal file attributes        2 bytes   0 
    151            - external file attributes        4 bytes   32 : 'archive' bit set 
    152            - relative offset of local header 4 bytes 
    153            - file name (variable size) 
    154            - extra field (variable size) 
    155            - file comment (variable size) 
    156         */ 
    157         $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$fileinfo; 
    158         $cdrecord .= "\x00\x00\x00\x00\x00\x00\x32\x00\x00\x00"; 
    159         $cdrecord .= pack('V', $this ->centralDirOffset ); 
    160         $cdrecord .= $zipFileName; 
    161  
    162         $this->centralDirectory[] = $cdrecord; 
    163  
    164         $this ->centralDirOffset += strlen($filerecord); 
    165  
     80    public function addContentFile($zipfilename,$content,$filetime = 0){ 
     81        $this->_zipfile->addFile($content,$zipfilename,$filetime); 
    16682    } 
    16783 
    168  
    16984    /** 
    170      * create the contenu of the zip file 
     85     * create the content of the zip file 
    17186     * @return  string  the content of the zip file 
    17287     */ 
    17388    public function getContent(){ 
    174  
    175         $centraldir = implode('', $this->centralDirectory); 
    176         $c = pack('v', count($this ->centralDirectory)); 
    177  
    178         /* 
    179         zip file : 
    180            - file records 
    181            - central dir 
    182            - end of central dir signature    4 bytes  (0x06054b50) 
    183            - number of this disk             2 bytes   (0 here) 
    184            - number of the disk with the 
    185               start of the central directory 2 bytes   (0 here) 
    186            - total number of entries in the 
    187               central directory on this disk 2 bytes 
    188            - total number of entries in 
    189               the central directory          2 bytes 
    190            - size of the central directory   4 bytes 
    191            - offset of start of central directory with respect to 
    192              the starting disk number        4 bytes 
    193            - .ZIP file comment length        2 bytes 
    194            - .ZIP file comment       (variable size) 
    195         */ 
    196         return implode('', $this->fileRecords).$centraldir."\x50\x4b\x05\x06\x00\x00\x00\x00".$c.$c. 
    197             pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 
     89        return $this->_zipfile->file(); 
    19890    } 
    199 } 
    20091 
     92} 
    20193?> 
Download in other formats: Original Format