Completed
Pull Request — master (#3)
by Indra
02:35
created

Configuration   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 4

Test Coverage

Coverage 90.48%

Importance

Changes 0
Metric Value
wmc 7
lcom 0
cbo 4
dl 0
loc 107
ccs 76
cts 84
cp 0.9048
rs 10
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
C getConfigTreeBuilder() 0 101 7
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 8
    public function getConfigTreeBuilder()
30
    {
31 8
        $treeBuilder = new TreeBuilder();
32 8
        $rootNode = $treeBuilder->root('indragunawan_api_rate_limit');
33
34
        $rootNode
35 8
            ->children()
36 8
                ->booleanNode('enabled')->defaultTrue()->end()
37 8
                ->scalarNode('storage')->defaultNull()->cannotBeEmpty()->end()
38 8
                ->scalarNode('cache')->defaultNull()->cannotBeEmpty()->end()
39 8
                ->arrayNode('header')
40 8
                    ->addDefaultsIfNotSet()
41 8
                    ->children()
42 8
                        ->booleanNode('display')->defaultTrue()->end()
43 8
                        ->arrayNode('names')
44 8
                            ->addDefaultsIfNotSet()
45 8
                            ->children()
46 8
                                ->scalarNode('limit')->cannotBeEmpty()->defaultValue('X-RateLimit-Limit')->end()
47 8
                                ->scalarNode('remaining')->cannotBeEmpty()->defaultValue('X-RateLimit-Remaining')->end()
48 8
                                ->scalarNode('reset')->cannotBeEmpty()->defaultValue('X-RateLimit-Reset')->end()
49 8
                            ->end()
50 8
                        ->end()
51 8
                    ->end()
52 8
                ->end()
53 8
                ->arrayNode('throttle')
54 8
                    ->beforeNormalization()
55
                        ->ifTrue(function ($v) { return is_array($v) && (isset($v['limit']) || isset($v['period'])); })
56
                        ->then(function ($v) {
57
                            $v['default'] = [];
58
                            if (isset($v['limit'])) {
59
                                @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...
60
61
                                $v['default']['limit'] = $v['limit'];
62
                            }
63
64
                            if (isset($v['period'])) {
65
                                @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...
66
67
                                $v['default']['period'] = $v['period'];
68
                            }
69
70
                            return $v;
71 8
                        })
72 8
                    ->end()
73 8
                    ->addDefaultsIfNotSet()
74 8
                    ->children()
75 8
                        ->integerNode('limit')->min(1)->defaultValue(60)->end()
76 8
                        ->integerNode('period')->min(1)->defaultValue(60)->end()
77 8
                        ->arrayNode('default')
78 8
                            ->addDefaultsIfNotSet()
79 8
                            ->children()
80 8
                                ->integerNode('limit')->min(1)->defaultValue(60)->end()
81 8
                                ->integerNode('period')->min(1)->defaultValue(60)->end()
82 8
                            ->end()
83 8
                        ->end()
84 8
                        ->arrayNode('roles')
85 8
                            ->useAttributeAsKey('name')
86 8
                            ->prototype('array')
87 8
                                ->children()
88 8
                                    ->integerNode('limit')->isRequired()->min(1)->end()
89 8
                                    ->integerNode('period')->isRequired()->min(1)->end()
90 8
                                ->end()
91 8
                            ->end()
92 8
                        ->end()
93 8
                    ->end()
94 8
                ->end()
95 8
                ->arrayNode('exception')
96 8
                    ->addDefaultsIfNotSet()
97 8
                    ->children()
98 8
                        ->integerNode('status_code')
99 8
                            ->defaultValue(Response::HTTP_TOO_MANY_REQUESTS)
100 8
                            ->validate()
101 8
                            ->ifNotInArray(array_keys(Response::$statusTexts))
102 8
                                ->thenInvalid('Invalid status code "%s"')
103 8
                            ->end()
104 8
                        ->end()
105 8
                        ->scalarNode('message')->cannotBeEmpty()->defaultValue('API rate limit exceeded for %s.')->end()
106 8
                        ->scalarNode('custom_exception')
107 8
                            ->cannotBeEmpty()
108 8
                            ->defaultNull()
109 8
                            ->validate()
110 8
                            ->ifTrue(function ($v) {
111 3
                                if (!class_exists($v)) {
112 1
                                    return true;
113
                                }
114
115 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...
116 1
                                    return true;
117
                                }
118
119 1
                                return false;
120 8
                            })
121 8
                                ->thenInvalid('The class %s does not exist or not extend "Indragunawan\ApiRateLimitBundle\Exception\RateLimitExceededException" class.')
122 8
                            ->end()
123 8
                        ->end()
124 8
                    ->end()
125 8
                ->end()
126 8
            ->end();
127
128 8
        return $treeBuilder;
129
    }
130
}
131