Completed
Pull Request — master (#14)
by Indra
04:30
created

Configuration   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 113
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 8
lcom 0
cbo 2
dl 0
loc 113
ccs 89
cts 89
cp 1
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
C getConfigTreeBuilder() 0 107 8
1
<?php
2
3
/*
4
 * This file is part of the ApiRateLimitBundle
5
 *
6
 * (c) Indra Gunawan <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Indragunawan\ApiRateLimitBundle\DependencyInjection;
13
14
use Indragunawan\ApiRateLimitBundle\Exception\RateLimitExceededException;
15
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
16
use Symfony\Component\Config\Definition\ConfigurationInterface;
17
use Symfony\Component\HttpFoundation\Response;
18
19
/**
20
 * The configuration of the bundle.
21
 *
22
 * @author Indra Gunawan <[email protected]>
23
 */
24
final class Configuration implements ConfigurationInterface
25
{
26
    /**
27
     * {@inheritdoc}
28
     */
29 12
    public function getConfigTreeBuilder()
30
    {
31 12
        $treeBuilder = new TreeBuilder('indragunawan_api_rate_limit');
32 12
        $rootNode = method_exists(TreeBuilder::class, 'getRootNode')
33 12
            ? $treeBuilder->getRootNode()
34 12
            : $treeBuilder->root('indragunawan_api_rate_limit');
0 ignored issues
show
Bug introduced by
The method root() does not seem to exist on object<Symfony\Component...on\Builder\TreeBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
35
36
        $rootNode
37 12
            ->children()
38 12
                ->booleanNode('enabled')->defaultTrue()->end()
39 12
                ->scalarNode('storage')->defaultNull()->cannotBeEmpty()->end()
40 12
                ->scalarNode('cache')->defaultNull()->cannotBeEmpty()->end()
41 12
                ->arrayNode('header')
42 12
                    ->addDefaultsIfNotSet()
43 12
                    ->children()
44 12
                        ->booleanNode('display')->defaultTrue()->end()
45 12
                        ->arrayNode('names')
46 12
                            ->addDefaultsIfNotSet()
47 12
                            ->children()
48 12
                                ->scalarNode('limit')->cannotBeEmpty()->defaultValue('X-RateLimit-Limit')->end()
49 12
                                ->scalarNode('remaining')->cannotBeEmpty()->defaultValue('X-RateLimit-Remaining')->end()
50 12
                                ->scalarNode('reset')->cannotBeEmpty()->defaultValue('X-RateLimit-Reset')->end()
51 12
                            ->end()
52 12
                        ->end()
53 12
                    ->end()
54 12
                ->end()
55 12
                ->arrayNode('throttle')
56 12
                    ->beforeNormalization()
57
                        ->ifTrue(function ($v) { return is_array($v) && (isset($v['limit']) || isset($v['period'])); })
58
                        ->then(function ($v) {
59 1
                            $v['default'] = [];
60 1
                            if (isset($v['limit'])) {
61 1
                                @trigger_error('The indragunawan_api_rate_limit.throttle.limit configuration key is deprecated since version v0.2.0 and will be removed in v0.3.0. Use the indragunawan_api_rate_limit.throttle.default.limit configuration key instead.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
62
63 1
                                $v['default']['limit'] = $v['limit'];
64
                            }
65
66 1
                            if (isset($v['period'])) {
67 1
                                @trigger_error('The indragunawan_api_rate_limit.throttle.period configuration key is deprecated since version v0.2.0 and will be removed in v0.3.0. Use the indragunawan_api_rate_limit.throttle.default.period configuration key instead.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
68
69 1
                                $v['default']['period'] = $v['period'];
70
                            }
71
72 1
                            return $v;
73 12
                        })
74 12
                    ->end()
75 12
                    ->addDefaultsIfNotSet()
76 12
                    ->children()
77 12
                        ->integerNode('limit')->min(1)->defaultValue(60)->end()
78 12
                        ->integerNode('period')->min(1)->defaultValue(60)->end()
79 12
                        ->arrayNode('default')
80 12
                            ->addDefaultsIfNotSet()
81 12
                            ->children()
82 12
                                ->integerNode('limit')->min(1)->defaultValue(60)->end()
83 12
                                ->integerNode('period')->min(1)->defaultValue(60)->end()
84 12
                            ->end()
85 12
                        ->end()
86 12
                        ->arrayNode('roles')
87 12
                            ->useAttributeAsKey('name')
88 12
                            ->prototype('array')
89 12
                                ->children()
90 12
                                    ->integerNode('limit')->isRequired()->min(1)->end()
91 12
                                    ->integerNode('period')->isRequired()->min(1)->end()
92 12
                                ->end()
93 12
                            ->end()
94 12
                        ->end()
95 12
                        ->enumNode('sort')
96 12
                            ->values(['first-match', 'rate-limit-asc', 'rate-limit-desc'])
97 12
                            ->defaultValue('rate-limit-desc')
98 12
                        ->end()
99 12
                    ->end()
100 12
                ->end()
101 12
                ->arrayNode('exception')
102 12
                    ->addDefaultsIfNotSet()
103 12
                    ->children()
104 12
                        ->integerNode('status_code')
105 12
                            ->defaultValue(Response::HTTP_TOO_MANY_REQUESTS)
106 12
                            ->validate()
107 12
                            ->ifNotInArray(array_keys(Response::$statusTexts))
108 12
                                ->thenInvalid('Invalid status code "%s"')
109 12
                            ->end()
110 12
                        ->end()
111 12
                        ->scalarNode('message')->cannotBeEmpty()->defaultValue('API rate limit exceeded for %s.')->end()
112 12
                        ->scalarNode('custom_exception')
113 12
                            ->cannotBeEmpty()
114 12
                            ->defaultNull()
115 12
                            ->validate()
116
                            ->ifTrue(function ($v) {
117 3
                                if (!class_exists($v)) {
118 1
                                    return true;
119
                                }
120
121 2
                                if (!is_subclass_of($v, RateLimitExceededException::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Indragunawan\ApiRateLim...xceededException::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
122 1
                                    return true;
123
                                }
124
125 1
                                return false;
126 12
                            })
127 12
                                ->thenInvalid('The class %s does not exist or not extend "Indragunawan\ApiRateLimitBundle\Exception\RateLimitExceededException" class.')
128 12
                            ->end()
129 12
                        ->end()
130 12
                    ->end()
131 12
                ->end()
132 12
            ->end();
133
134 12
        return $treeBuilder;
135
    }
136
}
137