%PDF- %PDF-
Direktori : /home/opti/public_html/stlc/wp-content/plugins/duplicator/src/Utils/ |
Current File : /home/opti/public_html/stlc/wp-content/plugins/duplicator/src/Utils/ZipArchiveExtended.php |
<?php /** * @package Duplicator */ namespace Duplicator\Utils; use Duplicator\Libs\Snap\SnapIO; use Duplicator\Libs\Snap\SnapLog; use Duplicator\Libs\Snap\SnapUtil; use Exception; use ZipArchive; class ZipArchiveExtended { /** @var string */ protected $archivePath = ''; /** @var ZipArchive */ protected $zipArchive = null; /** @var bool */ protected $isOpened = false; /** @var bool */ protected $compressed = false; /** @var bool */ protected $encrypt = false; /** @var string */ protected $password = ''; /** * Class constructor * * @param string $path zip archive path */ public function __construct($path) { if (!self::isPhpZipAvailable()) { throw new Exception('ZipArchive PHP module is not installed/enabled.'); } if (file_exists($path) && (!is_file($path) || !is_writeable($path))) { throw new Exception('File ' . SnapLog::v2str($path) . 'exists but isn\'t valid'); } $this->archivePath = $path; $this->zipArchive = new ZipArchive(); $this->setCompressed(true); } /** * Class destructor */ public function __destruct() { $this->close(); } /** * Check if class ZipArchvie is available * * @return bool */ public static function isPhpZipAvailable() { return SnapUtil::classExists(ZipArchive::class); } /** * Add full dir in archive * * @param string $dirPath dir path * @param string $archivePath local archive path * * @return bool TRUE on success or FALSE on failure. */ public function addDir($dirPath, $archivePath) { if (!is_dir($dirPath) || !is_readable($dirPath)) { return false; } $dirPath = SnapIO::safePathTrailingslashit($dirPath); $archivePath = SnapIO::safePathTrailingslashit($archivePath); $thisObj = $this; return SnapIO::regexGlobCallback( $dirPath, function ($path) use ($dirPath, $archivePath, $thisObj) { $newPath = $archivePath . SnapIO::getRelativePath($path, $dirPath); if (is_dir($path)) { $thisObj->addEmptyDir($newPath); } else { $thisObj->addFile($path, $newPath); } }, array('recursive' => true) ); } /** * Add empty dir on zip archive * * @param string $path archive dir to add * * @return bool TRUE on success or FALSE on failure. */ public function addEmptyDir($path) { return $this->zipArchive->addEmptyDir($path); } /** * Add file on zip archive * * @param string $filepath file path * @param string $archivePath archive path, if empty use file name * @param int $maxSize max size of file, if the size is grater than this value the file will be truncated, 0 for no limit * * @return bool TRUE on success or FALSE on failure. */ public function addFile($filepath, $archivePath = '', $maxSize = 0) { if (!is_file($filepath) || !is_readable($filepath)) { return false; } if (strlen($archivePath) === 0) { $archivePath = basename($filepath); } if ($maxSize > 0 && filesize($filepath) > $maxSize) { if (($content = file_get_contents($filepath, false, null, 0, $maxSize)) === false) { return false; } $result = $this->zipArchive->addFromString($archivePath, $content); } else { $result = $this->zipArchive->addFile($filepath, $archivePath); } if ($result && $this->encrypt) { $this->zipArchive->setEncryptionName($archivePath, ZipArchive::EM_AES_256); } if ($result && !$this->compressed) { $this->zipArchive->setCompressionName($archivePath, ZipArchive::CM_STORE); } return $result; } /** * Creates a temporary file with the given content. The file will be deleted after the zip is created * * @param string $archivePath Filename in archive * @param string $content Content of the file * @param int $maxSize max size of file, if the size is grater than this value the file will be truncated, 0 for no limit * * @return bool returns true if the file was created successfully */ public function addFileFromString($archivePath, $content, $maxSize = 0) { if ($maxSize > 0 && strlen($content) > $maxSize) { $content = substr($content, 0, $maxSize); } $result = $this->zipArchive->addFromString($archivePath, $content); if ($result && $this->encrypt) { $this->zipArchive->setEncryptionName($archivePath, ZipArchive::EM_AES_256); } if ($result && !$this->compressed) { $this->zipArchive->setCompressionName($archivePath, ZipArchive::CM_STORE); } return $result; } /** * Open Zip archive, create it if don't exists * * @return bool|int Returns TRUE on success or the error code. See zip archive */ public function open() { if ($this->isOpened) { return true; } if (($result = $this->zipArchive->open($this->archivePath, ZipArchive::CREATE)) === true) { $this->isOpened = true; if ($this->encrypt) { $this->zipArchive->setPassword($this->password); } else { $this->zipArchive->setPassword(''); } } return $result; } /** * Close zip archive * * @return bool True on success or false on failure. */ public function close() { if (!$this->isOpened) { return true; } $result = false; if (($result = $this->zipArchive->close()) === true) { $this->isOpened = false; } return $result; } /** * Get num files in zip archive * * @return int */ public function getNumFiles() { $this->open(); return $this->zipArchive->numFiles; } /** * Get the value of compressed\ * * @return bool */ public function isCompressed() { return $this->compressed; } /** * Se compression if is available * * @param bool $compressed if true compress zip archive * * @return bool return compressd value */ public function setCompressed($compressed) { if (!method_exists($this->zipArchive, 'setCompressionName')) { // If don't exists setCompressionName the archive can't create uncrompressed $this->compressed = true; } else { $this->compressed = $compressed; } return $this->compressed; } /** * Get the value of encrypt * * @return bool */ public function isEncrypted() { return $this->encrypt; } /** * Return true if ZipArchive encryption is available * * @return bool */ public static function isEncryptionAvaliable() { static $isEncryptAvailable = null; if ($isEncryptAvailable === null) { if (!self::isPhpZipAvailable()) { $isEncryptAvailable = false; return false; } $zipArchive = new ZipArchive(); if (!method_exists($zipArchive, 'setEncryptionName')) { $isEncryptAvailable = false; return false; } if (version_compare(self::getLibzipVersion(), '1.2.0', '<')) { $isEncryptAvailable = false; return false; } $isEncryptAvailable = true; } return $isEncryptAvailable; } /** * Get libzip version * * @return string */ public static function getLibzipVersion() { static $zlibVersion = null; if (is_null($zlibVersion)) { ob_start(); SnapUtil::phpinfo(INFO_MODULES); $info = (string) ob_get_clean(); if (preg_match('/<td\s.*?>\s*(libzip.*\sver.+?)\s*<\/td>\s*<td\s.*?>\s*(.+?)\s*<\/td>/i', $info, $matches) !== 1) { $zlibVersion = "0"; } else { $zlibVersion = $matches[2]; } } return $zlibVersion; } /** * Set encryption * * @param bool $encrypt true if archvie must be encrypted * @param string $password password * @return bool */ public function setEncrypt($encrypt, $password = '') { $this->encrypt = (self::isEncryptionAvaliable() ? $encrypt : false); if ($this->encrypt) { $this->password = $password; } else { $this->password = ''; } if ($this->isOpened) { if ($this->encrypt) { $this->zipArchive->setPassword($this->password); } else { $this->zipArchive->setPassword(''); } } return $this->encrypt; } /** * Files regex search and return zip file stat * * @param string $path Archive path * @param string $regex Regex to search * @param string $password Password if archive is encrypted or empty string * * @return false|array{name:string,index:int,crc:int,size:int,mtime:int,comp_size:int,comp_method:int} */ public static function searchRegex($path, $regex, $password = '') { if (!self::isPhpZipAvailable()) { throw new Exception(__('ZipArchive PHP module is not installed/enabled. The current Backup cannot be opened.', 'duplicator')); } $zip = new ZipArchive(); if ($zip->open($path) !== true) { throw new Exception('Cannot open the ZipArchive file. Please see the online FAQ\'s for additional help.' . $path); } if (strlen($password)) { $zip->setPassword($password); } $result = false; for ($i = 0; $i < $zip->numFiles; $i++) { /** @var array{name:string,index:int,crc:int,size:int,mtime:int,comp_size:int,comp_method:int} */ $stat = $zip->statIndex($i); $name = basename($stat['name']); if (preg_match($regex, $name) === 1) { $result = $stat; break; } } $zip->close(); return $result; } }