From 99410a21eb261f50234cc4148323a52b345e15e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20L=C5=93uillet?= Date: Mon, 19 Jan 2015 13:00:33 +0100 Subject: phpepub via composer --- inc/3rdparty/libraries/PHPePub/Zip.php | 818 --------------------------------- 1 file changed, 818 deletions(-) delete mode 100644 inc/3rdparty/libraries/PHPePub/Zip.php (limited to 'inc/3rdparty/libraries/PHPePub/Zip.php') diff --git a/inc/3rdparty/libraries/PHPePub/Zip.php b/inc/3rdparty/libraries/PHPePub/Zip.php deleted file mode 100644 index 01e03566..00000000 --- a/inc/3rdparty/libraries/PHPePub/Zip.php +++ /dev/null @@ -1,818 +0,0 @@ - - * @copyright 2009-2014 A. Grandt - * @license GNU LGPL 2.1 - * @link http://www.phpclasses.org/package/6110 - * @link https://github.com/Grandt/PHPZip - * @version 1.60 - */ -class Zip { - const VERSION = 1.60; - - const ZIP_LOCAL_FILE_HEADER = "\x50\x4b\x03\x04"; // Local file header signature - const ZIP_CENTRAL_FILE_HEADER = "\x50\x4b\x01\x02"; // Central file header signature - const ZIP_END_OF_CENTRAL_DIRECTORY = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record - - const EXT_FILE_ATTR_DIR = 010173200020; // Permission 755 drwxr-xr-x = (((S_IFDIR | 0755) << 16) | S_DOS_D); - const EXT_FILE_ATTR_FILE = 020151000040; // Permission 644 -rw-r--r-- = (((S_IFREG | 0644) << 16) | S_DOS_A); - - const ATTR_VERSION_TO_EXTRACT = "\x14\x00"; // Version needed to extract - const ATTR_MADE_BY_VERSION = "\x1E\x03"; // Made By Version - - // Unix file types - const S_IFIFO = 0010000; // named pipe (fifo) - const S_IFCHR = 0020000; // character special - const S_IFDIR = 0040000; // directory - const S_IFBLK = 0060000; // block special - const S_IFREG = 0100000; // regular - const S_IFLNK = 0120000; // symbolic link - const S_IFSOCK = 0140000; // socket - - // setuid/setgid/sticky bits, the same as for chmod: - - const S_ISUID = 0004000; // set user id on execution - const S_ISGID = 0002000; // set group id on execution - const S_ISTXT = 0001000; // sticky bit - - // And of course, the other 12 bits are for the permissions, the same as for chmod: - // When addding these up, you can also just write the permissions as a simgle octal number - // ie. 0755. The leading 0 specifies octal notation. - const S_IRWXU = 0000700; // RWX mask for owner - const S_IRUSR = 0000400; // R for owner - const S_IWUSR = 0000200; // W for owner - const S_IXUSR = 0000100; // X for owner - const S_IRWXG = 0000070; // RWX mask for group - const S_IRGRP = 0000040; // R for group - const S_IWGRP = 0000020; // W for group - const S_IXGRP = 0000010; // X for group - const S_IRWXO = 0000007; // RWX mask for other - const S_IROTH = 0000004; // R for other - const S_IWOTH = 0000002; // W for other - const S_IXOTH = 0000001; // X for other - const S_ISVTX = 0001000; // save swapped text even after use - - // Filetype, sticky and permissions are added up, and shifted 16 bits left BEFORE adding the DOS flags. - - // DOS file type flags, we really only use the S_DOS_D flag. - - const S_DOS_A = 0000040; // DOS flag for Archive - const S_DOS_D = 0000020; // DOS flag for Directory - const S_DOS_V = 0000010; // DOS flag for Volume - const S_DOS_S = 0000004; // DOS flag for System - const S_DOS_H = 0000002; // DOS flag for Hidden - const S_DOS_R = 0000001; // DOS flag for Read Only - - private $zipMemoryThreshold = 1048576; // Autocreate tempfile if the zip data exceeds 1048576 bytes (1 MB) - - private $zipData = NULL; - private $zipFile = NULL; - private $zipComment = NULL; - private $cdRec = array(); // central directory - private $offset = 0; - private $isFinalized = FALSE; - private $addExtraField = TRUE; - - private $streamChunkSize = 65536; - private $streamFilePath = NULL; - private $streamTimestamp = NULL; - private $streamFileComment = NULL; - private $streamFile = NULL; - private $streamData = NULL; - private $streamFileLength = 0; - private $streamExtFileAttr = null; - - /** - * Constructor. - * - * @param boolean $useZipFile Write temp zip data to tempFile? Default FALSE - */ - function __construct($useZipFile = FALSE) { - if ($useZipFile) { - $this->zipFile = tmpfile(); - } else { - $this->zipData = ""; - } - } - - function __destruct() { - if (is_resource($this->zipFile)) { - fclose($this->zipFile); - } - $this->zipData = NULL; - } - - /** - * Extra fields on the Zip directory records are Unix time codes needed for compatibility on the default Mac zip archive tool. - * These are enabled as default, as they do no harm elsewhere and only add 26 bytes per file added. - * - * @param bool $setExtraField TRUE (default) will enable adding of extra fields, anything else will disable it. - */ - function setExtraField($setExtraField = TRUE) { - $this->addExtraField = ($setExtraField === TRUE); - } - - /** - * Set Zip archive comment. - * - * @param string $newComment New comment. NULL to clear. - * @return bool $success - */ - public function setComment($newComment = NULL) { - if ($this->isFinalized) { - return FALSE; - } - $this->zipComment = $newComment; - - return TRUE; - } - - /** - * Set zip file to write zip data to. - * This will cause all present and future data written to this class to be written to this file. - * This can be used at any time, even after the Zip Archive have been finalized. Any previous file will be closed. - * Warning: If the given file already exists, it will be overwritten. - * - * @param string $fileName - * @return bool $success - */ - public function setZipFile($fileName) { - if (is_file($fileName)) { - unlink($fileName); - } - $fd=fopen($fileName, "x+b"); - if (is_resource($this->zipFile)) { - rewind($this->zipFile); - while (!feof($this->zipFile)) { - fwrite($fd, fread($this->zipFile, $this->streamChunkSize)); - } - - fclose($this->zipFile); - } else { - fwrite($fd, $this->zipData); - $this->zipData = NULL; - } - $this->zipFile = $fd; - - return TRUE; - } - - /** - * Add an empty directory entry to the zip archive. - * Basically this is only used if an empty directory is added. - * - * @param string $directoryPath Directory Path and name to be added to the archive. - * @param int $timestamp (Optional) Timestamp for the added directory, if omitted or set to 0, the current time will be used. - * @param string $fileComment (Optional) Comment to be added to the archive for this directory. To use fileComment, timestamp must be given. - * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this. - * @return bool $success - */ - public function addDirectory($directoryPath, $timestamp = 0, $fileComment = NULL, $extFileAttr = self::EXT_FILE_ATTR_DIR) { - if ($this->isFinalized) { - return FALSE; - } - $directoryPath = str_replace("\\", "/", $directoryPath); - $directoryPath = rtrim($directoryPath, "/"); - - if (strlen($directoryPath) > 0) { - $this->buildZipEntry($directoryPath.'/', $fileComment, "\x00\x00", "\x00\x00", $timestamp, "\x00\x00\x00\x00", 0, 0, $extFileAttr); - return TRUE; - } - return FALSE; - } - - /** - * Add a file to the archive at the specified location and file name. - * - * @param string $data File data. - * @param string $filePath Filepath and name to be used in the archive. - * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used. - * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given. - * @param bool $compress (Optional) Compress file, if set to FALSE the file will only be stored. Default TRUE. - * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this. - * @return bool $success - */ - public function addFile($data, $filePath, $timestamp = 0, $fileComment = NULL, $compress = TRUE, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if ($this->isFinalized) { - return FALSE; - } - - if (is_resource($data) && get_resource_type($data) == "stream") { - $this->addLargeFile($data, $filePath, $timestamp, $fileComment, $extFileAttr); - return FALSE; - } - - $gzData = ""; - $gzType = "\x08\x00"; // Compression type 8 = deflate - $gpFlags = "\x00\x00"; // General Purpose bit flags for compression type 8 it is: 0=Normal, 1=Maximum, 2=Fast, 3=super fast compression. - $dataLength = strlen($data); - $fileCRC32 = pack("V", crc32($data)); - - if ($compress) { - $gzTmp = gzcompress($data); - $gzData = substr(substr($gzTmp, 0, strlen($gzTmp) - 4), 2); // gzcompress adds a 2 byte header and 4 byte CRC we can't use. - // The 2 byte header does contain useful data, though in this case the 2 parameters we'd be interrested in will always be 8 for compression type, and 2 for General purpose flag. - $gzLength = strlen($gzData); - } else { - $gzLength = $dataLength; - } - - if ($gzLength >= $dataLength) { - $gzLength = $dataLength; - $gzData = $data; - $gzType = "\x00\x00"; // Compression type 0 = stored - $gpFlags = "\x00\x00"; // Compression type 0 = stored - } - - if (!is_resource($this->zipFile) && ($this->offset + $gzLength) > $this->zipMemoryThreshold) { - $this->zipflush(); - } - - $this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr); - - $this->zipwrite($gzData); - - return TRUE; - } - - /** - * Add the content to a directory. - * - * @author Adam Schmalhofer - * @author A. Grandt - * - * @param string $realPath Path on the file system. - * @param string $zipPath Filepath and name to be used in the archive. - * @param bool $recursive Add content recursively, default is TRUE. - * @param bool $followSymlinks Follow and add symbolic links, if they are accessible, default is TRUE. - * @param array &$addedFiles Reference to the added files, this is used to prevent duplicates, efault is an empty array. - * If you start the function by parsing an array, the array will be populated with the realPath - * and zipPath kay/value pairs added to the archive by the function. - * @param bool $overrideFilePermissions Force the use of the file/dir permissions set in the $extDirAttr - * and $extFileAttr parameters. - * @param int $extDirAttr Permissions for directories. - * @param int $extFileAttr Permissions for files. - */ - public function addDirectoryContent($realPath, $zipPath, $recursive = TRUE, $followSymlinks = TRUE, &$addedFiles = array(), - $overrideFilePermissions = FALSE, $extDirAttr = self::EXT_FILE_ATTR_DIR, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if (file_exists($realPath) && !isset($addedFiles[realpath($realPath)])) { - if (is_dir($realPath)) { - if ($overrideFilePermissions) { - $this->addDirectory($zipPath, 0, null, $extDirAttr); - } else { - $this->addDirectory($zipPath, 0, null, self::getFileExtAttr($realPath)); - } - } - - $addedFiles[realpath($realPath)] = $zipPath; - - $iter = new DirectoryIterator($realPath); - foreach ($iter as $file) { - if ($file->isDot()) { - continue; - } - $newRealPath = $file->getPathname(); - $newZipPath = self::pathJoin($zipPath, $file->getFilename()); - - if (file_exists($newRealPath) && ($followSymlinks === TRUE || !is_link($newRealPath))) { - if ($file->isFile()) { - $addedFiles[realpath($newRealPath)] = $newZipPath; - if ($overrideFilePermissions) { - $this->addLargeFile($newRealPath, $newZipPath, 0, null, $extFileAttr); - } else { - $this->addLargeFile($newRealPath, $newZipPath, 0, null, self::getFileExtAttr($newRealPath)); - } - } else if ($recursive === TRUE) { - $this->addDirectoryContent($newRealPath, $newZipPath, $recursive, $followSymlinks, $addedFiles, $overrideFilePermissions, $extDirAttr, $extFileAttr); - } else { - if ($overrideFilePermissions) { - $this->addDirectory($zipPath, 0, null, $extDirAttr); - } else { - $this->addDirectory($zipPath, 0, null, self::getFileExtAttr($newRealPath)); - } - } - } - } - } - } - - /** - * Add a file to the archive at the specified location and file name. - * - * @param string $dataFile File name/path. - * @param string $filePath Filepath and name to be used in the archive. - * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used. - * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given. - * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this. - * @return bool $success - */ - public function addLargeFile($dataFile, $filePath, $timestamp = 0, $fileComment = NULL, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if ($this->isFinalized) { - return FALSE; - } - - if (is_string($dataFile) && is_file($dataFile)) { - $this->processFile($dataFile, $filePath, $timestamp, $fileComment, $extFileAttr); - } else if (is_resource($dataFile) && get_resource_type($dataFile) == "stream") { - $fh = $dataFile; - $this->openStream($filePath, $timestamp, $fileComment, $extFileAttr); - - while (!feof($fh)) { - $this->addStreamData(fread($fh, $this->streamChunkSize)); - } - $this->closeStream($this->addExtraField); - } - return TRUE; - } - - /** - * Create a stream to be used for large entries. - * - * @param string $filePath Filepath and name to be used in the archive. - * @param int $timestamp (Optional) Timestamp for the added file, if omitted or set to 0, the current time will be used. - * @param string $fileComment (Optional) Comment to be added to the archive for this file. To use fileComment, timestamp must be given. - * @param int $extFileAttr (Optional) The external file reference, use generateExtAttr to generate this. - * @return bool $success - */ - public function openStream($filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if (!function_exists('sys_get_temp_dir')) { - die ("ERROR: Zip " . self::VERSION . " requires PHP version 5.2.1 or above if large files are used."); - } - - if ($this->isFinalized) { - return FALSE; - } - - $this->zipflush(); - - if (strlen($this->streamFilePath) > 0) { - $this->closeStream(); - } - - $this->streamFile = tempnam(sys_get_temp_dir(), 'Zip'); - $this->streamData = fopen($this->streamFile, "wb"); - $this->streamFilePath = $filePath; - $this->streamTimestamp = $timestamp; - $this->streamFileComment = $fileComment; - $this->streamFileLength = 0; - $this->streamExtFileAttr = $extFileAttr; - - return TRUE; - } - - /** - * Add data to the open stream. - * - * @param string $data - * @return mixed length in bytes added or FALSE if the archive is finalized or there are no open stream. - */ - public function addStreamData($data) { - if ($this->isFinalized || strlen($this->streamFilePath) == 0) { - return FALSE; - } - - $length = fwrite($this->streamData, $data, strlen($data)); - if ($length != strlen($data)) { - die ("

