187 lines
4.1 KiB
PHP
187 lines
4.1 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of Alchemy\BinaryDriver.
|
|
*
|
|
* (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\BinaryDriver;
|
|
|
|
use Alchemy\BinaryDriver\Exception\InvalidArgumentException;
|
|
use Symfony\Component\Process\Process;
|
|
use Symfony\Component\Process\ProcessBuilder;
|
|
|
|
class ProcessBuilderFactory implements ProcessBuilderFactoryInterface
|
|
{
|
|
/**
|
|
* The binary path
|
|
*
|
|
* @var String
|
|
*/
|
|
protected $binary;
|
|
|
|
/**
|
|
* The timeout for the generated processes
|
|
*
|
|
* @var integer|float
|
|
*/
|
|
private $timeout;
|
|
|
|
/**
|
|
* An internal ProcessBuilder.
|
|
*
|
|
* Note that this one is used only if Symfony ProcessBuilder has method
|
|
* setPrefix (2.3)
|
|
*
|
|
* @var ProcessBuilder
|
|
*/
|
|
private $builder;
|
|
|
|
/**
|
|
* Tells whether Symfony LTS ProcessBuilder should be emulated or not.
|
|
*
|
|
* This symfony version provided a brand new ::setPrefix method.
|
|
*
|
|
* @var Boolean
|
|
*/
|
|
public static $emulateSfLTS;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* @param String $binary The path to the binary
|
|
*
|
|
* @throws InvalidArgumentException In case binary path is invalid
|
|
*/
|
|
public function __construct($binary)
|
|
{
|
|
$this->detectEmulation();
|
|
|
|
if (!self::$emulateSfLTS) {
|
|
$this->builder = new ProcessBuilder();
|
|
}
|
|
|
|
$this->useBinary($binary);
|
|
}
|
|
|
|
/**
|
|
* Covenient method for unit testing
|
|
*
|
|
* @return type
|
|
*/
|
|
public function getBuilder()
|
|
{
|
|
return $this->builder;
|
|
}
|
|
|
|
/**
|
|
* Covenient method for unit testing
|
|
*
|
|
* @param ProcessBuilder $builder
|
|
* @return ProcessBuilderFactory
|
|
*/
|
|
public function setBuilder(ProcessBuilder $builder)
|
|
{
|
|
$this->builder = $builder;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function getBinary()
|
|
{
|
|
return $this->binary;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function useBinary($binary)
|
|
{
|
|
if (!is_executable($binary)) {
|
|
throw new InvalidArgumentException(sprintf('`%s` is not an executable binary', $binary));
|
|
}
|
|
|
|
$this->binary = $binary;
|
|
|
|
if (!static::$emulateSfLTS) {
|
|
$this->builder->setPrefix($binary);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function setTimeout($timeout)
|
|
{
|
|
$this->timeout = $timeout;
|
|
|
|
if (!static::$emulateSfLTS) {
|
|
$this->builder->setTimeout($this->timeout);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function getTimeout()
|
|
{
|
|
return $this->timeout;
|
|
}
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
public function create($arguments = array())
|
|
{
|
|
if (null === $this->binary) {
|
|
throw new InvalidArgumentException('No binary set');
|
|
}
|
|
|
|
if (!is_array($arguments)) {
|
|
$arguments = array($arguments);
|
|
}
|
|
|
|
if (static::$emulateSfLTS) {
|
|
array_unshift($arguments, $this->binary);
|
|
if (method_exists('Symfony\Component\Process\ProcessUtils', 'escapeArgument')) {
|
|
$script = implode(' ', array_map(array('Symfony\Component\Process\ProcessUtils', 'escapeArgument'), $arguments));
|
|
} else {
|
|
$script = $arguments;
|
|
}
|
|
|
|
$env = array_replace($_ENV, $_SERVER);
|
|
$env = array_filter($env, function ($value) {
|
|
return !is_array($value);
|
|
});
|
|
|
|
return new Process($script, null, $env, null, $this->timeout);
|
|
} else {
|
|
return $this->builder
|
|
->setArguments($arguments)
|
|
->getProcess();
|
|
}
|
|
}
|
|
|
|
private function detectEmulation()
|
|
{
|
|
if (null !== static::$emulateSfLTS) {
|
|
return $this;
|
|
}
|
|
|
|
static::$emulateSfLTS = !method_exists('Symfony\Component\Process\ProcessBuilder', 'setPrefix');
|
|
|
|
return $this;
|
|
}
|
|
}
|