Passed
Push — master ( cce2e1...993520 )
by Dawid
02:22
created

Configuration::addResponseSchemaValidation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 17
cts 17
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 17
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Spiechu\SymfonyCommonsBundle\DependencyInjection;
4
5
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
6
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
7
use Symfony\Component\Config\Definition\ConfigurationInterface;
8
use Symfony\Component\HttpFoundation\Request;
9
10
class Configuration implements ConfigurationInterface
11
{
12
    /**
13
     * {@inheritdoc}
14
     *
15
     * @throws \RuntimeException
16
     * @throws \InvalidArgumentException
17
     */
18 19
    public function getConfigTreeBuilder(): TreeBuilder
19
    {
20 19
        $treeBuilder = new TreeBuilder();
21 19
        $rootNode = $treeBuilder->root('spiechu_symfony_commons');
22
23 19
        $this->addGetMethodOverride($rootNode);
24 19
        $this->addResponseSchemaValidation($rootNode);
25 19
        $this->addApiVersionSupport($rootNode);
26
27 19
        return $treeBuilder;
28
    }
29
30
    /**
31
     * @param ArrayNodeDefinition $rootNode
32
     *
33
     * @throws \InvalidArgumentException
34
     * @throws \RuntimeException
35
     */
36 19
    protected function addGetMethodOverride(ArrayNodeDefinition $rootNode): void
37
    {
38 19
        $overridableHttpMethods = $this->getOverridableHttpMethods();
39
        $defaultOverridedHttpMethods = [
40 19
            Request::METHOD_DELETE,
41 19
            Request::METHOD_POST,
42 19
            Request::METHOD_PUT,
43
        ];
44
45
        $rootNode
46 19
            ->children()
47 19
                ->arrayNode('get_method_override')
48 19
                    ->addDefaultsIfNotSet()
49 19
                    ->canBeEnabled()
50 19
                    ->children()
51 19
                        ->scalarNode('listener_service_id')
52 19
                            ->cannotBeEmpty()
53 19
                            ->defaultValue('spiechu_symfony_commons.event_listener.get_method_override_listener')
54 19
                        ->end()
55 19
                        ->scalarNode('query_param_name')
56 19
                            ->cannotBeEmpty()
57 19
                            ->defaultValue('_method')
58 19
                            ->validate()
59
                                ->ifTrue(function ($methodName): bool {
60 1
                                    return !is_string($methodName);
61 19
                                })
62 19
                                ->thenInvalid('Not a string provided')
63 19
                            ->end()
64 19
                        ->end()
65 19
                        ->arrayNode('allow_methods_override')
66 19
                            ->beforeNormalization()
67 19
                                ->ifString()->castToArray()
68 19
                            ->end()
69 19
                            ->defaultValue($defaultOverridedHttpMethods)
70 19
                            ->prototype('scalar')
71 19
                                ->validate()
72 19
                                    ->ifNotInArray($overridableHttpMethods)
73 19
                                    ->thenInvalid(sprintf(
74 19
                                        'Invalid methods to override provided, known are: "%s"',
75 19
                                        implode(', ', $overridableHttpMethods)
76
                                    ))
77 19
                                ->end()
78 19
                            ->end()
79 19
                            ->beforeNormalization()
80 19
                                ->ifArray()
81
                                ->then(function (array $methods): array {
82 3
                                    return array_unique(array_map('strtoupper', $methods));
83 19
                                })
84 19
                            ->end()
85 19
                        ->end()
86 19
                    ->end()
87 19
                ->end()
88 19
            ->end()
89 19
        ->end();
90 19
    }
91
92
    /**
93
     * @param ArrayNodeDefinition $rootNode
94
     */
95 19
    protected function addResponseSchemaValidation(ArrayNodeDefinition $rootNode): void
96
    {
97
        $rootNode
98 19
            ->children()
99 19
                ->arrayNode('response_schema_validation')
100 19
                    ->addDefaultsIfNotSet()
101 19
                    ->canBeEnabled()
102 19
                    ->children()
103 19
                        ->booleanNode('throw_exception_when_format_not_found')->defaultTrue()->end()
104 19
                        ->scalarNode('failed_schema_check_listener_service_id')
105 19
                            ->defaultValue('spiechu_symfony_commons.event_listener.failed_schema_check_listener')
106 19
                        ->end()
107 19
                        ->booleanNode('disable_json_check_schema_subscriber')->defaultFalse()->end()
108 19
                        ->booleanNode('disable_xml_check_schema_subscriber')->defaultFalse()->end()
109 19
                    ->end()
110 19
                ->end()
111 19
            ->end()
112 19
        ->end();
113 19
    }
114
115
    /**
116
     * @param ArrayNodeDefinition $rootNode
117
     *
118
     * @throws \InvalidArgumentException
119
     * @throws \RuntimeException
120
     */
121 19
    protected function addApiVersionSupport(ArrayNodeDefinition $rootNode): void
122
    {
123
        $versionNormalizer = static function ($version): string {
124 4
            if (is_string($version)) {
125
                return $version;
126
            }
127
128 4
            if (!is_numeric($version)) {
129
                throw new \InvalidArgumentException(sprintf('"%s" is not numeric', $version));
130
            }
131
132 4
            return number_format($version, 1, '.', '');
133
        };
134
135
        $rootNode
136 19
            ->children()
137 19
                ->arrayNode('api_versioning')
138 19
                    ->addDefaultsIfNotSet()
139 19
                    ->canBeEnabled()
140 19
                    ->children()
141 19
                        ->booleanNode('versioned_view_listener')->defaultFalse()->end()
142 19
                        ->arrayNode('features')
143 19
                            ->useAttributeAsKey('name')
144 19
                            ->prototype('array')
145 19
                                ->children()
146 19
                                    ->scalarNode('since')
147 19
                                        ->defaultNull()
148 19
                                        ->beforeNormalization()
149 19
                                            ->always($versionNormalizer)
150 19
                                        ->end()
151 19
                                    ->end()
152 19
                                    ->scalarNode('until')
153 19
                                        ->defaultNull()
154 19
                                        ->beforeNormalization()
155 19
                                            ->always($versionNormalizer)
156 19
                                        ->end()
157 19
                                    ->end()
158 19
                                ->end()
159 19
                                ->beforeNormalization()
160 19
                                    ->always(function ($prototypeValue): array {
161 4
                                        if (empty($prototypeValue)) {
162
                                            throw new \InvalidArgumentException('No version constraints provided');
163
                                        }
164
165 4
                                        return $prototypeValue;
166 19
                                    })
167 19
                                ->end()
168 19
                            ->end()
169 19
                        ->end()
170 19
                    ->end()
171 19
                ->end()
172 19
            ->end()
173 19
        ->end();
174 19
    }
175
176
    /**
177
     * @return string[]
178
     */
179 19
    protected function getOverridableHttpMethods(): array
180
    {
181
        return [
182 19
            Request::METHOD_CONNECT,
183 19
            Request::METHOD_DELETE,
184 19
            Request::METHOD_HEAD,
185 19
            Request::METHOD_OPTIONS,
186 19
            Request::METHOD_PATCH,
187 19
            Request::METHOD_POST,
188 19
            Request::METHOD_PURGE,
189 19
            Request::METHOD_TRACE,
190 19
            Request::METHOD_PUT,
191
        ];
192
    }
193
}
194