165 lines
6.5 KiB
PHP
165 lines
6.5 KiB
PHP
<?php
|
|
|
|
defined('ABSPATH') || defined('DUPXABSPATH') || exit;
|
|
/**
|
|
* Utility class for zipping up content
|
|
*
|
|
* Standard: PSR-2
|
|
*
|
|
* @link http://www.php-fig.org/psr/psr-2
|
|
*
|
|
* @subpackage classes/utilities
|
|
* @copyright (c) 2017, Snapcreek LLC
|
|
* @license https://opensource.org/licenses/GPL-3.0 GNU Public License
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if (! defined('DUPLICATOR_VERSION')) {
|
|
exit;
|
|
}
|
|
|
|
class DUP_Zip_U
|
|
{
|
|
/**
|
|
* Add a directory to an existing ZipArchive object
|
|
*
|
|
* @param ZipArchive $zipArchive An existing ZipArchive object
|
|
* @param string $directoryPath The full directory path to add to the ZipArchive
|
|
* @param bool $retainDirectory Should the full directory path be retained in the archive
|
|
*
|
|
* @return bool Returns true if the directory was added to the object
|
|
*/
|
|
public static function addDirWithZipArchive($zipArchive, $directoryPath, $retainDirectory, $localPrefix, $isCompressed)
|
|
{
|
|
$directoryPath = rtrim(str_replace("\\", '/', $directoryPath), '/') . '/';
|
|
if (!is_dir($directoryPath) || !is_readable($directoryPath)) {
|
|
$success = false;
|
|
} elseif (!$fp = @opendir($directoryPath)) {
|
|
$success = false;
|
|
} else {
|
|
$success = true;
|
|
while (false !== ($file = readdir($fp))) {
|
|
if ($file === '.' || $file === '..') {
|
|
continue;
|
|
}
|
|
$objectPath = $directoryPath . $file;
|
|
// Not used SnapIO::safePath(), because I would like to decrease max_nest_level
|
|
// Otherwise we will get the error:
|
|
// PHP Fatal error: Uncaught Error: Maximum function nesting level of '512' reached, aborting! in ...
|
|
// $objectPath = SnapIO::safePath($objectPath);
|
|
$localName = ltrim(str_replace($directoryPath, '', $objectPath), '/');
|
|
if ($retainDirectory) {
|
|
$localName = basename($directoryPath) . "/$localName";
|
|
}
|
|
$localName = ltrim($localPrefix . $localName, '/');
|
|
if (is_readable($objectPath)) {
|
|
if (is_dir($objectPath)) {
|
|
$localPrefixArg = substr($localName, 0, strrpos($localName, '/')) . '/';
|
|
$added = self::addDirWithZipArchive($zipArchive, $objectPath, $retainDirectory, $localPrefixArg, $isCompressed);
|
|
} else {
|
|
$added = self::addFileToZipArchive($zipArchive, $objectPath, $localName, $isCompressed);
|
|
}
|
|
} else {
|
|
$added = false;
|
|
}
|
|
|
|
if (!$added) {
|
|
DUP_Log::error("Couldn't add file $objectPath to archive", '', false);
|
|
$success = false;
|
|
break;
|
|
}
|
|
}
|
|
@closedir($fp);
|
|
}
|
|
|
|
if ($success) {
|
|
return true;
|
|
} else {
|
|
DUP_Log::error("Couldn't add folder $directoryPath to archive", '', false);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
public static function extractFiles($archiveFilepath, $relativeFilesToExtract, $destinationDirectory, $useShellUnZip)
|
|
{
|
|
// TODO: Unzip using either shell unzip or ziparchive
|
|
if ($useShellUnZip) {
|
|
$shellExecPath = escapeshellcmd(DUPX_Server::get_unzip_filepath());
|
|
$escapedFiles = array_map('escapeshellarg', $relativeFilesToExtract);
|
|
$filenameString = implode(' ', $escapedFiles);
|
|
$safeArchivePath = escapeshellarg($archiveFilepath);
|
|
$safeDestination = escapeshellarg($destinationDirectory);
|
|
$command = "{$shellExecPath} -o -qq {$safeArchivePath} {$filenameString} -d {$safeDestination} 2>&1";
|
|
$stderr = shell_exec($command);
|
|
if ($stderr != '') {
|
|
$errorMessage = __("Error extracting {$archiveFilepath}): {$stderr}", 'duplicator');
|
|
throw new Exception($errorMessage);
|
|
}
|
|
} else {
|
|
$zipArchive = new ZipArchive();
|
|
$result = $zipArchive->open($archiveFilepath);
|
|
if ($result !== true) {
|
|
throw new Exception("Error opening {$archiveFilepath} when extracting.");
|
|
}
|
|
|
|
$result = $zipArchive->extractTo($destinationDirectory, $relativeFilesToExtract);
|
|
if ($result === false) {
|
|
throw new Exception("Error extracting {$archiveFilepath}.");
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a directory to an existing ZipArchive object
|
|
*
|
|
* @param string $sourceFilePath The file to add to the zip file
|
|
* @param string $zipFilePath The zip file to be added to
|
|
* @param bool $deleteOld Delete the zip file before adding a file
|
|
* @param string $newName Rename the $sourceFile if needed
|
|
*
|
|
* @return bool Returns true if the file was added to the zip file
|
|
*/
|
|
public static function zipFile($sourceFilePath, $zipFilePath, $deleteOld, $newName, $isCompressed)
|
|
{
|
|
if ($deleteOld && file_exists($zipFilePath)) {
|
|
SnapIO::unlink($zipFilePath);
|
|
}
|
|
|
|
if (file_exists($sourceFilePath)) {
|
|
$zip_archive = new ZipArchive();
|
|
$is_zip_open = ($zip_archive->open($zipFilePath, ZIPARCHIVE::CREATE) === true);
|
|
if ($is_zip_open === false) {
|
|
DUP_Log::error("Cannot create zip archive {$zipFilePath}");
|
|
} else {
|
|
//ADD SQL
|
|
if ($newName == null) {
|
|
$source_filename = basename($sourceFilePath);
|
|
DUP_Log::Info("adding {$source_filename}");
|
|
} else {
|
|
$source_filename = $newName;
|
|
DUP_Log::Info("new name added {$newName}");
|
|
}
|
|
|
|
$in_zip = DUP_Zip_U::addFileToZipArchive($zip_archive, $sourceFilePath, $source_filename, $isCompressed);
|
|
if ($in_zip === false) {
|
|
DUP_Log::error("Unable to add {$sourceFilePath} to $zipFilePath");
|
|
}
|
|
|
|
$zip_archive->close();
|
|
return true;
|
|
}
|
|
} else {
|
|
DUP_Log::error("Trying to add {$sourceFilePath} to a zip but it doesn't exist!");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static function addFileToZipArchive($zipArchive, $filepath, $localName, $isCompressed)
|
|
{
|
|
$added = $zipArchive->addFile($filepath, $localName);
|
|
return $added;
|
|
}
|
|
}
|