Changeset 950
- Timestamp:
- 05/28/08 13:26:38 (6 months ago)
- Files:
-
- branches/1.0.x/lib/jelix/CREDITS (modified) (1 diff)
- branches/1.0.x/lib/jelix/CREDITS (modified) (1 diff)
- branches/1.0.x/lib/jelix/CREDITS (modified) (1 diff)
- branches/1.0.x/lib/jelix/CREDITS (modified) (1 diff)
- branches/1.0.x/lib/jelix/utils/jZipCreator.class.php (modified) (4 diffs)
- branches/1.0.x/lib/jelix/utils/jZipCreator.class.php (modified) (4 diffs)
- branches/1.0.x/lib/jelix/utils/jZipCreator.class.php (modified) (4 diffs)
- branches/1.0.x/lib/jelix/utils/jZipCreator.class.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/1.0.x/lib/jelix/CREDITS
r947 r950 74 74 - form plugin create always a form with method post (#592) 75 75 - jDao : attribute groupby for method selectfirst (#447) 76 - jZipCreator : empty dirs are not included in the archive (#570) 76 77 77 78 Bastien Jaillot (aka bastnic) branches/1.0.x/lib/jelix/CREDITS
r947 r950 74 74 - form plugin create always a form with method post (#592) 75 75 - jDao : attribute groupby for method selectfirst (#447) 76 - jZipCreator : empty dirs are not included in the archive (#570) 76 77 77 78 Bastien Jaillot (aka bastnic) branches/1.0.x/lib/jelix/CREDITS
r947 r950 74 74 - form plugin create always a form with method post (#592) 75 75 - jDao : attribute groupby for method selectfirst (#447) 76 - jZipCreator : empty dirs are not included in the archive (#570) 76 77 77 78 Bastien Jaillot (aka bastnic) branches/1.0.x/lib/jelix/CREDITS
r947 r950 74 74 - form plugin create always a form with method post (#592) 75 75 - jDao : attribute groupby for method selectfirst (#447) 76 - jZipCreator : empty dirs are not included in the archive (#570) 76 77 77 78 Bastien Jaillot (aka bastnic) branches/1.0.x/lib/jelix/utils/jZipCreator.class.php
r922 r950 65 65 66 66 if ($handle = opendir($path)) { 67 $this->addEmptyDir($zipDirPath,filemtime($path)); 67 68 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)) 70 72 $this->addFile($path.$file, $zipDirPath.$file); 71 }elseif ($recursive){73 else if ($recursive) 72 74 $this->addDir($path.$file,$zipDirPath.$file, true); 73 }74 75 } 75 76 closedir($handle); … … 89 90 public function addContentFile($zipFileName, $content, $filetime = 0){ 90 91 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 102 94 /* 103 95 generation of the file record … … 127 119 $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 128 120 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; 131 123 132 124 $this->fileRecords[] = $filerecord; 133 125 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); 169 157 } 170 158 … … 200 188 pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 201 189 } 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 } 202 244 } 203 245 branches/1.0.x/lib/jelix/utils/jZipCreator.class.php
r922 r950 65 65 66 66 if ($handle = opendir($path)) { 67 $this->addEmptyDir($zipDirPath,filemtime($path)); 67 68 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)) 70 72 $this->addFile($path.$file, $zipDirPath.$file); 71 }elseif ($recursive){73 else if ($recursive) 72 74 $this->addDir($path.$file,$zipDirPath.$file, true); 73 }74 75 } 75 76 closedir($handle); … … 89 90 public function addContentFile($zipFileName, $content, $filetime = 0){ 90 91 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 102 94 /* 103 95 generation of the file record … … 127 119 $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 128 120 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; 131 123 132 124 $this->fileRecords[] = $filerecord; 133 125 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); 169 157 } 170 158 … … 200 188 pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 201 189 } 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 } 202 244 } 203 245 branches/1.0.x/lib/jelix/utils/jZipCreator.class.php
r922 r950 65 65 66 66 if ($handle = opendir($path)) { 67 $this->addEmptyDir($zipDirPath,filemtime($path)); 67 68 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)) 70 72 $this->addFile($path.$file, $zipDirPath.$file); 71 }elseif ($recursive){73 else if ($recursive) 72 74 $this->addDir($path.$file,$zipDirPath.$file, true); 73 }74 75 } 75 76 closedir($handle); … … 89 90 public function addContentFile($zipFileName, $content, $filetime = 0){ 90 91 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 102 94 /* 103 95 generation of the file record … … 127 119 $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 128 120 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; 131 123 132 124 $this->fileRecords[] = $filerecord; 133 125 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); 169 157 } 170 158 … … 200 188 pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 201 189 } 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 } 202 244 } 203 245 branches/1.0.x/lib/jelix/utils/jZipCreator.class.php
r922 r950 65 65 66 66 if ($handle = opendir($path)) { 67 $this->addEmptyDir($zipDirPath,filemtime($path)); 67 68 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)) 70 72 $this->addFile($path.$file, $zipDirPath.$file); 71 }elseif ($recursive){73 else if ($recursive) 72 74 $this->addDir($path.$file,$zipDirPath.$file, true); 73 }74 75 } 75 76 closedir($handle); … … 89 90 public function addContentFile($zipFileName, $content, $filetime = 0){ 90 91 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 102 94 /* 103 95 generation of the file record … … 127 119 $fileinfo .= pack('v', strlen($zipFileName))."\x00\x00"; 128 120 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; 131 123 132 124 $this->fileRecords[] = $filerecord; 133 125 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); 169 157 } 170 158 … … 200 188 pack('V', strlen($centraldir)).pack('V', $this ->centralDirOffset)."\x00\x00"; 201 189 } 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 } 202 244 } 203 245
