Passed
Pull Request — master (#520)
by Théo
03:39 queued 01:36
created

retrieveExcludedNamespaces()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 66
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 38
c 1
b 0
f 0
nc 7
nop 1
dl 0
loc 66
rs 8.3786

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Humbug\PhpScoper;
6
7
use InvalidArgumentException;
8
use function array_key_exists;
9
use function array_keys;
10
use function array_values;
11
use function gettype;
12
use function is_array;
13
use function is_bool;
14
use function is_string;
15
use function Safe\sprintf;
16
17
final class ConfigurationWhitelistFactory
18
{
19
    private RegexChecker $regexChecker;
20
21
    public function __construct(RegexChecker $regexChecker)
22
    {
23
        $this->regexChecker = $regexChecker;
24
    }
25
26
    public function createWhitelist(array $config): Whitelist
27
    {
28
        [
29
            $excludedNamespaceRegexes,
30
            $excludedNamespaceNames,
31
        ] = $this->retrieveExcludedNamespaces($config);
32
33
        $exposedElements = self::retrieveExposedElements($config);
34
35
        $exposeGlobalConstants = self::retrieveExposeGlobalSymbol(
36
            $config,
37
            ConfigurationKeys::EXPOSE_GLOBAL_CONSTANTS_KEYWORD,
38
        );
39
        $exposeGlobalClasses = self::retrieveExposeGlobalSymbol(
40
            $config,
41
            ConfigurationKeys::EXPOSE_GLOBAL_CLASSES_KEYWORD,
42
        );
43
        $exposeGlobalFunctions = self::retrieveExposeGlobalSymbol(
44
            $config,
45
            ConfigurationKeys::EXPOSE_GLOBAL_FUNCTIONS_KEYWORD,
46
        );
47
48
        return Whitelist::create(
49
            $exposeGlobalConstants,
50
            $exposeGlobalClasses,
51
            $exposeGlobalFunctions,
52
            $excludedNamespaceRegexes,
53
            $excludedNamespaceNames,
54
            ...$exposedElements,
55
        );
56
    }
57
58
    /**
59
     * @return array{string[], string[]}
0 ignored issues
show
Documentation Bug introduced by
The doc comment array{string[], string[]} at position 2 could not be parsed: Expected ':' at position 2, but found 'string'.
Loading history...
60
     */
61
    private function retrieveExcludedNamespaces(array $config): array
62
    {
63
        $key = ConfigurationKeys::EXCLUDE_NAMESPACES_KEYWORD;
64
65
        if (!array_key_exists($key, $config)) {
66
            return [[], []];
67
        }
68
69
        $regexesAndNamespaceNames = $config[$key];
70
71
        if (!is_array($regexesAndNamespaceNames)) {
72
            throw new InvalidArgumentException(
73
                sprintf(
74
                    'Expected "%s" to be an array of strings, got "%s" instead.',
75
                    $key,
76
                    gettype($regexesAndNamespaceNames),
77
                ),
78
            );
79
        }
80
81
        // Store the strings in the keys for avoiding a unique check later on
82
        $regexes = [];
83
        $namespaceNames = [];
84
85
        foreach ($regexesAndNamespaceNames as $index => $regexOrNamespaceName) {
86
            if (!is_string($regexOrNamespaceName)) {
87
                throw new InvalidArgumentException(
88
                    sprintf(
89
                        'Expected "%s" to be an array of strings, got "%s" for the element with the index "%s".',
90
                        $key,
91
                        gettype($regexOrNamespaceName),
92
                        $index,
93
                    ),
94
                );
95
            }
96
97
            if (!$this->regexChecker->isRegexLike($regexOrNamespaceName)) {
98
                $namespaceNames[$regexOrNamespaceName] = null;
99
100
                continue;
101
            }
102
103
            $excludeNamespaceRegex = $regexOrNamespaceName;
104
105
            $errorMessage = $this->regexChecker->validateRegex($excludeNamespaceRegex);
106
107
            if (null !== $errorMessage) {
108
                throw new InvalidArgumentException(
109
                    sprintf(
110
                        'Expected "%s" to be an array of valid regexes. The element "%s" with the index "%s" is not: %s.',
111
                        $key,
112
                        $excludeNamespaceRegex,
113
                        $index,
114
                        $errorMessage,
115
                    ),
116
                );
117
            }
118
119
            // Ensure namespace comparisons are always case-insensitive
120
            $excludeNamespaceRegex .= 'i';
121
            $regexes[$excludeNamespaceRegex] = null;
122
        }
123
124
        return [
125
            array_keys($regexes),
126
            array_keys($namespaceNames),
127
        ];
128
    }
129
130
    /**
131
     * return list<string>
132
     */
133
    private static function retrieveExposedElements(array $config): array
134
    {
135
        $key = ConfigurationKeys::WHITELIST_KEYWORD;
136
137
        if (!array_key_exists($key, $config)) {
138
            return [];
139
        }
140
141
        $whitelist = $config[$key];
142
143
        if (!is_array($whitelist)) {
144
            throw new InvalidArgumentException(
145
                sprintf(
146
                    'Expected "%s" to be an array of strings, found "%s" instead.',
147
                    $key,
148
                    gettype($whitelist),
149
                ),
150
            );
151
        }
152
153
        foreach ($whitelist as $index => $className) {
154
            if (is_string($className)) {
155
                continue;
156
            }
157
158
            throw new InvalidArgumentException(
159
                sprintf(
160
                    'Expected whitelist to be an array of string, the "%d" element is not.',
161
                    $index,
162
                ),
163
            );
164
        }
165
166
        return array_values($whitelist);
167
    }
168
169
    private static function retrieveExposeGlobalSymbol(array $config, string $key): bool
170
    {
171
        if (!array_key_exists($key, $config)) {
172
            return false;
173
        }
174
175
        $value = $config[$key];
176
177
        if (!is_bool($value)) {
178
            throw new InvalidArgumentException(
179
                sprintf(
180
                    'Expected %s to be a boolean, found "%s" instead.',
181
                    $key,
182
                    gettype($value),
183
                ),
184
            );
185
        }
186
187
        return $value;
188
    }
189
}
190