Completed
Pull Request — master (#132)
by
unknown
06:43 queued 04:56
created

AbstractBinaryAdapter::newInstance()   B

Complexity

Conditions 6
Paths 16

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 30
rs 8.8177
c 0
b 0
f 0
cc 6
nc 16
nop 4
1
<?php
2
3
/*
4
 * This file is part of Zippy.
5
 *
6
 * (c) Alchemy <[email protected]>
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\ProcessBuilder;
22
use Alchemy\Zippy\ProcessBuilder\ProcessBuilderFactory;
23
use Alchemy\Zippy\ProcessBuilder\ProcessBuilderFactoryInterface;
24
use Alchemy\Zippy\Resource\ResourceManager;
25
use Symfony\Component\Process\ExecutableFinder;
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);
0 ignored issues
show
Bug introduced by
It seems like $outputParser defined by \Alchemy\Zippy\Parser\Pa...eate(static::getName()) on line 163 can also be of type null; however, Alchemy\Zippy\Adapter\Ab...yAdapter::__construct() does only seem to accept object<Alchemy\Zippy\Parser\ParserInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
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
}
241