| 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 | 11 |  |     public function getConfigTreeBuilder() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 | 11 |  |         if (method_exists(TreeBuilder::class, 'getRootNode')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 | 11 |  |             $treeBuilder = new TreeBuilder('indragunawan_api_rate_limit'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 | 11 |  |             $rootNode = $treeBuilder->getRootNode(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |             $treeBuilder = new TreeBuilder(); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |             $rootNode = $treeBuilder->root('indragunawan_api_rate_limit'); | 
                            
                    |  |  |  | 
                                                                                        
                                                                                     | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |         $rootNode | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 | 11 |  |             ->children() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 | 11 |  |                 ->booleanNode('enabled')->defaultTrue()->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 | 11 |  |                 ->scalarNode('cache')->defaultNull()->cannotBeEmpty()->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 | 11 |  |                 ->arrayNode('header') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 | 11 |  |                     ->addDefaultsIfNotSet() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 | 11 |  |                     ->children() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 | 11 |  |                         ->booleanNode('display')->defaultTrue()->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 | 11 |  |                         ->arrayNode('names') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 | 11 |  |                             ->addDefaultsIfNotSet() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 | 11 |  |                             ->children() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 | 11 |  |                                 ->scalarNode('limit')->cannotBeEmpty()->defaultValue('X-RateLimit-Limit')->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 | 11 |  |                                 ->scalarNode('remaining')->cannotBeEmpty()->defaultValue('X-RateLimit-Remaining')->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 | 11 |  |                                 ->scalarNode('reset')->cannotBeEmpty()->defaultValue('X-RateLimit-Reset')->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 | 11 |  |                             ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 | 11 |  |                         ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 | 11 |  |                     ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 | 11 |  |                 ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 | 11 |  |                 ->arrayNode('throttle') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 | 11 |  |                     ->beforeNormalization() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |                         ->ifTrue(function ($v) { return is_array($v) && (isset($v['limit']) || isset($v['period'])); }) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |                         ->then(function ($v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 | 1 |  |                             $v['default'] = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 | 1 |  |                             if (isset($v['limit'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 | 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); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 | 1 |  |                                 $v['default']['limit'] = $v['limit']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 | 1 |  |                             if (isset($v['period'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 | 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); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 | 1 |  |                                 $v['default']['period'] = $v['period']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |                             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 | 1 |  |                             return $v; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 | 11 |  |                         }) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 | 11 |  |                     ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 | 11 |  |                     ->addDefaultsIfNotSet() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 | 11 |  |                     ->children() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 | 11 |  |                         ->integerNode('limit')->min(1)->defaultValue(60)->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 | 11 |  |                         ->integerNode('period')->min(1)->defaultValue(60)->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 | 11 |  |                         ->arrayNode('default') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 | 11 |  |                             ->addDefaultsIfNotSet() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 | 11 |  |                             ->children() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 | 11 |  |                                 ->integerNode('limit')->min(1)->defaultValue(60)->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 | 11 |  |                                 ->integerNode('period')->min(1)->defaultValue(60)->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 | 11 |  |                             ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 | 11 |  |                         ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 | 11 |  |                         ->arrayNode('roles') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 | 11 |  |                             ->useAttributeAsKey('name') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 | 11 |  |                             ->prototype('array') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 | 11 |  |                                 ->children() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 | 11 |  |                                     ->integerNode('limit')->isRequired()->min(1)->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 | 11 |  |                                     ->integerNode('period')->isRequired()->min(1)->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 | 11 |  |                                 ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 | 11 |  |                             ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 | 11 |  |                         ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 | 11 |  |                         ->enumNode('sort') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 | 11 |  |                             ->values(['first-match', 'rate-limit-asc', 'rate-limit-desc']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 | 11 |  |                             ->defaultValue('rate-limit-desc') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 | 11 |  |                         ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 | 11 |  |                     ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 | 11 |  |                 ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 | 11 |  |                 ->arrayNode('exception') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 | 11 |  |                     ->addDefaultsIfNotSet() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 | 11 |  |                     ->children() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 | 11 |  |                         ->integerNode('status_code') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 | 11 |  |                             ->defaultValue(Response::HTTP_TOO_MANY_REQUESTS) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 | 11 |  |                             ->validate() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 | 11 |  |                             ->ifNotInArray(array_keys(Response::$statusTexts)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 | 11 |  |                                 ->thenInvalid('Invalid status code "%s"') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 | 11 |  |                             ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 | 11 |  |                         ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 | 11 |  |                         ->scalarNode('message')->cannotBeEmpty()->defaultValue('API rate limit exceeded for %s.')->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 | 11 |  |                         ->scalarNode('custom_exception') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 | 11 |  |                             ->cannotBeEmpty() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 | 11 |  |                             ->defaultNull() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 | 11 |  |                             ->validate() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |                             ->ifTrue(function ($v) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 | 3 |  |                                 if (!class_exists($v)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 | 1 |  |                                     return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |                                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 | 2 |  |                                 if (!is_subclass_of($v, RateLimitExceededException::class)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 | 1 |  |                                     return true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |                                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 | 1 |  |                                 return false; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 | 11 |  |                             }) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 | 11 |  |                                 ->thenInvalid('The class %s does not exist or not extend "Indragunawan\ApiRateLimitBundle\Exception\RateLimitExceededException" class.') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 | 11 |  |                             ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 | 11 |  |                         ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 | 11 |  |                     ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 | 11 |  |                 ->end() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 | 11 |  |             ->end(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 136 | 11 |  |         return $treeBuilder; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 138 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 139 |  |  |  | 
            
                        
This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.