Test Failed
Push — master ( 466b97...e9a466 )
by Dawid
10:05
created

Configuration   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 96.9%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 4
dl 0
loc 194
ccs 125
cts 129
cp 0.969
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfigTreeBuilder() 0 18 2
B addGetMethodOverride() 0 56 1
A addResponseSchemaValidation() 0 20 1
B addApiVersionSupport() 0 55 4
A getOverridableHttpMethods() 0 14 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 21
    public function getConfigTreeBuilder(): TreeBuilder
19
    {
20 21
        if (\method_exists(TreeBuilder::class, 'getRootNode')) {
21 21
            $treeBuilder = new TreeBuilder('spiechu_symfony_commons');
22 21
            $rootNode = $treeBuilder->getRootNode();
23
        } else {
24
            $treeBuilder = new TreeBuilder();
25
26
            // BC layer for symfony/config 4.1 and older
27
            $rootNode = $treeBuilder->root('spiechu_symfony_commons');
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Config...der\TreeBuilder::root() has been deprecated with message: since Symfony 4.3, pass the root name to the constructor instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
28 21
        }
29 21
30 21
        $this->addGetMethodOverride($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
31
        $this->addResponseSchemaValidation($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
32 21
        $this->addApiVersionSupport($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
33
34
        return $treeBuilder;
35
    }
36
37
    /**
38
     * @param ArrayNodeDefinition $rootNode
39
     *
40
     * @throws \InvalidArgumentException
41 21
     * @throws \RuntimeException
42
     */
43 21
    protected function addGetMethodOverride(ArrayNodeDefinition $rootNode): void
44
    {
45 21
        $overridableHttpMethods = $this->getOverridableHttpMethods();
46 21
        $defaultOverridedHttpMethods = [
47 21
            Request::METHOD_DELETE,
48
            Request::METHOD_POST,
49
            Request::METHOD_PUT,
50
        ];
51 21
52 21
        $rootNode
53 21
            ->children()
54 21
                ->arrayNode('get_method_override')
55 21
                    ->info('Default options for GET method override feature')
56 21
                    ->addDefaultsIfNotSet()
57 21
                    ->canBeEnabled()
58 21
                    ->children()
59 21
                        ->scalarNode('listener_service_id')
60 21
                            ->cannotBeEmpty()
61 21
                            ->defaultValue('spiechu_symfony_commons.event_listener.get_method_override_listener')
62 21
                        ->end()
63 21
                        ->/* @scrutinizer ignore-call */scalarNode('query_param_name')
64 21
                            ->cannotBeEmpty()
65
                            ->defaultValue('_method')
66 1
                            ->validate()
67 21
                                ->ifTrue(static function ($methodName): bool {
68 21
                                    return !\is_string($methodName);
69 21
                                })
70 21
                                ->thenInvalid('Not a string provided')
71 21
                            ->end()
72 21
                        ->end()
73 21
                        ->arrayNode('allow_methods_override')
74 21
                            ->beforeNormalization()
75 21
                                ->ifString()->castToArray()
76 21
                            ->end()
77 21
                            ->defaultValue($defaultOverridedHttpMethods)
78 21
                            ->prototype('scalar')
79 21
                                ->validate()
80 21
                                    ->ifNotInArray($overridableHttpMethods)
81 21
                                    ->thenInvalid(sprintf(
82
                                        'Invalid methods to override provided, known are: "%s"',
83 21
                                        implode(', ', $overridableHttpMethods)
84 21
                                    ))
85 21
                                ->end()
86 21
                            ->end()
87
                            ->beforeNormalization()
88 4
                                ->ifArray()
89 21
                                ->then(static function (array $methods): array {
90 21
                                    return array_unique(array_map('strtoupper', $methods));
91 21
                                })
92 21
                            ->end()
93 21
                        ->end()
94 21
                    ->end()
95 21
                ->end()
96 21
            ->end()
97
        ->end();
98
    }
99
100
    /**
101 21
     * @param ArrayNodeDefinition $rootNode
102
     */
103
    protected function addResponseSchemaValidation(ArrayNodeDefinition $rootNode): void
104 21
    {
105 21
        $rootNode
106 21
            ->children()
107 21
                ->arrayNode('response_schema_validation')
108 21
                    ->info('Default options for response schema validation feature')
109 21
                    ->addDefaultsIfNotSet()
110 21
                    ->canBeEnabled()
111 21
                    ->children()
112 21
                        ->booleanNode('throw_exception_when_format_not_found')->defaultTrue()->end()
113 21
                        ->/* @scrutinizer ignore-call */scalarNode('failed_schema_check_listener_service_id')
114 21
                            ->defaultValue('spiechu_symfony_commons.event_listener.failed_schema_check_listener')
115 21
                        ->end()
116 21
                        ->booleanNode('disable_json_check_schema_subscriber')->defaultFalse()->end()
117 21
                        ->booleanNode('disable_xml_check_schema_subscriber')->defaultFalse()->end()
118 21
                    ->end()
119 21
                ->end()
120 21
            ->end()
121
        ->end();
122
    }
123
124
    /**
125
     * @param ArrayNodeDefinition $rootNode
126
     *
127
     * @throws \InvalidArgumentException
128 21
     * @throws \RuntimeException
129
     */
130
    protected function addApiVersionSupport(ArrayNodeDefinition $rootNode): void
131 4
    {
132
        $versionNormalizer = static function ($version): string {
133
            if (\is_string($version)) {
134
                return $version;
135 4
            }
136
137
            if (!is_numeric($version)) {
138
                throw new \InvalidArgumentException(sprintf('"%s" is not numeric', $version));
139 4
            }
140 21
141
            return number_format($version, 1, '.', '');
142
        };
143 21
144 21
        $rootNode
145 21
            ->children()
146 21
                ->arrayNode('api_versioning')
147 21
                    ->info('Default options for API versioning feature')
148 21
                    ->addDefaultsIfNotSet()
149 21
                    ->canBeEnabled()
150 21
                    ->children()
151 21
                        ->booleanNode('versioned_view_listener')->defaultFalse()->end()
152 21
                        ->/* @scrutinizer ignore-call */arrayNode('features')
153 21
                            ->useAttributeAsKey('name')
154 21
                            ->prototype('array')
155 21
                                ->children()
156 21
                                    ->scalarNode('since')
157 21
                                        ->defaultNull()
158 21
                                        ->beforeNormalization()
159 21
                                            ->always($versionNormalizer)
160 21
                                        ->end()
161 21
                                    ->end()
162 21
                                    ->scalarNode('until')
163 21
                                        ->defaultNull()
164 21
                                        ->beforeNormalization()
165 21
                                            ->always($versionNormalizer)
166 21
                                        ->end()
167 21
                                    ->end()
168
                                ->end()
169 4
                                ->beforeNormalization()
170
                                    ->always(static function ($prototypeValue): array {
171
                                        if (empty($prototypeValue)) {
172
                                            throw new \InvalidArgumentException('No version constraints provided');
173 4
                                        }
174 21
175 21
                                        return $prototypeValue;
176 21
                                    })
177 21
                                ->end()
178 21
                            ->end()
179 21
                        ->end()
180 21
                    ->end()
181 21
                ->end()
182 21
            ->end()
183
        ->end();
184
    }
185
186
    /**
187 21
     * @return string[]
188
     */
189
    protected function getOverridableHttpMethods(): array
190 21
    {
191 21
        return [
192 21
            Request::METHOD_CONNECT,
193 21
            Request::METHOD_DELETE,
194 21
            Request::METHOD_HEAD,
195 21
            Request::METHOD_OPTIONS,
196 21
            Request::METHOD_PATCH,
197 21
            Request::METHOD_POST,
198 21
            Request::METHOD_PURGE,
199
            Request::METHOD_TRACE,
200
            Request::METHOD_PUT,
201
        ];
202
    }
203
}
204