File: /var/www/vhosts/greenclinic.kz/test.greenclinic.kz/vendor/october/rain/src/Filesystem/Zip.php
<?php namespace October\Rain\Filesystem;
/**
* Zip helper
*
* @package october\filesystem
* @author Alexey Bobkov, Samuel Georges
*
* Usage:
*
* Zip::make('file.zip', '/some/path/*.php');
*
* Zip::make('file.zip', function($zip) {
*
* // Add all PHP files and directories
* $zip->add('/some/path/*.php');
*
* // Do not include subdirectories, one level only
* $zip->add('/non/recursive/*', ['recursive' => false]);
*
* // Add multiple paths
* $zip->add([
* '/collection/of/paths/*',
* '/a/single/file.php'
* ]);
*
* // Add all INI files to a zip folder "config"
* $zip->folder('/config', '/path/to/config/*.ini');
*
* // Add multiple paths to a zip folder "images"
* $zip->folder('/images', function($zip) {
* $zip->add('/my/gifs/*.gif', );
* $zip->add('/photo/reel/*.{png,jpg}', );
* });
*
* // Remove these files/folders from the zip
* $zip->remove([
* '.htaccess',
* 'config.php',
* 'some/folder'
* ]);
*
* });
*
* Zip::extract('file.zip', '/destination/path');
*
*/
use ZipArchive;
class Zip extends ZipArchive
{
/**
* @var string Folder prefix
*/
protected $folderPrefix = '';
/**
* Extract an existing zip file.
* @param string $source Path for the existing zip
* @param string $destination Path to extract the zip files
* @param array $options
* @return bool
*/
public static function extract($source, $destination, $options = [])
{
extract(array_merge([
'mask' => 0777
], $options));
if (file_exists($destination) || mkdir($destination, $mask, true)) {
$zip = new ZipArchive;
if ($zip->open($source) === true) {
$zip->extractTo($destination);
$zip->close();
return true;
}
}
return false;
}
/**
* Creates a new empty zip file.
* @param string $destination Path for the new zip
* @param mixed $source
* @param array $options
* @return self
*/
public static function make($destination, $source, $options = [])
{
$zip = new self;
$zip->open($destination, ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE);
if (is_string($source)) {
$zip->add($source, $options);
}
elseif (is_callable($source)) {
$source($zip);
}
elseif (is_array($source)) {
foreach ($source as $_source) {
$zip->add($_source, $options);
}
}
$zip->close();
return $zip;
}
/**
* Includes a source to the Zip
* @param mixed $source
* @param array $options
* @return self
*/
public function add($source, $options = [])
{
/*
* A directory has been supplied, convert it to a useful glob
*
* The wildcard for including hidden files:
* - isn't hidden with an '.'
* - is hidden with a '.' but is followed by a non '.' character
* - starts with '..' but has at least one character after it
*/
if (is_dir($source)) {
$includeHidden = isset($options['includeHidden']) && $options['includeHidden'];
$wildcard = $includeHidden ? '{*,.[!.]*,..?*}' : '*';
$source = implode('/', [dirname($source), basename($source), $wildcard]);
}
extract(array_merge([
'recursive' => true,
'includeHidden' => false,
'basedir' => dirname($source),
'baseglob' => basename($source)
], $options));
if (is_file($source)) {
$files = [$source];
$recursive = false;
}
else {
$files = glob($source, GLOB_BRACE);
$folders = glob(dirname($source) . '/*', GLOB_ONLYDIR);
}
foreach ($files as $file) {
if (!is_file($file)) {
continue;
}
$localpath = $this->removePathPrefix($basedir.'/', dirname($file).'/');
$localfile = $this->folderPrefix . $localpath . basename($file);
$this->addFile($file, $localfile);
}
if (!$recursive) {
return $this;
}
foreach ($folders as $folder) {
if (!is_dir($folder)) {
continue;
}
$localpath = $this->folderPrefix . $this->removePathPrefix($basedir.'/', $folder.'/');
$this->addEmptyDir($localpath);
$this->add($folder.'/'.$baseglob, array_merge($options, ['basedir' => $basedir]));
}
return $this;
}
/**
* Creates a new folder inside the Zip and adds source files (optional)
* @param string $name Folder name
* @param mixed $source
* @return self
*/
public function folder($name, $source = null)
{
$prefix = $this->folderPrefix;
$this->addEmptyDir($prefix . $name);
if ($source === null) {
return $this;
}
$this->folderPrefix = $prefix . $name . '/';
if (is_string($source)) {
$this->add($source);
}
elseif (is_callable($source)) {
$source($this);
}
elseif (is_array($source)) {
foreach ($source as $_source) {
$this->add($_source);
}
}
$this->folderPrefix = $prefix;
return $this;
}
/**
* Removes a file or folder from the zip collection.
* Does not support wildcards.
* @param string $source
* @return self
*/
public function remove($source)
{
if (is_array($source)) {
foreach ($source as $_source) {
$this->remove($_source);
}
}
if (!is_string($source)) {
return $this;
}
if (substr($source, 0, 1) == '/') {
$source = substr($source, 1);
}
for ($i = 0; $i < $this->numFiles; $i++) {
$stats = $this->statIndex($i);
if (substr($stats['name'], 0, strlen($source)) == $source) {
$this->deleteIndex($i);
}
}
return $this;
}
/**
* Removes a prefix from a path.
* @param string $prefix /var/sites/
* @param string $path /var/sites/moo/cow/
* @return string moo/cow/
*/
protected function removePathPrefix($prefix, $path)
{
return (strpos($path, $prefix) === 0)
? substr($path, strlen($prefix))
: $path;
}
}