Calculate the 2 byte dos time used in the zip entries.
public static getDosTime ( integer $timestamp ) : string | ||
$timestamp | integer | |
Результат | string | 2-byte encoded DOS Date |
public static function createDirEntry($path, $timestamp) { $fileEntry = new ZipFileEntry(); $fileEntry->gzType = 0; $fileEntry->gpFlags = 0; $fileEntry->fileCRC32 = 0; $fileEntry->externalFileAttributes = ZipFileEntry::EXT_FILE_ATTR_DIR; $fileEntry->gzLength = 0; $fileEntry->dataLength = 0; $fileEntry->isDirectory = true; $fileEntry->dosTime = ZipUtils::getDosTime($timestamp); $fileEntry->path = $path; $ef = new ExtendedTimeStampExtraField(); $ef->setModTime($timestamp); $ef->setAccessTime($timestamp); $fileEntry->addExtraField($ef); $ef = new GenericExtraField(); $ef->header = AbstractExtraField::HEADER_UNIX_TYPE_3; $ef->setFieldData("è", ''); $fileEntry->addExtraField($ef); return $fileEntry; }
/** * Build the Zip file structures * * @author A. Grandt <*****@*****.**> * @author Greg Kappatos * * @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. */ protected function buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr) { $filePath = str_replace("\\", "/", $filePath); $fileCommentLength = empty($fileComment) ? 0 : ZipUtils::bin_strlen($fileComment); $timestamp = (int) $timestamp; $timestamp = $timestamp == 0 ? time() : $timestamp; $dosTime = ZipUtils::getDosTime($timestamp); $tsPack = pack("V", $timestamp); if (!isset($gpFlags) || ZipUtils::bin_strlen($gpFlags) != 2) { $gpFlags = self::DEFAULT_GP_FLAGS; } $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"); $localExtraField = ""; $centralExtraField = ""; if ($this->addExtraField) { $localExtraField .= "UT\t" . $tsPack . $tsPack . self::EXTRA_FIELD_NEW_UNIX_GUID; $centralExtraField .= "UT" . $tsPack . self::EXTRA_FIELD_NEW_UNIX_GUID_CD; } if ($isFileUTF8 || $isCommentUTF8) { $flag = 0; $gpFlagsV = unpack("vflags", $gpFlags); if (isset($gpFlagsV['flags'])) { $flag = $gpFlagsV['flags']; } $gpFlags = pack("v", $flag | 1 << 11); if ($isFileUTF8) { $utfPathExtraField = "up" . pack("v", 5 + ZipUtils::bin_strlen($filePath)) . "" . pack("V", crc32($filePath)) . $filePath; $localExtraField .= $utfPathExtraField; $centralExtraField .= $utfPathExtraField; } if ($isCommentUTF8) { $centralExtraField .= "uc" . pack("v", 5 + ZipUtils::bin_strlen($fileComment)) . "" . pack("V", crc32($fileComment)) . $fileComment; } } $header = $gpFlags . $gzType . $dosTime . $fileCRC32 . pack("VVv", $gzLength, $dataLength, ZipUtils::bin_strlen($filePath)); // File name length $zipEntry = self::ZIP_LOCAL_FILE_HEADER . self::ATTR_VERSION_TO_EXTRACT . $header . pack("v", ZipUtils::bin_strlen($localExtraField)) . $filePath . $localExtraField; // Extra fields $this->onBuildZipEntry(array('zipEntry' => $zipEntry)); $cdEntry = self::ZIP_CENTRAL_FILE_HEADER . self::ATTR_MADE_BY_VERSION . ($dataLength === 0 ? "\n" : self::ATTR_VERSION_TO_EXTRACT) . $header . pack("v", ZipUtils::bin_strlen($centralExtraField)) . pack("v", $fileCommentLength) . self::NUL_NUL . self::NUL_NUL . pack("V", $extFileAttr) . pack("V", $this->offset) . $filePath . $centralExtraField; // Extra fields if (!empty($fileComment)) { $cdEntry .= $fileComment; // Comment } $this->cdRec[] = $cdEntry; $this->offset += ZipUtils::bin_strlen($zipEntry) + $gzLength; $this->_notifyListeners(null, array('file' => $zipEntry)); }
/** * Build the Zip file structures * * @author A. Grandt <*****@*****.**> * @author Greg Kappatos * * @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. */ protected function buildZipEntry($filePath, $fileComment, $gpFlags, $gzType, $timestamp, $fileCRC32, $gzLength, $dataLength, $extFileAttr) { $filePath = str_replace("\\", "/", $filePath); $fileCommentLength = (empty($fileComment) ? 0 : BinStringStatic::_strlen($fileComment)); $timestamp = (int)$timestamp; $timestamp = ($timestamp == 0 ? time() : $timestamp); $dosTime = ZipUtils::getDosTime($timestamp); $tsPack = pack("V", $timestamp); if (!isset($gpFlags) || BinStringStatic::_strlen($gpFlags) != 2) { $gpFlags = self::DEFAULT_GP_FLAGS; } $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"); $locExField = ""; $cenExField = ""; if ($this->addExtraField) { $locExField .= self::HEADER_EXTENDED_TIMESTAMP . "\x09\x00\x03" . $tsPack . $tsPack . self::EXTRA_FIELD_NEW_UNIX_GUID; $cenExField .= self::HEADER_EXTENDED_TIMESTAMP . "\x05\x00\x03" . $tsPack . self::EXTRA_FIELD_NEW_UNIX_GUID_CD; } if ($isFileUTF8 || $isCommentUTF8) { $flag = 0; $gpFlagsV = unpack("vflags", $gpFlags); if (isset($gpFlagsV['flags'])) { $flag = $gpFlagsV['flags']; } $gpFlags = pack("v", $flag | (1 << 11)); if ($isFileUTF8) { $utfExField = self::HEADER_UNICODE_PATH // utf8 encoded File path extra field . pack ("v", (5 + BinStringStatic::_strlen($filePath))) . "\x01" . pack("V", crc32($filePath)) . $filePath; $locExField .= $utfExField; $cenExField .= $utfExField; } if ($isCommentUTF8) { $cenExField .= self::HEADER_UNICODE_COMMENT // utf8 encoded file comment extra field . pack ("v", (5 + BinStringStatic::_strlen($fileComment))) . "\x01" . pack("V", crc32($fileComment)) . $fileComment; } } $header = $gpFlags . $gzType . $dosTime. $fileCRC32 . pack("VVv", $gzLength, $dataLength, BinStringStatic::_strlen($filePath)); // File name length $zipEntry = self::ZIP_LOCAL_FILE_HEADER . self::ATTR_VERSION_TO_EXTRACT . $header . pack("v", BinStringStatic::_strlen($locExField)) // Extra field length . $filePath // FileName . $locExField; // Extra fields $this->onBuildZipEntry(array( 'zipEntry' => $zipEntry, )); $cdEntry = self::ZIP_CENTRAL_FILE_HEADER . self::ATTR_MADE_BY_VERSION . ($dataLength === 0 ? "\x0A\x00" : self::ATTR_VERSION_TO_EXTRACT) . $header . pack("v", BinStringStatic::_strlen($cenExField)) // Extra field length . pack("v", $fileCommentLength) // File comment length . self::NULL_WORD // Disk number start . self::NULL_WORD // internal file attributes . pack("V", $extFileAttr) // External file attributes . pack("V", $this->offset) // Relative offset of local header . $filePath // FileName . $cenExField; // Extra fields if (!empty($fileComment)) { $cdEntry .= $fileComment; // Comment } $this->cdRec[] = $cdEntry; $this->offset += BinStringStatic::_strlen($zipEntry) + $gzLength; $this->_notifyListeners(null, array( 'file' => $zipEntry, )); }