scratch – Blame information for rev 120

Subversion Repositories:
Rev:
Rev Author Line No. Line
120 office 1 <?php
2  
3 /*
4 * This file is part of Alchemy\BinaryDriver.
5 *
6 * (c) Alchemy <info@alchemy.fr>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11  
12 namespace Alchemy\BinaryDriver;
13  
14 use Alchemy\BinaryDriver\Exception\ExecutableNotFoundException;
15 use Alchemy\BinaryDriver\Exception\ExecutionFailureException;
16 use Alchemy\BinaryDriver\Listeners\Listeners;
17 use Alchemy\BinaryDriver\Listeners\ListenerInterface;
18 use Evenement\EventEmitter;
19 use Monolog\Logger;
20 use Monolog\Handler\NullHandler;
21 use Psr\Log\LoggerInterface;
22 use Symfony\Component\Process\ExecutableFinder;
23 use Symfony\Component\Process\Process;
24  
25 abstract class AbstractBinary extends EventEmitter implements BinaryInterface
26 {
27 /** @var ConfigurationInterface */
28 protected $configuration;
29  
30 /** @var ProcessBuilderFactoryInterface */
31 protected $factory;
32  
33 /** @var ProcessRunner */
34 private $processRunner;
35  
36 /** @var Listeners */
37 private $listenersManager;
38  
39 public function __construct(ProcessBuilderFactoryInterface $factory, LoggerInterface $logger, ConfigurationInterface $configuration)
40 {
41 $this->factory = $factory;
42 $this->configuration = $configuration;
43 $this->processRunner = new ProcessRunner($logger, $this->getName());
44 $this->listenersManager = new Listeners();
45 $this->applyProcessConfiguration();
46 }
47  
48 /**
49 * {@inheritdoc}
50 */
51 public function listen(ListenerInterface $listener)
52 {
53 $this->listenersManager->register($listener, $this);
54  
55 return $this;
56 }
57  
58 /**
59 * {@inheritdoc}
60 */
61 public function unlisten(ListenerInterface $listener)
62 {
63 $this->listenersManager->unregister($listener, $this);
64  
65 return $this;
66 }
67  
68 /**
69 * {@inheritdoc}
70 */
71 public function getConfiguration()
72 {
73 return $this->configuration;
74 }
75  
76 /**
77 * {@inheritdoc}
78 *
79 * @return BinaryInterface
80 */
81 public function setConfiguration(ConfigurationInterface $configuration)
82 {
83 $this->configuration = $configuration;
84 $this->applyProcessConfiguration();
85  
86 return $this;
87 }
88  
89 /**
90 * {@inheritdoc}
91 */
92 public function getProcessBuilderFactory()
93 {
94 return $this->factory;
95 }
96  
97 /**
98 * {@inheritdoc}
99 *
100 * @return BinaryInterface
101 */
102 public function setProcessBuilderFactory(ProcessBuilderFactoryInterface $factory)
103 {
104 $this->factory = $factory;
105 $this->applyProcessConfiguration();
106  
107 return $this;
108 }
109  
110 /**
111 * {@inheritdoc}
112 */
113 public function getProcessRunner()
114 {
115 return $this->processRunner;
116 }
117  
118 /**
119 * {@inheritdoc}
120 */
121 public function setProcessRunner(ProcessRunnerInterface $runner)
122 {
123 $this->processRunner = $runner;
124  
125 return $this;
126 }
127  
128 /**
129 * {@inheritdoc}
130 */
131 public function command($command, $bypassErrors = false, $listeners = null)
132 {
133 if (!is_array($command)) {
134 $command = array($command);
135 }
136  
137 return $this->run($this->factory->create($command), $bypassErrors, $listeners);
138 }
139  
140 /**
141 * {@inheritdoc}
142 */
143 public static function load($binaries, LoggerInterface $logger = null, $configuration = array())
144 {
145 $finder = new ExecutableFinder();
146 $binary = null;
147 $binaries = is_array($binaries) ? $binaries : array($binaries);
148  
149 foreach ($binaries as $candidate) {
150 if (file_exists($candidate) && is_executable($candidate)) {
151 $binary = $candidate;
152 break;
153 }
154 if (null !== $binary = $finder->find($candidate)) {
155 break;
156 }
157 }
158  
159 if (null === $binary) {
160 throw new ExecutableNotFoundException(sprintf(
161 'Executable not found, proposed : %s', implode(', ', $binaries)
162 ));
163 }
164  
165 if (null === $logger) {
166 $logger = new Logger(__NAMESPACE__ . ' logger');
167 $logger->pushHandler(new NullHandler());
168 }
169  
170 $configuration = $configuration instanceof ConfigurationInterface ? $configuration : new Configuration($configuration);
171  
172 return new static(new ProcessBuilderFactory($binary), $logger, $configuration);
173 }
174  
175 /**
176 * Returns the name of the driver
177 *
178 * @return string
179 */
180 abstract public function getName();
181  
182 /**
183 * Executes a process, logs events
184 *
185 * @param Process $process
186 * @param Boolean $bypassErrors Set to true to disable throwing ExecutionFailureExceptions
187 * @param ListenerInterface|array $listeners A listener or an array of listener to register for this unique run
188 *
189 * @return string The Process output
190 *
191 * @throws ExecutionFailureException in case of process failure.
192 */
193 protected function run(Process $process, $bypassErrors = false, $listeners = null)
194 {
195 if (null !== $listeners) {
196 if (!is_array($listeners)) {
197 $listeners = array($listeners);
198 }
199  
200 $listenersManager = clone $this->listenersManager;
201  
202 foreach ($listeners as $listener) {
203 $listenersManager->register($listener, $this);
204 }
205 } else {
206 $listenersManager = $this->listenersManager;
207 }
208  
209 return $this->processRunner->run($process, $listenersManager->storage, $bypassErrors);
210 }
211  
212 private function applyProcessConfiguration()
213 {
214 if ($this->configuration->has('timeout')) {
215 $this->factory->setTimeout($this->configuration->get('timeout'));
216 }
217  
218 return $this;
219 }
220 }