Changeset 950

Show
Ignore:
Timestamp:
05/28/08 13:26:38 (6 months ago)
Author:
julieni
Message:

ticket #570: jZipCreator : empty dirs are not included in the archive

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/1.0.x/lib/jelix/CREDITS

    r947 r950  
    7474 - form plugin create always a form with method post (#592) 
    7575 - jDao : attribute groupby for method selectfirst (#447) 
     76 - jZipCreator : empty dirs are not included in the archive (#570) 
    7677 
    7778Bastien Jaillot (aka bastnic) 
  • branches/1.0.x/lib/jelix/CREDITS

    r947 r950  
    7474 - form plugin create always a form with method post (#592) 
    7575 - jDao : attribute groupby for method selectfirst (#447) 
     76 - jZipCreator : empty dirs are not included in the archive (#570) 
    7677 
    7778Bastien Jaillot (aka bastnic) 
  • branches/1.0.x/lib/jelix/CREDITS

    r947 r950  
    7474 - form plugin create always a form with method post (#592) 
    7575 - jDao : attribute groupby for method selectfirst (#447) 
     76 - jZipCreator : empty dirs are not included in the archive (#570) 
    7677 
    7778Bastien Jaillot (aka bastnic) 
  • branches/1.0.x/lib/jelix/CREDITS

    r947 r950  
    7474 - form plugin create always a form with method post (#592) 
    7575 - jDao : attribute groupby for method selectfirst (#447) 
     76 - jZipCreator : empty dirs are not included in the archive (#570) 
    7677 
    7778Bastien Jaillot (aka bastnic) 
  • branches/1.0.x/lib/jelix/utils/jZipCreator.class.php

    r922 r950  
    6565 
    6666            if ($handle = opendir($path)) { 
     67                $this->addEmptyDir($zipDirPath,filemtime($path)); 
    6768                while (($file = readdir($handle)) !== false) { 
    68                     if($file == "." || $file == "..") continue; 
    69                     if (!is_dir($path.$file)) { 
     69                    if($file == '.' || $file == '..') 
     70                        continue; 
     71                    if (!is_dir($path.$file)) 
    7072                        $this->addFile($path.$file, $zipDirPath.$file); 
    71                     }elseif ($recursive){ 
     73                    else if ($recursive) 
    7274                        $this->addDir($path.$file,$zipDirPath.$file, true); 
    73                     } 
    7475                } 
    7576                closedir($handle); 
     
    8990    public function addContentFile($zipFileName, $content, $filetime = 0){ 
    9091 
    91         // converts unix timestamp to dos binary format 
    92         if($filetime == 0) 
    93             $filetime = time(); 
    94         elseif($filetime < 315529200) // 01/01/1980 
    95             $filetime = 315529200; 
    96  
    97         $dt = getdate($filetime); 
    98  
    99         $filetime =  pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
    100                 ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
    101  
     92        $filetime = $this->_getDOSTimeFormat($filetime); 
     93         
    10294        /* 
    10395        generation of the file record 
     
    127119        $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 
    128120 
    129         $filerecord   = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00"; 
    130         $filerecord .= $fileinfo.$zipFileName.$zippedcontent; 
     121        $filerecord = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$fileinfo. 
     122            $zipFileName.$zippedcontent; 
    131123 
    132124        $this->fileRecords[] = $filerecord; 
    133125 
    134  
    135         /* 
    136          register the file into the central directory record 
    137          it contains an header for each file 
    138            - central file header signature   4 bytes  (0x02014b50) 
    139            - version made by                 2 bytes  0=DOS 
    140            - version needed to extract       2 bytes  0x14 
    141            - general purpose bit flag        2 bytes  0 
    142            - compression method              2 bytes  0x8 
    143            - last mod file time              2 bytes (fileinfo) 
    144            - last mod file date              2 bytes (fileinfo) 
    145            - crc-32                          4 bytes (fileinfo) 
    146            - compressed size                 4 bytes (fileinfo) 
    147            - uncompressed size               4 bytes (fileinfo) 
    148            - file name length                2 bytes (fileinfo) 
    149            - extra field length              2 bytes   0 (fileinfo) 
    150            - file comment length             2 bytes   0 
    151            - disk number start               2 bytes   0 
    152            - internal file attributes        2 bytes   0 
    153            - external file attributes        4 bytes   32 : 'archive' bit set 
    154            - relative offset of local header 4 bytes 
    155            - file name (variable size) 
    156            - extra field (variable size) 
    157            - file comment (variable size) 
    158         */ 
    159         $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$fileinfo; 
    160         $cdrecord .= "\x00\x00\x00\x00\x00\x00"; 
    161         $cdrecord .= pack('V', 32); 
    162         $cdrecord .= pack('V', $this ->centralDirOffset ); 
    163         $cdrecord .= $zipFileName; 
    164  
    165         $this->centralDirectory[] = $cdrecord; 
    166  
    167         $this ->centralDirOffset += strlen($filerecord); 
    168  
     126        $this->_addCentralDirEntry($zipFileName, $fileinfo); 
     127 
     128        $this->centralDirOffset += strlen($filerecord); 
     129 
     130    } 
     131     
     132    /** 
     133     * adds an empty dir to the zip file 
     134     */ 
     135    public function addEmptyDir($name, $time=0){ 
     136         
     137        $time = $this->_getDOSTimeFormat($time); 
     138 
     139        $name = str_replace('\\', '/', $name); 
     140         
     141        if(substr($name,-1,1)!=='/') 
     142            $name .= '/'; 
     143 
     144        if($name == '/') 
     145            return; 
     146 
     147        $fileinfo = $time."\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00". 
     148            pack('v', strlen($name))."\x00\x00"; 
     149 
     150        $filerecord = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$fileinfo.$name; 
     151 
     152        $this->fileRecords[] = $filerecord; 
     153 
     154        $this->_addCentralDirEntry($name, $fileinfo, true); 
     155 
     156        $this->centralDirOffset += strlen($filerecord); 
    169157    } 
    170158 
     
    200188            pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 
    201189    } 
     190     
     191     
     192     
     193    protected function _getDOSTimeFormat($timestamp){ 
     194        // converts unix timestamp to dos binary format 
     195        if($timestamp == 0) 
     196            $timestamp = time(); 
     197        elseif($timestamp < 315529200) // 01/01/1980 
     198            $timestamp = 315529200; 
     199 
     200        $dt = getdate($timestamp); 
     201 
     202        return pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
     203                ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
     204         
     205    } 
     206     
     207    protected function _addCentralDirEntry($name, $info, $isDir = false){         
     208        /* 
     209         register the file into the central directory record 
     210         it contains an header for each file 
     211           - central file header signature   4 bytes  (0x02014b50) 
     212           - version made by                 2 bytes  0=DOS 
     213           - version needed to extract       2 bytes  0x14 
     214           - general purpose bit flag        2 bytes  0 
     215           - compression method              2 bytes  0x8 
     216           - last mod file time              2 bytes (fileinfo) 
     217           - last mod file date              2 bytes (fileinfo) 
     218           - crc-32                          4 bytes (fileinfo) 
     219           - compressed size                 4 bytes (fileinfo) 
     220           - uncompressed size               4 bytes (fileinfo) 
     221           - file name length                2 bytes (fileinfo) 
     222           - extra field length              2 bytes   0 (fileinfo) 
     223           - file comment length             2 bytes   0 
     224           - disk number start               2 bytes   0 
     225           - internal file attributes        2 bytes   0 
     226           - external file attributes        4 bytes   32 : 'archive' bit set ; 16 : for empty folder support 
     227           - relative offset of local header 4 bytes 
     228           - file name (variable size) 
     229           - extra field (variable size) 
     230           - file comment (variable size) 
     231        */ 
     232         
     233        $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$info; 
     234        $cdrecord .= "\x00\x00\x00\x00\x00\x00"; 
     235        if($isDir) 
     236            $cdrecord .= pack('V', 16); 
     237        else 
     238            $cdrecord .= pack('V', 32); 
     239        $cdrecord .= pack('V', $this ->centralDirOffset ); 
     240        $cdrecord .= $name; 
     241 
     242        $this->centralDirectory[] = $cdrecord; 
     243    } 
    202244} 
    203245 
  • branches/1.0.x/lib/jelix/utils/jZipCreator.class.php

    r922 r950  
    6565 
    6666            if ($handle = opendir($path)) { 
     67                $this->addEmptyDir($zipDirPath,filemtime($path)); 
    6768                while (($file = readdir($handle)) !== false) { 
    68                     if($file == "." || $file == "..") continue; 
    69                     if (!is_dir($path.$file)) { 
     69                    if($file == '.' || $file == '..') 
     70                        continue; 
     71                    if (!is_dir($path.$file)) 
    7072                        $this->addFile($path.$file, $zipDirPath.$file); 
    71                     }elseif ($recursive){ 
     73                    else if ($recursive) 
    7274                        $this->addDir($path.$file,$zipDirPath.$file, true); 
    73                     } 
    7475                } 
    7576                closedir($handle); 
     
    8990    public function addContentFile($zipFileName, $content, $filetime = 0){ 
    9091 
    91         // converts unix timestamp to dos binary format 
    92         if($filetime == 0) 
    93             $filetime = time(); 
    94         elseif($filetime < 315529200) // 01/01/1980 
    95             $filetime = 315529200; 
    96  
    97         $dt = getdate($filetime); 
    98  
    99         $filetime =  pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
    100                 ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
    101  
     92        $filetime = $this->_getDOSTimeFormat($filetime); 
     93         
    10294        /* 
    10395        generation of the file record 
     
    127119        $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 
    128120 
    129         $filerecord   = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00"; 
    130         $filerecord .= $fileinfo.$zipFileName.$zippedcontent; 
     121        $filerecord = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$fileinfo. 
     122            $zipFileName.$zippedcontent; 
    131123 
    132124        $this->fileRecords[] = $filerecord; 
    133125 
    134  
    135         /* 
    136          register the file into the central directory record 
    137          it contains an header for each file 
    138            - central file header signature   4 bytes  (0x02014b50) 
    139            - version made by                 2 bytes  0=DOS 
    140            - version needed to extract       2 bytes  0x14 
    141            - general purpose bit flag        2 bytes  0 
    142            - compression method              2 bytes  0x8 
    143            - last mod file time              2 bytes (fileinfo) 
    144            - last mod file date              2 bytes (fileinfo) 
    145            - crc-32                          4 bytes (fileinfo) 
    146            - compressed size                 4 bytes (fileinfo) 
    147            - uncompressed size               4 bytes (fileinfo) 
    148            - file name length                2 bytes (fileinfo) 
    149            - extra field length              2 bytes   0 (fileinfo) 
    150            - file comment length             2 bytes   0 
    151            - disk number start               2 bytes   0 
    152            - internal file attributes        2 bytes   0 
    153            - external file attributes        4 bytes   32 : 'archive' bit set 
    154            - relative offset of local header 4 bytes 
    155            - file name (variable size) 
    156            - extra field (variable size) 
    157            - file comment (variable size) 
    158         */ 
    159         $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$fileinfo; 
    160         $cdrecord .= "\x00\x00\x00\x00\x00\x00"; 
    161         $cdrecord .= pack('V', 32); 
    162         $cdrecord .= pack('V', $this ->centralDirOffset ); 
    163         $cdrecord .= $zipFileName; 
    164  
    165         $this->centralDirectory[] = $cdrecord; 
    166  
    167         $this ->centralDirOffset += strlen($filerecord); 
    168  
     126        $this->_addCentralDirEntry($zipFileName, $fileinfo); 
     127 
     128        $this->centralDirOffset += strlen($filerecord); 
     129 
     130    } 
     131     
     132    /** 
     133     * adds an empty dir to the zip file 
     134     */ 
     135    public function addEmptyDir($name, $time=0){ 
     136         
     137        $time = $this->_getDOSTimeFormat($time); 
     138 
     139        $name = str_replace('\\', '/', $name); 
     140         
     141        if(substr($name,-1,1)!=='/') 
     142            $name .= '/'; 
     143 
     144        if($name == '/') 
     145            return; 
     146 
     147        $fileinfo = $time."\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00". 
     148            pack('v', strlen($name))."\x00\x00"; 
     149 
     150        $filerecord = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$fileinfo.$name; 
     151 
     152        $this->fileRecords[] = $filerecord; 
     153 
     154        $this->_addCentralDirEntry($name, $fileinfo, true); 
     155 
     156        $this->centralDirOffset += strlen($filerecord); 
    169157    } 
    170158 
     
    200188            pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 
    201189    } 
     190     
     191     
     192     
     193    protected function _getDOSTimeFormat($timestamp){ 
     194        // converts unix timestamp to dos binary format 
     195        if($timestamp == 0) 
     196            $timestamp = time(); 
     197        elseif($timestamp < 315529200) // 01/01/1980 
     198            $timestamp = 315529200; 
     199 
     200        $dt = getdate($timestamp); 
     201 
     202        return pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
     203                ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
     204         
     205    } 
     206     
     207    protected function _addCentralDirEntry($name, $info, $isDir = false){         
     208        /* 
     209         register the file into the central directory record 
     210         it contains an header for each file 
     211           - central file header signature   4 bytes  (0x02014b50) 
     212           - version made by                 2 bytes  0=DOS 
     213           - version needed to extract       2 bytes  0x14 
     214           - general purpose bit flag        2 bytes  0 
     215           - compression method              2 bytes  0x8 
     216           - last mod file time              2 bytes (fileinfo) 
     217           - last mod file date              2 bytes (fileinfo) 
     218           - crc-32                          4 bytes (fileinfo) 
     219           - compressed size                 4 bytes (fileinfo) 
     220           - uncompressed size               4 bytes (fileinfo) 
     221           - file name length                2 bytes (fileinfo) 
     222           - extra field length              2 bytes   0 (fileinfo) 
     223           - file comment length             2 bytes   0 
     224           - disk number start               2 bytes   0 
     225           - internal file attributes        2 bytes   0 
     226           - external file attributes        4 bytes   32 : 'archive' bit set ; 16 : for empty folder support 
     227           - relative offset of local header 4 bytes 
     228           - file name (variable size) 
     229           - extra field (variable size) 
     230           - file comment (variable size) 
     231        */ 
     232         
     233        $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$info; 
     234        $cdrecord .= "\x00\x00\x00\x00\x00\x00"; 
     235        if($isDir) 
     236            $cdrecord .= pack('V', 16); 
     237        else 
     238            $cdrecord .= pack('V', 32); 
     239        $cdrecord .= pack('V', $this ->centralDirOffset ); 
     240        $cdrecord .= $name; 
     241 
     242        $this->centralDirectory[] = $cdrecord; 
     243    } 
    202244} 
    203245 
  • branches/1.0.x/lib/jelix/utils/jZipCreator.class.php

    r922 r950  
    6565 
    6666            if ($handle = opendir($path)) { 
     67                $this->addEmptyDir($zipDirPath,filemtime($path)); 
    6768                while (($file = readdir($handle)) !== false) { 
    68                     if($file == "." || $file == "..") continue; 
    69                     if (!is_dir($path.$file)) { 
     69                    if($file == '.' || $file == '..') 
     70                        continue; 
     71                    if (!is_dir($path.$file)) 
    7072                        $this->addFile($path.$file, $zipDirPath.$file); 
    71                     }elseif ($recursive){ 
     73                    else if ($recursive) 
    7274                        $this->addDir($path.$file,$zipDirPath.$file, true); 
    73                     } 
    7475                } 
    7576                closedir($handle); 
     
    8990    public function addContentFile($zipFileName, $content, $filetime = 0){ 
    9091 
    91         // converts unix timestamp to dos binary format 
    92         if($filetime == 0) 
    93             $filetime = time(); 
    94         elseif($filetime < 315529200) // 01/01/1980 
    95             $filetime = 315529200; 
    96  
    97         $dt = getdate($filetime); 
    98  
    99         $filetime =  pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
    100                 ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
    101  
     92        $filetime = $this->_getDOSTimeFormat($filetime); 
     93         
    10294        /* 
    10395        generation of the file record 
     
    127119        $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 
    128120 
    129         $filerecord   = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00"; 
    130         $filerecord .= $fileinfo.$zipFileName.$zippedcontent; 
     121        $filerecord = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$fileinfo. 
     122            $zipFileName.$zippedcontent; 
    131123 
    132124        $this->fileRecords[] = $filerecord; 
    133125 
    134  
    135         /* 
    136          register the file into the central directory record 
    137          it contains an header for each file 
    138            - central file header signature   4 bytes  (0x02014b50) 
    139            - version made by                 2 bytes  0=DOS 
    140            - version needed to extract       2 bytes  0x14 
    141            - general purpose bit flag        2 bytes  0 
    142            - compression method              2 bytes  0x8 
    143            - last mod file time              2 bytes (fileinfo) 
    144            - last mod file date              2 bytes (fileinfo) 
    145            - crc-32                          4 bytes (fileinfo) 
    146            - compressed size                 4 bytes (fileinfo) 
    147            - uncompressed size               4 bytes (fileinfo) 
    148            - file name length                2 bytes (fileinfo) 
    149            - extra field length              2 bytes   0 (fileinfo) 
    150            - file comment length             2 bytes   0 
    151            - disk number start               2 bytes   0 
    152            - internal file attributes        2 bytes   0 
    153            - external file attributes        4 bytes   32 : 'archive' bit set 
    154            - relative offset of local header 4 bytes 
    155            - file name (variable size) 
    156            - extra field (variable size) 
    157            - file comment (variable size) 
    158         */ 
    159         $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$fileinfo; 
    160         $cdrecord .= "\x00\x00\x00\x00\x00\x00"; 
    161         $cdrecord .= pack('V', 32); 
    162         $cdrecord .= pack('V', $this ->centralDirOffset ); 
    163         $cdrecord .= $zipFileName; 
    164  
    165         $this->centralDirectory[] = $cdrecord; 
    166  
    167         $this ->centralDirOffset += strlen($filerecord); 
    168  
     126        $this->_addCentralDirEntry($zipFileName, $fileinfo); 
     127 
     128        $this->centralDirOffset += strlen($filerecord); 
     129 
     130    } 
     131     
     132    /** 
     133     * adds an empty dir to the zip file 
     134     */ 
     135    public function addEmptyDir($name, $time=0){ 
     136         
     137        $time = $this->_getDOSTimeFormat($time); 
     138 
     139        $name = str_replace('\\', '/', $name); 
     140         
     141        if(substr($name,-1,1)!=='/') 
     142            $name .= '/'; 
     143 
     144        if($name == '/') 
     145            return; 
     146 
     147        $fileinfo = $time."\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00". 
     148            pack('v', strlen($name))."\x00\x00"; 
     149 
     150        $filerecord = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$fileinfo.$name; 
     151 
     152        $this->fileRecords[] = $filerecord; 
     153 
     154        $this->_addCentralDirEntry($name, $fileinfo, true); 
     155 
     156        $this->centralDirOffset += strlen($filerecord); 
    169157    } 
    170158 
     
    200188            pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 
    201189    } 
     190     
     191     
     192     
     193    protected function _getDOSTimeFormat($timestamp){ 
     194        // converts unix timestamp to dos binary format 
     195        if($timestamp == 0) 
     196            $timestamp = time(); 
     197        elseif($timestamp < 315529200) // 01/01/1980 
     198            $timestamp = 315529200; 
     199 
     200        $dt = getdate($timestamp); 
     201 
     202        return pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
     203                ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
     204         
     205    } 
     206     
     207    protected function _addCentralDirEntry($name, $info, $isDir = false){         
     208        /* 
     209         register the file into the central directory record 
     210         it contains an header for each file 
     211           - central file header signature   4 bytes  (0x02014b50) 
     212           - version made by                 2 bytes  0=DOS 
     213           - version needed to extract       2 bytes  0x14 
     214           - general purpose bit flag        2 bytes  0 
     215           - compression method              2 bytes  0x8 
     216           - last mod file time              2 bytes (fileinfo) 
     217           - last mod file date              2 bytes (fileinfo) 
     218           - crc-32                          4 bytes (fileinfo) 
     219           - compressed size                 4 bytes (fileinfo) 
     220           - uncompressed size               4 bytes (fileinfo) 
     221           - file name length                2 bytes (fileinfo) 
     222           - extra field length              2 bytes   0 (fileinfo) 
     223           - file comment length             2 bytes   0 
     224           - disk number start               2 bytes   0 
     225           - internal file attributes        2 bytes   0 
     226           - external file attributes        4 bytes   32 : 'archive' bit set ; 16 : for empty folder support 
     227           - relative offset of local header 4 bytes 
     228           - file name (variable size) 
     229           - extra field (variable size) 
     230           - file comment (variable size) 
     231        */ 
     232         
     233        $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$info; 
     234        $cdrecord .= "\x00\x00\x00\x00\x00\x00"; 
     235        if($isDir) 
     236            $cdrecord .= pack('V', 16); 
     237        else 
     238            $cdrecord .= pack('V', 32); 
     239        $cdrecord .= pack('V', $this ->centralDirOffset ); 
     240        $cdrecord .= $name; 
     241 
     242        $this->centralDirectory[] = $cdrecord; 
     243    } 
    202244} 
    203245 
  • branches/1.0.x/lib/jelix/utils/jZipCreator.class.php

    r922 r950  
    6565 
    6666            if ($handle = opendir($path)) { 
     67                $this->addEmptyDir($zipDirPath,filemtime($path)); 
    6768                while (($file = readdir($handle)) !== false) { 
    68                     if($file == "." || $file == "..") continue; 
    69                     if (!is_dir($path.$file)) { 
     69                    if($file == '.' || $file == '..') 
     70                        continue; 
     71                    if (!is_dir($path.$file)) 
    7072                        $this->addFile($path.$file, $zipDirPath.$file); 
    71                     }elseif ($recursive){ 
     73                    else if ($recursive) 
    7274                        $this->addDir($path.$file,$zipDirPath.$file, true); 
    73                     } 
    7475                } 
    7576                closedir($handle); 
     
    8990    public function addContentFile($zipFileName, $content, $filetime = 0){ 
    9091 
    91         // converts unix timestamp to dos binary format 
    92         if($filetime == 0) 
    93             $filetime = time(); 
    94         elseif($filetime < 315529200) // 01/01/1980 
    95             $filetime = 315529200; 
    96  
    97         $dt = getdate($filetime); 
    98  
    99         $filetime =  pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
    100                 ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
    101  
     92        $filetime = $this->_getDOSTimeFormat($filetime); 
     93         
    10294        /* 
    10395        generation of the file record 
     
    127119        $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 
    128120 
    129         $filerecord   = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00"; 
    130         $filerecord .= $fileinfo.$zipFileName.$zippedcontent; 
     121        $filerecord = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$fileinfo. 
     122            $zipFileName.$zippedcontent; 
    131123 
    132124        $this->fileRecords[] = $filerecord; 
    133125 
    134  
    135         /* 
    136          register the file into the central directory record 
    137          it contains an header for each file 
    138            - central file header signature   4 bytes  (0x02014b50) 
    139            - version made by                 2 bytes  0=DOS 
    140            - version needed to extract       2 bytes  0x14 
    141            - general purpose bit flag        2 bytes  0 
    142            - compression method              2 bytes  0x8 
    143            - last mod file time              2 bytes (fileinfo) 
    144            - last mod file date              2 bytes (fileinfo) 
    145            - crc-32                          4 bytes (fileinfo) 
    146            - compressed size                 4 bytes (fileinfo) 
    147            - uncompressed size               4 bytes (fileinfo) 
    148            - file name length                2 bytes (fileinfo) 
    149            - extra field length              2 bytes   0 (fileinfo) 
    150            - file comment length             2 bytes   0 
    151            - disk number start               2 bytes   0 
    152            - internal file attributes        2 bytes   0 
    153            - external file attributes        4 bytes   32 : 'archive' bit set 
    154            - relative offset of local header 4 bytes 
    155            - file name (variable size) 
    156            - extra field (variable size) 
    157            - file comment (variable size) 
    158         */ 
    159         $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$fileinfo; 
    160         $cdrecord .= "\x00\x00\x00\x00\x00\x00"; 
    161         $cdrecord .= pack('V', 32); 
    162         $cdrecord .= pack('V', $this ->centralDirOffset ); 
    163         $cdrecord .= $zipFileName; 
    164  
    165         $this->centralDirectory[] = $cdrecord; 
    166  
    167         $this ->centralDirOffset += strlen($filerecord); 
    168  
     126        $this->_addCentralDirEntry($zipFileName, $fileinfo); 
     127 
     128        $this->centralDirOffset += strlen($filerecord); 
     129 
     130    } 
     131     
     132    /** 
     133     * adds an empty dir to the zip file 
     134     */ 
     135    public function addEmptyDir($name, $time=0){ 
     136         
     137        $time = $this->_getDOSTimeFormat($time); 
     138 
     139        $name = str_replace('\\', '/', $name); 
     140         
     141        if(substr($name,-1,1)!=='/') 
     142            $name .= '/'; 
     143 
     144        if($name == '/') 
     145            return; 
     146 
     147        $fileinfo = $time."\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00". 
     148            pack('v', strlen($name))."\x00\x00"; 
     149 
     150        $filerecord = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$fileinfo.$name; 
     151 
     152        $this->fileRecords[] = $filerecord; 
     153 
     154        $this->_addCentralDirEntry($name, $fileinfo, true); 
     155 
     156        $this->centralDirOffset += strlen($filerecord); 
    169157    } 
    170158 
     
    200188            pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 
    201189    } 
     190     
     191     
     192     
     193    protected function _getDOSTimeFormat($timestamp){ 
     194        // converts unix timestamp to dos binary format 
     195        if($timestamp == 0) 
     196            $timestamp = time(); 
     197        elseif($timestamp < 315529200) // 01/01/1980 
     198            $timestamp = 315529200; 
     199 
     200        $dt = getdate($timestamp); 
     201 
     202        return pack('V',($dt['seconds'] >> 1) | ($dt['minutes'] << 5) | ($dt['hours'] << 11) | 
     203                ($dt['mday'] << 16) | ($dt['mon'] << 21) | (($dt['year'] - 1980) << 25)); 
     204         
     205    } 
     206     
     207    protected function _addCentralDirEntry($name, $info, $isDir = false){         
     208        /* 
     209         register the file into the central directory record 
     210         it contains an header for each file 
     211           - central file header signature   4 bytes  (0x02014b50) 
     212           - version made by                 2 bytes  0=DOS 
     213           - version needed to extract       2 bytes  0x14 
     214           - general purpose bit flag        2 bytes  0 
     215           - compression method              2 bytes  0x8 
     216           - last mod file time              2 bytes (fileinfo) 
     217           - last mod file date              2 bytes (fileinfo) 
     218           - crc-32                          4 bytes (fileinfo) 
     219           - compressed size                 4 bytes (fileinfo) 
     220           - uncompressed size               4 bytes (fileinfo) 
     221           - file name length                2 bytes (fileinfo) 
     222           - extra field length              2 bytes   0 (fileinfo) 
     223           - file comment length             2 bytes   0 
     224           - disk number start               2 bytes   0 
     225           - internal file attributes        2 bytes   0 
     226           - external file attributes        4 bytes   32 : 'archive' bit set ; 16 : for empty folder support 
     227           - relative offset of local header 4 bytes 
     228           - file name (variable size) 
     229           - extra field (variable size) 
     230           - file comment (variable size) 
     231        */ 
     232         
     233        $cdrecord = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00".$info; 
     234        $cdrecord .= "\x00\x00\x00\x00\x00\x00"; 
     235        if($isDir) 
     236            $cdrecord .= pack('V', 16); 
     237        else 
     238            $cdrecord .= pack('V', 32); 
     239        $cdrecord .= pack('V', $this ->centralDirOffset ); 
     240        $cdrecord .= $name; 
     241 
     242        $this->centralDirectory[] = $cdrecord; 
     243    } 
    202244} 
    203245 
Download in other formats: Unified Diff Zip Archive