Version 1
[yaffs-website] / vendor / alchemy / zippy / src / Adapter / AbstractBinaryAdapter.php
1 <?php
2
3 /*
4  * This file is part of Zippy.
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
13 namespace Alchemy\Zippy\Adapter;
14
15 use Alchemy\Zippy\Adapter\Resource\FileResource;
16 use Alchemy\Zippy\Archive\MemberInterface;
17 use Alchemy\Zippy\Exception\RuntimeException;
18 use Alchemy\Zippy\Exception\InvalidArgumentException;
19 use Alchemy\Zippy\Parser\ParserFactory;
20 use Alchemy\Zippy\Parser\ParserInterface;
21 use Alchemy\Zippy\ProcessBuilder\ProcessBuilderFactory;
22 use Alchemy\Zippy\ProcessBuilder\ProcessBuilderFactoryInterface;
23 use Alchemy\Zippy\Resource\ResourceManager;
24 use Symfony\Component\Process\ExecutableFinder;
25 use Symfony\Component\Process\ProcessBuilder;
26
27 abstract class AbstractBinaryAdapter extends AbstractAdapter implements BinaryAdapterInterface
28 {
29     /**
30      * The parser to use to parse command output
31      *
32      * @var ParserInterface
33      */
34     protected $parser;
35
36     /**
37      * The deflator process builder factory to use to build binary command line
38      *
39      * @var ProcessBuilderFactoryInterface
40      */
41     protected $deflator;
42
43     /**
44      * The inflator process builder factory to use to build binary command line
45      *
46      * @var ProcessBuilderFactoryInterface
47      */
48     protected $inflator;
49
50     /**
51      * Constructor
52      *
53      * @param ParserInterface $parser An output parser
54      * @param ResourceManager $manager A resource manager
55      * @param ProcessBuilderFactoryInterface $inflator A process builder factory for the inflator binary
56      * @param ProcessBuilderFactoryInterface $deflator A process builder factory for the deflator binary
57      */
58     public function __construct(
59         ParserInterface $parser,
60         ResourceManager $manager,
61         ProcessBuilderFactoryInterface $inflator,
62         ProcessBuilderFactoryInterface $deflator
63     ) {
64         $this->parser = $parser;
65         parent::__construct($manager);
66         $this->deflator = $deflator;
67         $this->inflator = $inflator;
68     }
69
70     /**
71      * @inheritdoc
72      */
73     public function getParser()
74     {
75         return $this->parser;
76     }
77
78     /**
79      * @inheritdoc
80      */
81     public function setParser(ParserInterface $parser)
82     {
83         $this->parser = $parser;
84
85         return $this;
86     }
87
88     /**
89      * @inheritdoc
90      */
91     public function getDeflator()
92     {
93         return $this->deflator;
94     }
95
96     /**
97      * @inheritdoc
98      */
99     public function getInflator()
100     {
101         return $this->inflator;
102     }
103
104     /**
105      * @inheritdoc
106      */
107     public function setDeflator(ProcessBuilderFactoryInterface $processBuilder)
108     {
109         $this->deflator = $processBuilder;
110
111         return $this;
112     }
113
114     public function setInflator(ProcessBuilderFactoryInterface $processBuilder)
115     {
116         $this->inflator = $processBuilder;
117
118         return $this;
119     }
120
121     /**
122      * @inheritdoc
123      */
124     public function getInflatorVersion()
125     {
126         $this->requireSupport();
127
128         return $this->doGetInflatorVersion();
129     }
130
131     /**
132      * @inheritdoc
133      */
134     public function getDeflatorVersion()
135     {
136         $this->requireSupport();
137
138         return $this->doGetDeflatorVersion();
139     }
140
141     /**
142      * Returns a new instance of the invoked adapter
143      *
144      * @param ExecutableFinder $finder
145      * @param ResourceManager  $manager
146      * @param string|null      $inflatorBinaryName The inflator binary name to use
147      * @param string|null      $deflatorBinaryName The deflator binary name to use
148      *
149      * @return AbstractBinaryAdapter
150      */
151     public static function newInstance(
152         ExecutableFinder $finder,
153         ResourceManager $manager,
154         $inflatorBinaryName = null,
155         $deflatorBinaryName = null
156     ) {
157         $inflator = $inflatorBinaryName instanceof ProcessBuilderFactoryInterface ? $inflatorBinaryName : self::findABinary($inflatorBinaryName,
158             static::getDefaultInflatorBinaryName(), $finder);
159         $deflator = $deflatorBinaryName instanceof ProcessBuilderFactoryInterface ? $deflatorBinaryName : self::findABinary($deflatorBinaryName,
160             static::getDefaultDeflatorBinaryName(), $finder);
161
162         try {
163             $outputParser = ParserFactory::create(static::getName());
164         } catch (InvalidArgumentException $e) {
165             throw new RuntimeException(sprintf(
166                 'Failed to get a new instance of %s',
167                 get_called_class()), $e->getCode(), $e
168             );
169         }
170
171         if (null === $inflator) {
172             throw new RuntimeException(sprintf('Unable to create the inflator'));
173         }
174
175         if (null === $deflator) {
176             throw new RuntimeException(sprintf('Unable to create the deflator'));
177         }
178
179         return new static($outputParser, $manager, $inflator, $deflator);
180     }
181
182     private static function findABinary($wish, array $defaults, ExecutableFinder $finder)
183     {
184         $possibles = $wish ? (array) $wish : $defaults;
185
186         $binary = null;
187
188         foreach ($possibles as $possible) {
189             if (null !== $found = $finder->find($possible)) {
190                 $binary = new ProcessBuilderFactory($found);
191                 break;
192             }
193         }
194
195         return $binary;
196     }
197
198     /**
199      * Adds files to argument list
200      *
201      * @param MemberInterface[]|\SplFileInfo[]|string[] $files   An array of files
202      * @param ProcessBuilder                            $builder A Builder instance
203      *
204      * @return bool
205      */
206     protected function addBuilderFileArgument(array $files, ProcessBuilder $builder)
207     {
208         $iterations = 0;
209
210         array_walk($files, function($file) use ($builder, &$iterations) {
211             $builder->add(
212                 $file instanceof \SplFileInfo ?
213                     $file->getRealPath() : ($file instanceof MemberInterface ? $file->getLocation() : $file)
214             );
215
216             $iterations++;
217         });
218
219         return 0 !== $iterations;
220     }
221
222     protected function createResource($path)
223     {
224         return new FileResource($path);
225     }
226
227     /**
228      * Fetch the inflator version after having check that the current adapter is supported
229      *
230      * @return string
231      */
232     abstract protected function doGetInflatorVersion();
233
234     /**
235      * Fetch the Deflator version after having check that the current adapter is supported
236      *
237      * @return string
238      */
239     abstract protected function doGetDeflatorVersion();
240 }