273 lines
6.8 KiB
PHP
273 lines
6.8 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of Zippy.
|
|
*
|
|
* (c) Alchemy <info@alchemy.fr>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*
|
|
*/
|
|
|
|
namespace Alchemy\Zippy\Adapter;
|
|
|
|
use Alchemy\Zippy\Adapter\Resource\ResourceInterface;
|
|
use Alchemy\Zippy\Adapter\VersionProbe\VersionProbeInterface;
|
|
use Alchemy\Zippy\Archive\Archive;
|
|
use Alchemy\Zippy\Archive\ArchiveInterface;
|
|
use Alchemy\Zippy\Exception\RuntimeException;
|
|
use Alchemy\Zippy\Exception\InvalidArgumentException;
|
|
use Alchemy\Zippy\Resource\PathUtil;
|
|
use Alchemy\Zippy\Resource\ResourceManager;
|
|
|
|
abstract class AbstractAdapter implements AdapterInterface
|
|
{
|
|
/** @var ResourceManager */
|
|
protected $manager;
|
|
|
|
/**
|
|
* The version probe
|
|
*
|
|
* @var VersionProbeInterface
|
|
*/
|
|
protected $probe;
|
|
|
|
public function __construct(ResourceManager $manager)
|
|
{
|
|
$this->manager = $manager;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function open($path)
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return new Archive($this->createResource($path), $this, $this->manager);
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function create($path, $files = null, $recursive = true)
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return $this->doCreate($this->makeTargetAbsolute($path), $files, $recursive);
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function listMembers(ResourceInterface $resource)
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return $this->doListMembers($resource);
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function add(ResourceInterface $resource, $files, $recursive = true)
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return $this->doAdd($resource, $files, $recursive);
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function remove(ResourceInterface $resource, $files)
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return $this->doRemove($resource, $files);
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function extract(ResourceInterface $resource, $to = null)
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return $this->doExtract($resource, $to);
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function extractMembers(ResourceInterface $resource, $members, $to = null, $overwrite = false)
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return $this->doExtractMembers($resource, $members, $to, $overwrite);
|
|
}
|
|
|
|
/**
|
|
* Returns the version probe used by this adapter
|
|
*
|
|
* @return VersionProbeInterface
|
|
*/
|
|
public function getVersionProbe()
|
|
{
|
|
return $this->probe;
|
|
}
|
|
|
|
/**
|
|
* Sets the version probe used by this adapter
|
|
*
|
|
* @param VersionProbeInterface $probe
|
|
*
|
|
* @return VersionProbeInterface
|
|
*/
|
|
public function setVersionProbe(VersionProbeInterface $probe)
|
|
{
|
|
$this->probe = $probe;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function isSupported()
|
|
{
|
|
if (!$this->probe) {
|
|
throw new RuntimeException(sprintf(
|
|
'No version probe has been set on %s whereas it is required', get_class($this)
|
|
));
|
|
}
|
|
|
|
return VersionProbeInterface::PROBE_OK === $this->probe->getStatus();
|
|
}
|
|
|
|
/**
|
|
* Throws an exception is the current adapter is not supported
|
|
*
|
|
* @throws RuntimeException
|
|
*/
|
|
protected function requireSupport()
|
|
{
|
|
if (false === $this->isSupported()) {
|
|
throw new RuntimeException(sprintf('%s is not supported on your system', get_class($this)));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Change current working directory to another
|
|
*
|
|
* @param string $target the target directory
|
|
*
|
|
* @return AdapterInterface
|
|
*
|
|
* @throws RuntimeException In case of failure
|
|
*/
|
|
protected function chdir($target)
|
|
{
|
|
if (false === @chdir($target)) {
|
|
throw new RuntimeException(sprintf('Unable to chdir to `%s`', $target));
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Creates a resource given a path
|
|
*
|
|
* @param string $path
|
|
*
|
|
* @return ResourceInterface
|
|
*/
|
|
abstract protected function createResource($path);
|
|
|
|
/**
|
|
* Do the removal after having check that the current adapter is supported
|
|
*
|
|
* @param ResourceInterface $resource
|
|
* @param array $files
|
|
*
|
|
* @return array
|
|
*/
|
|
abstract protected function doRemove(ResourceInterface $resource, $files);
|
|
|
|
/**
|
|
* Do the add after having check that the current adapter is supported
|
|
*
|
|
* @param ResourceInterface $resource
|
|
* @param array $files
|
|
* @param bool $recursive
|
|
*
|
|
* @return array
|
|
*/
|
|
abstract protected function doAdd(ResourceInterface $resource, $files, $recursive);
|
|
|
|
/**
|
|
* Do the extract after having check that the current adapter is supported
|
|
*
|
|
* @param ResourceInterface $resource
|
|
* @param $to
|
|
*
|
|
* @return \SplFileInfo The extracted archive
|
|
*/
|
|
abstract protected function doExtract(ResourceInterface $resource, $to);
|
|
|
|
/**
|
|
* Do the extract members after having check that the current adapter is supported
|
|
*
|
|
* @param ResourceInterface $resource
|
|
* @param string|string[] $members
|
|
* @param string $to
|
|
* @param bool $overwrite
|
|
*
|
|
* @return \SplFileInfo The extracted archive
|
|
*/
|
|
abstract protected function doExtractMembers(ResourceInterface $resource, $members, $to, $overwrite = false);
|
|
|
|
/**
|
|
* Do the list members after having check that the current adapter is supported
|
|
*
|
|
* @param ResourceInterface $resource
|
|
*
|
|
* @return array
|
|
*/
|
|
abstract protected function doListMembers(ResourceInterface $resource);
|
|
|
|
/**
|
|
* Do the create after having check that the current adapter is supported
|
|
*
|
|
* @param string $path
|
|
* @param string $file
|
|
* @param bool $recursive
|
|
*
|
|
* @return ArchiveInterface
|
|
*/
|
|
abstract protected function doCreate($path, $file, $recursive);
|
|
|
|
/**
|
|
* Makes the target path absolute as the adapters might have a different directory
|
|
*
|
|
* @param string $path The path to convert
|
|
*
|
|
* @return string The absolute path
|
|
*
|
|
* @throws InvalidArgumentException In case the path is not writable or does not exist
|
|
*/
|
|
private function makeTargetAbsolute($path)
|
|
{
|
|
$directory = dirname($path);
|
|
|
|
if (!is_dir($directory)) {
|
|
throw new InvalidArgumentException(sprintf('Target path %s does not exist.', $directory));
|
|
}
|
|
if (!is_writable($directory)) {
|
|
throw new InvalidArgumentException(sprintf('Target path %s is not writeable.', $directory));
|
|
}
|
|
|
|
return realpath($directory) . '/' . PathUtil::basename($path);
|
|
}
|
|
}
|