GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#837)
by E
07:31 queued 05:03
created

ConfigurationOptionsResolver::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 3
dl 0
loc 9
ccs 0
cts 4
cp 0
crap 2
rs 9.6666
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace ApiGen\Configuration;
4
5
use ApiGen\Configuration\Exceptions\ConfigurationException;
6
use ApiGen\Configuration\Theme\ThemeConfigFactory;
7
use ApiGen\Utils\FileSystem;
8
use ReflectionProperty;
9
use Symfony\Component\OptionsResolver\Options;
10
use Symfony\Component\OptionsResolver\OptionsResolver;
11
12
final class ConfigurationOptionsResolver
13
{
14
    /**
15
     * @var string
16
     */
17
    public const ACCESS_LEVEL_PROTECTED = 'protected';
18
19
    /**
20
     * @var string
21
     */
22
    public const ACCESS_LEVEL_PRIVATE = 'private';
23
24
    /**
25
     * @var string
26
     */
27
    public const ACCESS_LEVEL_PUBLIC = 'public';
28
29
    /**
30
     * @var mixed[]
31
     */
32
    private $defaults = [
33
        // required
34
        ConfigurationOptions::SOURCE => [],
35
        ConfigurationOptions::DESTINATION => null,
36
        // file finder
37
        ConfigurationOptions::EXCLUDE => [],
38
        ConfigurationOptions::EXTENSIONS => ['php'],
39
        // template parameters
40
        ConfigurationOptions::TITLE => '',
41
        ConfigurationOptions::GOOGLE_ANALYTICS => '',
42
        // filtering generated content
43
        ConfigurationOptions::ACCESS_LEVELS => [self::ACCESS_LEVEL_PUBLIC, self::ACCESS_LEVEL_PROTECTED],
44
        ConfigurationOptions::ANNOTATION_GROUPS => [],
45
        ConfigurationOptions::BASE_URL => '',
46
        ConfigurationOptions::CONFIG => '',
47
        ConfigurationOptions::FORCE_OVERWRITE => false,
48
        ConfigurationOptions::TEMPLATE_CONFIG => null,
49
        // helpers - @todo: remove
50
        ConfigurationOptions::VISIBILITY_LEVELS => [],
51
    ];
52
53
    /**
54
     * @var ThemeConfigFactory
55
     */
56
    private $themeConfigFactory;
57
58
    /**
59
     * @var OptionsResolver
60
     */
61
    private $resolver;
62
63
    /**
64
     * @var OptionsResolverFactory
65
     */
66
    private $optionsResolverFactory;
67
68
    /**
69
     * @var FileSystem
70
     */
71
    private $fileSystem;
72
73
    public function __construct(
74
        ThemeConfigFactory $themeConfigFactory,
75
        OptionsResolverFactory $optionsResolverFactory,
76
        FileSystem $fileSystem
77
    ) {
78
        $this->themeConfigFactory = $themeConfigFactory;
79
        $this->optionsResolverFactory = $optionsResolverFactory;
80
        $this->fileSystem = $fileSystem;
81
    }
82
83
    /**
84
     * @param mixed[] $options
85 29
     * @return mixed[]
86
     */
87 29
    public function resolve(array $options): array
88 29
    {
89 29
        $this->resolver = $this->optionsResolverFactory->create();
90 29
        $this->setDefaults();
91 29
        $this->setRequired();
92
        $this->setAllowedValues();
93 29
        $this->setNormalizers();
94
95
        return $this->resolver->resolve($options);
96 29
    }
97
98 29
    private function setDefaults(): void
99 29
    {
100
        $this->resolver->setDefaults($this->defaults);
101 26
        $this->resolver->setDefaults([
102 26
            ConfigurationOptions::VISIBILITY_LEVELS => function (Options $options) {
103 26
                return $this->getAccessLevelForReflections($options[ConfigurationOptions::ACCESS_LEVELS]);
104
            },
105
            ConfigurationOptions::TEMPLATE => function (Options $options) {
106 26
                $config = $options[ConfigurationOptions::TEMPLATE_CONFIG];
107 26
                if ($config === '') {
108 29
                    $config = getcwd() . '/packages/ThemeDefault/src/config.neon';
109
                }
110 29
111
                return $this->themeConfigFactory->create($config)
112
                    ->getOptions();
113
            }
114
        ]);
115 27
    }
116
117 27
    /**
118
     * @param mixed[] $options
119 27
     */
120 27
    private function getAccessLevelForReflections(array $options): int
121
    {
122
        $accessLevel = null;
123 27
124 27
        if (in_array(self::ACCESS_LEVEL_PUBLIC, $options)) {
125
            $accessLevel |= ReflectionProperty::IS_PUBLIC;
126
        }
127 27
128 2
        if (in_array(self::ACCESS_LEVEL_PROTECTED, $options)) {
129
            $accessLevel |= ReflectionProperty::IS_PROTECTED;
130
        }
131 27
132
        if (in_array(self::ACCESS_LEVEL_PRIVATE, $options)) {
133
            $accessLevel |= ReflectionProperty::IS_PRIVATE;
134 29
        }
135
136 29
        return $accessLevel;
137 29
    }
138
139 29
    private function setRequired(): void
140
    {
141
        $this->resolver->setRequired([ConfigurationOptions::SOURCE, ConfigurationOptions::DESTINATION]);
142 29
    }
143 29
144
    private function setAllowedValues(): void
145
    {
146 29
        $this->resolver->addAllowedValues(ConfigurationOptions::DESTINATION, function ($destination) {
147 29
            return $this->allowedValuesForDestination($destination);
148
        });
149
150 27
        $this->resolver->addAllowedValues(ConfigurationOptions::SOURCE, function ($source) {
151
            return $this->allowedValuesForSource($source);
152
        });
153
154
        $this->resolver->addAllowedValues(ConfigurationOptions::TEMPLATE_CONFIG, function ($value) {
155
            if ($value && ! is_file($value)) {
156 27
                throw new ConfigurationException(sprintf(
157 29
                    'Template config "%s" was not found.', $value
158 29
                ));
159
            }
160 29
161
            return true;
162
        });
163 27
    }
164
165
    private function setNormalizers(): void
166
    {
167 27
        $this->resolver->setNormalizer(ConfigurationOptions::ANNOTATION_GROUPS, function (Options $options, $value) {
168 29
            if ($value === '') {
169
                return [];
170
            }
171 27
172 29
            return $value;
173
        });
174
175 27
        $this->resolver->setNormalizer(ConfigurationOptions::DESTINATION, function (Options $options, $value) {
176 29
            return $this->fileSystem->getAbsolutePath($value);
177
        });
178
179 29
        $this->resolver->setNormalizer(ConfigurationOptions::BASE_URL, function (Options $options, $value) {
180
            return rtrim((string) $value, '/');
181
        });
182
183 29
        $this->resolver->setNormalizer(ConfigurationOptions::SOURCE, function (Options $options, $value) {
184 28
            if (! is_array($value)) {
185
                $value = [$value];
186
            }
187 29
188 29
            foreach ($value as $key => $source) {
189
                $value[$key] = $this->fileSystem->getAbsolutePath($source);
190
            }
191 27
192 27
            return $value;
193
        });
194
195
        $this->resolver->setNormalizer(ConfigurationOptions::TEMPLATE_CONFIG, function (Options $options, $value) {
196 29
            if ($value === null) {
197
                return '';
198 29
            }
199 27
200 29
            return $this->fileSystem->getAbsolutePath($value);
201 29
        });
202
    }
203 29
204
    private function allowedValuesForDestination(?string $destination): bool
205 29
    {
206 2
        if (! $destination) {
207 2
            throw new ConfigurationException(
208
                'Destination is not set. Use "--destination <directory>" or config to set it.'
209
            );
210
        } elseif (! is_dir($destination)) {
211 27
            mkdir($destination, 0755, true);
212 4
        }
213
214
        if (! is_writable($destination)) {
215 27
            throw new ConfigurationException(sprintf(
216
                'Destination "%s" is not writable.',
217
                $destination
218
            ));
219
        }
220
221
        return true;
222 27
    }
223
224
    /**
225
     * @param string[] $source
226
     */
227
    private function allowedValuesForSource(array $source): bool
228 29
    {
229
        foreach ($source as $singleSource) {
230 29
            $this->ensureSourceExists($singleSource);
231 28
        }
232
233
        return true;
234 29
    }
235
236
    private function ensureSourceExists(string $singleSource): void
237 28
    {
238
        if (! file_exists($singleSource)) {
239 28
            throw new ConfigurationException(sprintf(
240
                'Source "%s" does not exist',
241
                $singleSource
242
            ));
243
        }
244
    }
245
}
246