Completed
Push — master ( 0b7273...69a9c3 )
by Dawid
09:25
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 20
    public function getConfigTreeBuilder(): TreeBuilder
19
    {
20 20
        $treeBuilder = new TreeBuilder();
21 20
        $rootNode = $treeBuilder->root('spiechu_symfony_commons');
22
23 20
        $this->addGetMethodOverride($rootNode);
24 20
        $this->addResponseSchemaValidation($rootNode);
25 20
        $this->addApiVersionSupport($rootNode);
26
27 20
        return $treeBuilder;
28
    }
29
30
    /**
31
     * @param ArrayNodeDefinition $rootNode
32
     *
33
     * @throws \InvalidArgumentException
34
     * @throws \RuntimeException
35
     */
36 20
    protected function addGetMethodOverride(ArrayNodeDefinition $rootNode): void
37
    {
38 20
        $overridableHttpMethods = $this->getOverridableHttpMethods();
39
        $defaultOverridedHttpMethods = [
40 20
            Request::METHOD_DELETE,
41 20
            Request::METHOD_POST,
42 20
            Request::METHOD_PUT,
43
        ];
44
45
        $rootNode
46 20
            ->children()
47 20
                ->arrayNode('get_method_override')
48 20
                    ->addDefaultsIfNotSet()
49 20
                    ->canBeEnabled()
50 20
                    ->children()
51 20
                        ->scalarNode('listener_service_id')
52 20
                            ->cannotBeEmpty()
53 20
                            ->defaultValue('spiechu_symfony_commons.event_listener.get_method_override_listener')
54 20
                        ->end()
55 20
                        ->scalarNode('query_param_name')
56 20
                            ->cannotBeEmpty()
57 20
                            ->defaultValue('_method')
58 20
                            ->validate()
59
                                ->ifTrue(function ($methodName): bool {
60 1
                                    return !\is_string($methodName);
61 20
                                })
62 20
                                ->thenInvalid('Not a string provided')
63 20
                            ->end()
64 20
                        ->end()
65 20
                        ->arrayNode('allow_methods_override')
66 20
                            ->beforeNormalization()
67 20
                                ->ifString()->castToArray()
68 20
                            ->end()
69 20
                            ->defaultValue($defaultOverridedHttpMethods)
70 20
                            ->prototype('scalar')
71 20
                                ->validate()
72 20
                                    ->ifNotInArray($overridableHttpMethods)
73 20
                                    ->thenInvalid(sprintf(
74 20
                                        'Invalid methods to override provided, known are: "%s"',
75 20
                                        implode(', ', $overridableHttpMethods)
76
                                    ))
77 20
                                ->end()
78 20
                            ->end()
79 20
                            ->beforeNormalization()
80 20
                                ->ifArray()
81
                                ->then(function (array $methods): array {
82 3
                                    return array_unique(array_map('strtoupper', $methods));
83 20
                                })
84 20
                            ->end()
85 20
                        ->end()
86 20
                    ->end()
87 20
                ->end()
88 20
            ->end()
89 20
        ->end();
90 20
    }
91
92
    /**
93
     * @param ArrayNodeDefinition $rootNode
94
     */
95 20
    protected function addResponseSchemaValidation(ArrayNodeDefinition $rootNode): void
96
    {
97
        $rootNode
98 20
            ->children()
99 20
                ->arrayNode('response_schema_validation')
100 20
                    ->addDefaultsIfNotSet()
101 20
                    ->canBeEnabled()
102 20
                    ->children()
103 20
                        ->booleanNode('throw_exception_when_format_not_found')->defaultTrue()->end()
104 20
                        ->scalarNode('failed_schema_check_listener_service_id')
105 20
                            ->defaultValue('spiechu_symfony_commons.event_listener.failed_schema_check_listener')
106 20
                        ->end()
107 20
                        ->booleanNode('disable_json_check_schema_subscriber')->defaultFalse()->end()
108 20
                        ->booleanNode('disable_xml_check_schema_subscriber')->defaultFalse()->end()
109 20
                    ->end()
110 20
                ->end()
111 20
            ->end()
112 20
        ->end();
113 20
    }
114
115
    /**
116
     * @param ArrayNodeDefinition $rootNode
117
     *
118
     * @throws \InvalidArgumentException
119
     * @throws \RuntimeException
120
     */
121 20
    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 20
        };
134
135
        $rootNode
136 20
            ->children()
137 20
                ->arrayNode('api_versioning')
138 20
                    ->addDefaultsIfNotSet()
139 20
                    ->canBeEnabled()
140 20
                    ->children()
141 20
                        ->booleanNode('versioned_view_listener')->defaultFalse()->end()
142 20
                        ->arrayNode('features')
143 20
                            ->useAttributeAsKey('name')
144 20
                            ->prototype('array')
145 20
                                ->children()
146 20
                                    ->scalarNode('since')
147 20
                                        ->defaultNull()
148 20
                                        ->beforeNormalization()
149 20
                                            ->always($versionNormalizer)
150 20
                                        ->end()
151 20
                                    ->end()
152 20
                                    ->scalarNode('until')
153 20
                                        ->defaultNull()
154 20
                                        ->beforeNormalization()
155 20
                                            ->always($versionNormalizer)
156 20
                                        ->end()
157 20
                                    ->end()
158 20
                                ->end()
159 20
                                ->beforeNormalization()
160 20
                                    ->always(function ($prototypeValue): array {
161 4
                                        if (empty($prototypeValue)) {
162
                                            throw new \InvalidArgumentException('No version constraints provided');
163
                                        }
164
165 4
                                        return $prototypeValue;
166 20
                                    })
167 20
                                ->end()
168 20
                            ->end()
169 20
                        ->end()
170 20
                    ->end()
171 20
                ->end()
172 20
            ->end()
173 20
        ->end();
174 20
    }
175
176
    /**
177
     * @return string[]
178
     */
179 20
    protected function getOverridableHttpMethods(): array
180
    {
181
        return [
182 20
            Request::METHOD_CONNECT,
183 20
            Request::METHOD_DELETE,
184 20
            Request::METHOD_HEAD,
185 20
            Request::METHOD_OPTIONS,
186 20
            Request::METHOD_PATCH,
187 20
            Request::METHOD_POST,
188 20
            Request::METHOD_PURGE,
189 20
            Request::METHOD_TRACE,
190 20
            Request::METHOD_PUT,
191
        ];
192
    }
193
}
194