240 lines
6.4 KiB
PHP
240 lines
6.4 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\FileResource;
|
|
use Alchemy\Zippy\Archive\MemberInterface;
|
|
use Alchemy\Zippy\Exception\RuntimeException;
|
|
use Alchemy\Zippy\Exception\InvalidArgumentException;
|
|
use Alchemy\Zippy\Parser\ParserFactory;
|
|
use Alchemy\Zippy\Parser\ParserInterface;
|
|
use Alchemy\Zippy\ProcessBuilder\ProcessBuilderFactory;
|
|
use Alchemy\Zippy\ProcessBuilder\ProcessBuilderFactoryInterface;
|
|
use Alchemy\Zippy\Resource\ResourceManager;
|
|
use Symfony\Component\Process\ExecutableFinder;
|
|
use Symfony\Component\Process\ProcessBuilder;
|
|
|
|
abstract class AbstractBinaryAdapter extends AbstractAdapter implements BinaryAdapterInterface
|
|
{
|
|
/**
|
|
* The parser to use to parse command output
|
|
*
|
|
* @var ParserInterface
|
|
*/
|
|
protected $parser;
|
|
|
|
/**
|
|
* The deflator process builder factory to use to build binary command line
|
|
*
|
|
* @var ProcessBuilderFactoryInterface
|
|
*/
|
|
protected $deflator;
|
|
|
|
/**
|
|
* The inflator process builder factory to use to build binary command line
|
|
*
|
|
* @var ProcessBuilderFactoryInterface
|
|
*/
|
|
protected $inflator;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param ParserInterface $parser An output parser
|
|
* @param ResourceManager $manager A resource manager
|
|
* @param ProcessBuilderFactoryInterface $inflator A process builder factory for the inflator binary
|
|
* @param ProcessBuilderFactoryInterface $deflator A process builder factory for the deflator binary
|
|
*/
|
|
public function __construct(
|
|
ParserInterface $parser,
|
|
ResourceManager $manager,
|
|
ProcessBuilderFactoryInterface $inflator,
|
|
ProcessBuilderFactoryInterface $deflator
|
|
) {
|
|
$this->parser = $parser;
|
|
parent::__construct($manager);
|
|
$this->deflator = $deflator;
|
|
$this->inflator = $inflator;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function getParser()
|
|
{
|
|
return $this->parser;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function setParser(ParserInterface $parser)
|
|
{
|
|
$this->parser = $parser;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function getDeflator()
|
|
{
|
|
return $this->deflator;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function getInflator()
|
|
{
|
|
return $this->inflator;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function setDeflator(ProcessBuilderFactoryInterface $processBuilder)
|
|
{
|
|
$this->deflator = $processBuilder;
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function setInflator(ProcessBuilderFactoryInterface $processBuilder)
|
|
{
|
|
$this->inflator = $processBuilder;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function getInflatorVersion()
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return $this->doGetInflatorVersion();
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function getDeflatorVersion()
|
|
{
|
|
$this->requireSupport();
|
|
|
|
return $this->doGetDeflatorVersion();
|
|
}
|
|
|
|
/**
|
|
* Returns a new instance of the invoked adapter
|
|
*
|
|
* @param ExecutableFinder $finder
|
|
* @param ResourceManager $manager
|
|
* @param string|null $inflatorBinaryName The inflator binary name to use
|
|
* @param string|null $deflatorBinaryName The deflator binary name to use
|
|
*
|
|
* @return AbstractBinaryAdapter
|
|
*/
|
|
public static function newInstance(
|
|
ExecutableFinder $finder,
|
|
ResourceManager $manager,
|
|
$inflatorBinaryName = null,
|
|
$deflatorBinaryName = null
|
|
) {
|
|
$inflator = $inflatorBinaryName instanceof ProcessBuilderFactoryInterface ? $inflatorBinaryName : self::findABinary($inflatorBinaryName,
|
|
static::getDefaultInflatorBinaryName(), $finder);
|
|
$deflator = $deflatorBinaryName instanceof ProcessBuilderFactoryInterface ? $deflatorBinaryName : self::findABinary($deflatorBinaryName,
|
|
static::getDefaultDeflatorBinaryName(), $finder);
|
|
|
|
try {
|
|
$outputParser = ParserFactory::create(static::getName());
|
|
} catch (InvalidArgumentException $e) {
|
|
throw new RuntimeException(sprintf(
|
|
'Failed to get a new instance of %s',
|
|
get_called_class()), $e->getCode(), $e
|
|
);
|
|
}
|
|
|
|
if (null === $inflator) {
|
|
throw new RuntimeException(sprintf('Unable to create the inflator'));
|
|
}
|
|
|
|
if (null === $deflator) {
|
|
throw new RuntimeException(sprintf('Unable to create the deflator'));
|
|
}
|
|
|
|
return new static($outputParser, $manager, $inflator, $deflator);
|
|
}
|
|
|
|
private static function findABinary($wish, array $defaults, ExecutableFinder $finder)
|
|
{
|
|
$possibles = $wish ? (array) $wish : $defaults;
|
|
|
|
$binary = null;
|
|
|
|
foreach ($possibles as $possible) {
|
|
if (null !== $found = $finder->find($possible)) {
|
|
$binary = new ProcessBuilderFactory($found);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $binary;
|
|
}
|
|
|
|
/**
|
|
* Adds files to argument list
|
|
*
|
|
* @param MemberInterface[]|\SplFileInfo[]|string[] $files An array of files
|
|
* @param ProcessBuilder $builder A Builder instance
|
|
*
|
|
* @return bool
|
|
*/
|
|
protected function addBuilderFileArgument(array $files, ProcessBuilder $builder)
|
|
{
|
|
$iterations = 0;
|
|
|
|
array_walk($files, function($file) use ($builder, &$iterations) {
|
|
$builder->add(
|
|
$file instanceof \SplFileInfo ?
|
|
$file->getRealPath() : ($file instanceof MemberInterface ? $file->getLocation() : $file)
|
|
);
|
|
|
|
$iterations++;
|
|
});
|
|
|
|
return 0 !== $iterations;
|
|
}
|
|
|
|
protected function createResource($path)
|
|
{
|
|
return new FileResource($path);
|
|
}
|
|
|
|
/**
|
|
* Fetch the inflator version after having check that the current adapter is supported
|
|
*
|
|
* @return string
|
|
*/
|
|
abstract protected function doGetInflatorVersion();
|
|
|
|
/**
|
|
* Fetch the Deflator version after having check that the current adapter is supported
|
|
*
|
|
* @return string
|
|
*/
|
|
abstract protected function doGetDeflatorVersion();
|
|
}
|