developer.jelix.org is not used any more and exists only for history. Post new tickets on the Github account.
developer.jelix.org n'est plus utilisée, et existe uniquement pour son historique. Postez les nouveaux tickets sur le compte github.

Ticket #538: 538-jZipCreator.diff

File 538-jZipCreator.diff, 14.4 KB (added by Julien, 13 years ago)

patch based on a wrapper for a class from phpMyAdmin

  • build/manifests/jelix-lib.mn

     
    703703! WSDLException.class.php
    704704! WSDLStruct.class.php
    705705! WSException.class.php
     706
     707cd lib/zip
     708  zip.lib.php
     709 Pas de fin de ligne à la fin du fichier
  • lib/zip/zip.lib.php

     
     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?>
     186 Pas de fin de ligne à la fin du fichier
  • lib/jelix/utils/jZipCreator.class.php

     
    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?>
     94 Pas de fin de ligne à la fin du fichier