Completed
Push — master ( dcddf7...d2fb4d )
by Théo
05:16 queued 03:22
created

Configuration::retrieveWhitelist()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 32
Code Lines 17

Duplication

Lines 32
Ratio 100 %

Importance

Changes 0
Metric Value
cc 5
eloc 17
nc 5
nop 1
dl 32
loc 32
rs 8.439
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the humbug/php-scoper package.
7
 *
8
 * Copyright (c) 2017 Théo FIDRY <[email protected]>,
9
 *                    Pádraic Brady <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Humbug\PhpScoper\Console;
16
17
use InvalidArgumentException;
18
use Symfony\Component\Finder\Finder;
19
20
final class Configuration
21
{
22
    /** @internal */
23
    const FINDER_KEYWORD = 'finders';
24
25
    /** @internal */
26
    const PATCHERS_KEYWORD = 'patchers';
27
28
    /** @internal */
29
    const WHITELIST_KEYWORD = 'whitelist';
30
31
    /** @internal */
32
    const GLOBAL_NAMESPACE_KEYWORD = 'global_namespace_whitelist';
33
34
    /** @internal */
35
    const KEYWORDS = [
36
        self::FINDER_KEYWORD,
37
        self::PATCHERS_KEYWORD,
38
        self::WHITELIST_KEYWORD,
39
        self::GLOBAL_NAMESPACE_KEYWORD,
40
    ];
41
42
    private $path;
43
    private $patchers;
44
    private $finders;
45
    private $whitelist;
46
    private $globalNamespaceWhitelisters;
47
48
    /**
49
     * @param string|null $path Absolute path to the configuration file.
50
     *
51
     * @return self
52
     */
53
    public static function load(string $path = null): self
54
    {
55
        if (null === $path) {
56
            return new self(null, [], [], [], []);
57
        }
58
59
        $config = include $path;
60
61
        if (false === is_array($config)) {
62
            throw new InvalidArgumentException(
63
                sprintf(
64
                    'Expected configuration to be an array, found "%s" instead.',
65
                    gettype($config)
66
                )
67
            );
68
        }
69
70
        self::validateConfigKeys($config);
71
72
        $finders = self::retrieveFinders($config);
73
        $patchers = self::retrievePatchers($config);
74
        $whitelist = self::retrieveWhitelist($config);
75
        $globalNamespace = self::retrieveGlobalNamespaceWhitelisters($config);
76
77
        return new self($path, $finders, $patchers, $whitelist, $globalNamespace);
78
    }
79
80
    /**
81
     * @param string|null         $path            Absolute path to the configuration file loaded.
82
     * @param Finder[]            $finders         List of finders which will provide the files that will be scoped.
83
     * @param callable[]          $patchers        List of closures which can alter the content of the files being
84
     *                                             scoped.
85
     * @param string[]            $whitelist       List of classes that will not be scoped.
86
     * @param callable[]|string[] $globalNamespace List of class names from the global namespace that should be scoped
87
     *                                             or closures filtering if the class should be scoped or not.
88
     */
89
    private function __construct(
90
        string $path = null,
91
        array $finders,
92
        array $patchers,
93
        array $whitelist,
94
        array $globalNamespace
95
    ) {
96
        $this->path = $path;
97
        $this->patchers = $patchers;
98
        $this->finders = $finders;
99
        $this->whitelist = $whitelist;
100
        $this->globalNamespaceWhitelisters = $globalNamespace;
101
    }
102
103
    public function getPath(): string
104
    {
105
        return $this->path;
106
    }
107
108
    /**
109
     * @return Finder[]
110
     */
111
    public function getFinders(): array
112
    {
113
        return $this->finders;
114
    }
115
116
    /**
117
     * @return callable[]
118
     */
119
    public function getPatchers(): array
120
    {
121
        return $this->patchers;
122
    }
123
124
    public function getWhitelist(): array
125
    {
126
        return $this->whitelist;
127
    }
128
129
    /**
130
     * @return callable[]|string[]
131
     */
132
    public function getGlobalNamespaceWhitelisters()
133
    {
134
        return $this->globalNamespaceWhitelisters;
135
    }
136
137
    private static function validateConfigKeys(array $config)
138
    {
139
        array_map(
140
            ['self', 'validateConfigKey'],
141
            array_keys($config)
142
        );
143
    }
144
145
    private static function validateConfigKey(string $key)
146
    {
147
        if (false === in_array($key, self::KEYWORDS)) {
148
            throw new InvalidArgumentException(
149
                sprintf(
150
                    'Invalid configuration key value "%s" found.',
151
                    $key
152
                )
153
            );
154
        }
155
    }
156
157
    private static function retrieveFinders(array $config): array
158
    {
159
        if (false === array_key_exists(self::FINDER_KEYWORD, $config)) {
160
            return [];
161
        }
162
163
        $finders = $config[self::FINDER_KEYWORD];
164
165
        if (false === is_array($finders)) {
166
            throw new InvalidArgumentException(
167
                sprintf(
168
                    'Expected finders to be an array of "%s", found "%s" instead.',
169
                    Finder::class,
170
                    gettype($finders)
171
                )
172
            );
173
        }
174
175
        foreach ($finders as $index => $finder) {
176
            if ($finder instanceof Finder) {
177
                continue;
178
            }
179
180
            throw new InvalidArgumentException(
181
                sprintf(
182
                    'Expected finders to be an array of "%s", the "%d" element is not.',
183
                    Finder::class,
184
                    $index
185
                )
186
            );
187
        }
188
189
        return $finders;
190
    }
191
192 View Code Duplication
    private static function retrievePatchers(array $config): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
193
    {
194
        if (false === array_key_exists(self::PATCHERS_KEYWORD, $config)) {
195
            return [];
196
        }
197
198
        $patchers = $config[self::PATCHERS_KEYWORD];
199
200
        if (false === is_array($patchers)) {
201
            throw new InvalidArgumentException(
202
                sprintf(
203
                    'Expected patchers to be an array of callables, found "%s" instead.',
204
                    gettype($patchers)
205
                )
206
            );
207
        }
208
209
        foreach ($patchers as $index => $patcher) {
210
            if (is_callable($patcher)) {
211
                continue;
212
            }
213
214
            throw new InvalidArgumentException(
215
                sprintf(
216
                    'Expected patchers to be an array of callables, the "%d" element is not.',
217
                    $index
218
                )
219
            );
220
        }
221
222
        return $patchers;
223
    }
224
225 View Code Duplication
    private static function retrieveWhitelist(array $config): array
226
    {
227
        if (false === array_key_exists(self::WHITELIST_KEYWORD, $config)) {
228
            return [];
229
        }
230
231
        $whitelist = $config[self::WHITELIST_KEYWORD];
232
233
        if (false === is_array($whitelist)) {
234
            throw new InvalidArgumentException(
235
                sprintf(
236
                    'Expected whitelist to be an array of strings, found "%s" instead.',
237
                    gettype($whitelist)
238
                )
239
            );
240
        }
241
242
        foreach ($whitelist as $index => $className) {
243
            if (is_string($className)) {
244
                continue;
245
            }
246
247
            throw new InvalidArgumentException(
248
                sprintf(
249
                    'Expected whitelist to be an array of string, the "%d" element is not.',
250
                    $index
251
                )
252
            );
253
        }
254
255
        return $whitelist;
256
    }
257
258 View Code Duplication
    private static function retrieveGlobalNamespaceWhitelisters(array $config): array
259
    {
260
        if (false === array_key_exists(self::GLOBAL_NAMESPACE_KEYWORD, $config)) {
261
            return [];
262
        }
263
264
        $globalNamespace = $config[self::GLOBAL_NAMESPACE_KEYWORD];
265
266
        if (false === is_array($globalNamespace)) {
267
            throw new InvalidArgumentException(
268
                sprintf(
269
                    'Expected "global_namespace" to be an array, found "%s" instead.',
270
                    gettype($globalNamespace)
271
                )
272
            );
273
        }
274
275
        foreach ($globalNamespace as $index => $className) {
276
            if (is_string($className) || is_callable($className)) {
277
                continue;
278
            }
279
280
            throw new InvalidArgumentException(
281
                sprintf(
282
                    'Expected "global_namespace" to be an array of callables or strings, the "%d" element '
283
                    .'is not.',
284
                    $index
285
                )
286
            );
287
        }
288
289
        return $globalNamespace;
290
    }
291
}
292