| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- <?php
- namespace application\controllers;
- class ZipController {
-
- /** @var ZipFile */
- private $zipFile = null;
- private $zipBuffer = "";
- private $destination = null;
-
- public function extractZip($data) {
- $this->destination = '/home/' . $data['username'] . '/' . $data['domain'];
- $url = $data['zip'];
- @set_time_limit(3600);
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));
- curl_setopt($ch, CURLOPT_TIMEOUT, 3600);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- //curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- //curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_WRITEFUNCTION, array($this, 'readZip'));
- $r = curl_exec($ch);
- $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
- $error = curl_error($ch);
- if ($status != 200) {
- throw new ErrorException("Zip download error (code: $status)".($error ? ": $error" : ''));
- }
- curl_close($ch);
- if ($this->zipFile) { $this->zipFile->close(); }
- }
-
- protected function readZip($ch, $data) {
- if (is_file($this->destination.'/index.html')) {
- rename($this->destination.'/index.html', $this->destination.'/index_backup.html');
- }
- $size = function_exists('mb_strlen') ? mb_strlen($data, '8bit') : strlen($data);
- $this->zipBuffer .= $data;
- //self::debugLog("Receive: ".$data);
- $continue = true;
- while ($continue) {
- $continue = false;
- $size_0 = function_exists('mb_strlen') ? mb_strlen($this->zipBuffer, '8bit') : strlen($this->zipBuffer);
- if ($this->zipFile && $size_0 >= $this->zipFile->compressedSize) {
- $continue = true;
- $this->zipFile->writeUncompressed(substr($this->zipBuffer, 0, $this->zipFile->compressedSize));
- $this->zipBuffer = substr($this->zipBuffer, $this->zipFile->compressedSize);
- $this->zipFile->close();
- $this->zipFile = null;
- } else if (!$this->zipFile && ($fp = strpos($this->zipBuffer, ZipFile::ZIP_FILE_HEAD)) !== false) {
- $continue = true;
- $this->zipBuffer = substr($this->zipBuffer, $fp);
- $hsize = 26 + strlen(ZipFile::ZIP_FILE_HEAD);
- if (strlen($this->zipBuffer) <= $hsize) { break; } // need more data
- $name_size_raw = unpack('v', substr($this->zipBuffer, strlen(ZipFile::ZIP_FILE_HEAD) + 22, 2));
- $name_size = intval(reset($name_size_raw));
- $extra_size_raw = unpack('v', substr($this->zipBuffer, strlen(ZipFile::ZIP_FILE_HEAD) + 24, 2));
- $extra_size = intval(reset($extra_size_raw));
- $hsize += $name_size + $extra_size;
- if (strlen($this->zipBuffer) < $hsize) { break; } // need more data
- // parse file header
- if ($this->zipFile) { $this->zipFile->close(); }
- $this->zipFile = ZipFile::parse(substr($this->zipBuffer, 0, $hsize), $this->destination);
- //self::debugLog('File: '.$this->zipFile->baseDir.'/'.$this->zipFile->name);
- $this->zipFile->open();
- $this->zipBuffer = substr($this->zipBuffer, $hsize);
- }
- }
- return $size;
- }
-
- }
- class ZipFile {
-
- const ZIP_FILE_HEAD = "\x50\x4b\x03\x04";
-
- public $version;
- public $flags;
- public $compression;
- public $modDateTime;
- public $crc32;
- public $crc32Raw;
- public $compressedSize;
- public $size;
- public $sizeRaw;
- public $name;
- public $extra;
- public $baseDir;
- private $handle;
-
- public function __construct($baseDir = null) {
- $this->baseDir = rtrim($baseDir, '/');
- $this->modDateTime = date('Y-m-d H:i:s');
- $this->compressedSize = 0;
- $this->size = 0;
- $this->name = 'new file';
- }
-
- public function open() {
- $dir = dirname($this->baseDir.'/'.$this->name);
- if (!is_dir($dir)) { mkdir($dir, 0755, true); }
- if (!empty($this->name)) {
- $this->handle = fopen($this->baseDir.'/'.$this->name, 'w');
- } else {
- throw new ErrorException("File name is empty");
- }
- }
-
- public function close() {
- if ($this->handle !== false) {
- fclose($this->handle);
- chmod($this->baseDir.'/'.$this->name, 0644);
- }
- }
-
- public function write($data) {
- if ($this->handle !== false) {
- fwrite($this->handle, $data);
- } else {
- throw new ErrorException("File is not open");
- }
- }
-
- public function writeUncompressed($data) {
- $data_u = gzinflate($data);
- $this->write($data_u);
- }
- /**
- * @param string $data
- * @return ZipFile
- */
- public static function parse($data, $baseDir = null) {
- $data = substr($data, strlen(self::ZIP_FILE_HEAD));
- $fh = new ZipFile($baseDir);
- $fh->version = substr($data, 0, 2);
- $fh->flags = substr($data, 2, 2);
- $fh->compression = substr($data, 4, 2);
- $hexdtime_raw = unpack('V', substr($data, 6, 4));
- $hexdtime = reset($hexdtime_raw);
- $fh->modDateTime = ''.((($hexdtime >> 25) & 0xff) + 1980).'-'.
- sprintf('%02d', ($hexdtime >> 21) & 0x0f).'-'.
- sprintf('%02d', ($hexdtime >> 16) & 0x1f).' '.
- sprintf('%02d', ($hexdtime >> 11) & 0x1f).':'.
- sprintf('%02d', ($hexdtime >> 5) & 0x3f).':'.
- sprintf('%02d', ($hexdtime << 1) & 0x1f);
- $fh->crc32Raw = substr($data, 10, 4);
- $crc32 = unpack('V', $fh->crc32Raw);
- $fh->crc32 = sprintf('%08x', reset($crc32));
- $clen = unpack('V', substr($data, 14, 4));
- $fh->compressedSize = reset($clen);
- $fh->sizeRaw = substr($data, 18, 4);
- $ulen = unpack('V', $fh->sizeRaw);
- $fh->size = reset($ulen);
- $nlen_raw = unpack('v', substr($data, 22, 2));
- $nlen = reset($nlen_raw);
- $elen_raw = unpack('v', substr($data, 24, 2));
- $elen = reset($elen_raw);
- $fh->name = substr($data, 26, $nlen);
- $fh->extra = substr($data, 26 + $nlen, $elen);
- return $fh;
- }
-
- }
|