Length mismatch

\n"); - } - $this->streamFileLength += $length; - - return $length; - } - - /** - * Close the current stream. - * - * @return bool $success - */ - public function closeStream() { - if ($this->isFinalized || strlen($this->streamFilePath) == 0) { - return FALSE; - } - - fflush($this->streamData); - fclose($this->streamData); - - $this->processFile($this->streamFile, $this->streamFilePath, $this->streamTimestamp, $this->streamFileComment, $this->streamExtFileAttr); - - $this->streamData = null; - $this->streamFilePath = null; - $this->streamTimestamp = null; - $this->streamFileComment = null; - $this->streamFileLength = 0; - $this->streamExtFileAttr = null; - - // Windows is a little slow at times, so a millisecond later, we can unlink this. - unlink($this->streamFile); - - $this->streamFile = null; - - return TRUE; - } - - private function processFile($dataFile, $filePath, $timestamp = 0, $fileComment = null, $extFileAttr = self::EXT_FILE_ATTR_FILE) { - if ($this->isFinalized) { - return FALSE; - } - - $tempzip = tempnam(sys_get_temp_dir(), 'ZipStream'); - - $zip = new ZipArchive; - if ($zip->open($tempzip) === TRUE) { - $zip->addFile($dataFile, 'file'); - $zip->close(); - } - - $file_handle = fopen($tempzip, "rb"); - $stats = fstat($file_handle); - $eof = $stats['size']-72; - - fseek($file_handle, 6); - - $gpFlags = fread($file_handle, 2); - $gzType = fread($file_handle, 2); - fread($file_handle, 4); - $fileCRC32 = fread($file_handle, 4); - $v = unpack("Vval", fread($file_handle, 4)); - $gzLength = $v['val']; - $v = unpack("Vval", fread($file_handle, 4)); - $dataLength = $v['val']; - - $this->buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr); - - fseek($file_handle, 34); - $pos = 34; - - while (!feof($file_handle) && $pos < $eof) { - $datalen = $this->streamChunkSize; - if ($pos + $this->streamChunkSize > $eof) { - $datalen = $eof-$pos; - } - $data = fread($file_handle, $datalen); - $pos += $datalen; - - $this->zipwrite($data); - } - - fclose($file_handle); - - unlink($tempzip); - } - - /** - * Close the archive. - * A closed archive can no longer have new files added to it. - * - * @return bool $success - */ - public function finalize() { - if (!$this->isFinalized) { - if (strlen($this->streamFilePath) > 0) { - $this->closeStream(); - } - $cd = implode("", $this->cdRec); - - $cdRecSize = pack("v", sizeof($this->cdRec)); - $cdRec = $cd . self::ZIP_END_OF_CENTRAL_DIRECTORY - . $cdRecSize . $cdRecSize - . pack("VV", strlen($cd), $this->offset); - if (!empty($this->zipComment)) { - $cdRec .= pack("v", strlen($this->zipComment)) . $this->zipComment; - } else { - $cdRec .= "\x00\x00"; - } - - $this->zipwrite($cdRec); - - $this->isFinalized = TRUE; - $this->cdRec = NULL; - - return TRUE; - } - return FALSE; - } - - /** - * Get the handle ressource for the archive zip file. - * If the zip haven't been finalized yet, this will cause it to become finalized - * - * @return zip file handle - */ - public function getZipFile() { - if (!$this->isFinalized) { - $this->finalize(); - } - - $this->zipflush(); - - rewind($this->zipFile); - - return $this->zipFile; - } - - /** - * Get the zip file contents - * If the zip haven't been finalized yet, this will cause it to become finalized - * - * @return zip data - */ - public function getZipData() { - if (!$this->isFinalized) { - $this->finalize(); - } - if (!is_resource($this->zipFile)) { - return $this->zipData; - } else { - rewind($this->zipFile); - $filestat = fstat($this->zipFile); - return fread($this->zipFile, $filestat['size']); - } - } - - /** - * Send the archive as a zip download - * - * @param String $fileName The name of the Zip archive, in ISO-8859-1 (or ASCII) encoding, ie. "archive.zip". Optional, defaults to NULL, which means that no ISO-8859-1 encoded file name will be specified. - * @param String $contentType Content mime type. Optional, defaults to "application/zip". - * @param String $utf8FileName The name of the Zip archive, in UTF-8 encoding. Optional, defaults to NULL, which means that no UTF-8 encoded file name will be specified. - * @param bool $inline Use Content-Disposition with "inline" instead of "attached". Optional, defaults to FALSE. - * @return bool $success - */ - function sendZip($fileName = null, $contentType = "application/zip", $utf8FileName = null, $inline = false) { - if (!$this->isFinalized) { - $this->finalize(); - } - - $headerFile = null; - $headerLine = null; - if (!headers_sent($headerFile, $headerLine) or die("

Error: Unable to send file $fileName. HTML Headers have already been sent from $headerFile in line $headerLine

")) { - if ((ob_get_contents() === FALSE || ob_get_contents() == '') or die("\n

Error: Unable to send file $fileName. Output buffer contains the following text (typically warnings or errors):
" . htmlentities(ob_get_contents()) . "

")) { - if (ini_get('zlib.output_compression')) { - ini_set('zlib.output_compression', 'Off'); - } - - header("Pragma: public"); - header("Last-Modified: " . gmdate("D, d M Y H:i:s T")); - header("Expires: 0"); - header("Accept-Ranges: bytes"); - header("Connection: close"); - header("Content-Type: " . $contentType); - $cd = "Content-Disposition: "; - if ($inline) { - $cd .= "inline"; - } else{ - $cd .= "attached"; - } - if ($fileName) { - $cd .= '; filename="' . $fileName . '"'; - } - if ($utf8FileName) { - $cd .= "; filename*=UTF-8''" . rawurlencode($utf8FileName); - } - header($cd); - header("Content-Length: ". $this->getArchiveSize()); - - if (!is_resource($this->zipFile)) { - echo $this->zipData; - } else { - rewind($this->zipFile); - - while (!feof($this->zipFile)) { - echo fread($this->zipFile, $this->streamChunkSize); - } - } - } - return TRUE; - } - return FALSE; - } - - /** - * Return the current size of the archive - * - * @return $size Size of the archive - */ - public function getArchiveSize() { - if (!is_resource($this->zipFile)) { - return strlen($this->zipData); - } - $filestat = fstat($this->zipFile); - - return $filestat['size']; - } - - /** - * Calculate the 2 byte dostime used in the zip entries. - * - * @param int $timestamp - * @return 2-byte encoded DOS Date - */ - private function getDosTime($timestamp = 0) { - $timestamp = (int)$timestamp; - $oldTZ = @date_default_timezone_get(); - date_default_timezone_set('UTC'); - $date = ($timestamp == 0 ? getdate() : getdate($timestamp)); - date_default_timezone_set($oldTZ); - if ($date["year"] >= 1980) { - return pack("V", (($date["mday"] + ($date["mon"] << 5) + (($date["year"]-1980) << 9)) << 16) | - (($date["seconds"] >> 1) + ($date["minutes"] << 5) + ($date["hours"] << 11))); - } - return "\x00\x00\x00\x00"; - } - - /** - * Build the Zip file structures - * - * @param string $filePath - * @param string $fileComment - * @param string $gpFlags - * @param string $gzType - * @param int $timestamp - * @param string $fileCRC32 - * @param int $gzLength - * @param int $dataLength - * @param int $extFileAttr Use self::EXT_FILE_ATTR_FILE for files, self::EXT_FILE_ATTR_DIR for Directories. - */ - private function buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr) { - $filePath = str_replace("\\", "/", $filePath); - $fileCommentLength = (empty($fileComment) ? 0 : strlen($fileComment)); - $timestamp = (int)$timestamp; - $timestamp = ($timestamp == 0 ? time() : $timestamp); - - $dosTime = $this->getDosTime($timestamp); - $tsPack = pack("V", $timestamp); - - $ux = "\x75\x78\x0B\x00\x01\x04\xE8\x03\x00\x00\x04\x00\x00\x00\x00"; - - if (!isset($gpFlags) || strlen($gpFlags) != 2) { - $gpFlags = "\x00\x00"; - } - - $isFileUTF8 = mb_check_encoding($filePath, "UTF-8") && !mb_check_encoding($filePath, "ASCII"); - $isCommentUTF8 = !empty($fileComment) && mb_check_encoding($fileComment, "UTF-8") && !mb_check_encoding($fileComment, "ASCII"); - if ($isFileUTF8 || $isCommentUTF8) { - $flag = 0; - $gpFlagsV = unpack("vflags", $gpFlags); - if (isset($gpFlagsV['flags'])) { - $flag = $gpFlagsV['flags']; - } - $gpFlags = pack("v", $flag | (1 << 11)); - } - - $header = $gpFlags . $gzType . $dosTime. $fileCRC32 - . pack("VVv", $gzLength, $dataLength, strlen($filePath)); // File name length - - $zipEntry = self::ZIP_LOCAL_FILE_HEADER; - $zipEntry .= self::ATTR_VERSION_TO_EXTRACT; - $zipEntry .= $header; - $zipEntry .= pack("v", ($this->addExtraField ? 28 : 0)); // Extra field length - $zipEntry .= $filePath; // FileName - // Extra fields - if ($this->addExtraField) { - $zipEntry .= "\x55\x54\x09\x00\x03" . $tsPack . $tsPack . $ux; - } - $this->zipwrite($zipEntry); - - $cdEntry = self::ZIP_CENTRAL_FILE_HEADER; - $cdEntry .= self::ATTR_MADE_BY_VERSION; - $cdEntry .= ($dataLength === 0 ? "\x0A\x00" : self::ATTR_VERSION_TO_EXTRACT); - $cdEntry .= $header; - $cdEntry .= pack("v", ($this->addExtraField ? 24 : 0)); // Extra field length - $cdEntry .= pack("v", $fileCommentLength); // File comment length - $cdEntry .= "\x00\x00"; // Disk number start - $cdEntry .= "\x00\x00"; // internal file attributes - $cdEntry .= pack("V", $extFileAttr); // External file attributes - $cdEntry .= pack("V", $this->offset); // Relative offset of local header - $cdEntry .= $filePath; // FileName - // Extra fields - if ($this->addExtraField) { - $cdEntry .= "\x55\x54\x05\x00\x03" . $tsPack . $ux; - } - if (!empty($fileComment)) { - $cdEntry .= $fileComment; // Comment - } - - $this->cdRec[] = $cdEntry; - $this->offset += strlen($zipEntry) + $gzLength; - } - - private function zipwrite($data) { - if (!is_resource($this->zipFile)) { - $this->zipData .= $data; - } else { - fwrite($this->zipFile, $data); - fflush($this->zipFile); - } - } - - private function zipflush() { - if (!is_resource($this->zipFile)) { - $this->zipFile = tmpfile(); - fwrite($this->zipFile, $this->zipData); - $this->zipData = NULL; - } - } - - /** - * Join $file to $dir path, and clean up any excess slashes. - * - * @param string $dir - * @param string $file - */ - public static function pathJoin($dir, $file) { - if (empty($dir) || empty($file)) { - return self::getRelativePath($dir . $file); - } - return self::getRelativePath($dir . '/' . $file); - } - - /** - * Clean up a path, removing any unnecessary elements such as /./, // or redundant ../ segments. - * If the path starts with a "/", it is deemed an absolute path and any /../ in the beginning is stripped off. - * The returned path will not end in a "/". - * - * Sometimes, when a path is generated from multiple fragments, - * you can get something like "../data/html/../images/image.jpeg" - * This will normalize that example path to "../data/images/image.jpeg" - * - * @param string $path The path to clean up - * @return string the clean path - */ - public static function getRelativePath($path) { - $path = preg_replace("#/+\.?/+#", "/", str_replace("\\", "/", $path)); - $dirs = explode("/", rtrim(preg_replace('#^(?:\./)+#', '', $path), '/')); - - $offset = 0; - $sub = 0; - $subOffset = 0; - $root = ""; - - if (empty($dirs[0])) { - $root = "/"; - $dirs = array_splice($dirs, 1); - } else if (preg_match("#[A-Za-z]:#", $dirs[0])) { - $root = strtoupper($dirs[0]) . "/"; - $dirs = array_splice($dirs, 1); - } - - $newDirs = array(); - foreach ($dirs as $dir) { - if ($dir !== "..") { - $subOffset--; - $newDirs[++$offset] = $dir; - } else { - $subOffset++; - if (--$offset < 0) { - $offset = 0; - if ($subOffset > $sub) { - $sub++; - } - } - } - } - - if (empty($root)) { - $root = str_repeat("../", $sub); - } - return $root . implode("/", array_slice($newDirs, 0, $offset)); - } - - /** - * Create the file permissions for a file or directory, for use in the extFileAttr parameters. - * - * @param int $owner Unix permisions for owner (octal from 00 to 07) - * @param int $group Unix permisions for group (octal from 00 to 07) - * @param int $other Unix permisions for others (octal from 00 to 07) - * @param bool $isFile - * @return EXTRERNAL_REF field. - */ - public static function generateExtAttr($owner = 07, $group = 05, $other = 05, $isFile = true) { - $fp = $isFile ? self::S_IFREG : self::S_IFDIR; - $fp |= (($owner & 07) << 6) | (($group & 07) << 3) | ($other & 07); - - return ($fp << 16) | ($isFile ? self::S_DOS_A : self::S_DOS_D); - } - - /** - * Get the file permissions for a file or directory, for use in the extFileAttr parameters. - * - * @param string $filename - * @return external ref field, or FALSE if the file is not found. - */ - public static function getFileExtAttr($filename) { - if (file_exists($filename)) { - $fp = fileperms($filename) << 16; - return $fp | (is_dir($filename) ? self::S_DOS_D : self::S_DOS_A); - } - return FALSE; - } -} -?> -- cgit v1.2.3