Completed
Push — master ( e41328...feabfc )
by
unknown
15:35 queued 43s
created

PathLimitProcessor::getMatchedPath()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.1406

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
ccs 6
cts 8
cp 0.75
rs 9.8333
cc 3
nc 3
nop 1
crap 3.1406
1
<?php
2
3
4
namespace Noxlogic\RateLimitBundle\Util;
5
6
use Noxlogic\RateLimitBundle\Annotation\RateLimit;
7
use Symfony\Component\HttpFoundation\Request;
8
9
class PathLimitProcessor
10
{
11
    private $pathLimits;
12
13 13
    function __construct(array $pathLimits)
14
    {
15 13
        $this->pathLimits = $pathLimits;
16
17
        // Clean up any extra slashes from the config
18 13
        foreach ($this->pathLimits as &$pathLimit) {
19 12
            $pathLimit['path'] = trim($pathLimit['path'], '/');
20 13
        }
21
22
        // Order the configs so that the most specific paths
23
        // are matched first
24 13
        usort($this->pathLimits, function($a, $b) {
25 4
            return substr_count($b['path'], '/') - substr_count($a['path'], '/');
26 13
        });
27 13
    }
28
29 10
    public function getRateLimit(Request $request)
30
    {
31 10
        $path = trim(urldecode($request->getPathInfo()), '/');
32 10
        $method = $request->getMethod();
33
34 10
        foreach ($this->pathLimits as $pathLimit) {
35 9
            if ($this->requestMatched($pathLimit, $path, $method)) {
36 8
                return new RateLimit(array(
37 8
                    'limit' => $pathLimit['limit'],
38 8
                    'period' => $pathLimit['period'],
39 8
                    'methods' => $pathLimit['methods']
40 8
                ));
41
            }
42 2
        }
43
44 2
        return null;
45
    }
46
47 3
    public function getMatchedPath(Request $request)
48
    {
49 3
        $path = trim($request->getPathInfo(), '/');
50 3
        $method = $request->getMethod();
51
52 3
        foreach ($this->pathLimits as $pathLimit) {
53 3
            if ($this->requestMatched($pathLimit, $path, $method)) {
54 3
                return $pathLimit['path'];
55
            }
56
        }
57
58
        return '';
59
    }
60
61 12
    private function requestMatched($pathLimit, $path, $method)
62
    {
63 12
       return $this->methodMatched($pathLimit['methods'], $method)
64 12
            && $this->pathMatched($pathLimit['path'], $path);
65
    }
66
67 12
    private function methodMatched(array $expectedMethods, $method)
68
    {
69 12
        foreach ($expectedMethods as $expectedMethod) {
70 12
            if ($expectedMethod === '*' || $expectedMethod === $method) {
71 12
                return true;
72
            }
73 2
        }
74
75
        return false;
76
    }
77
78 12
    private function pathMatched($expectedPath, $path)
79
    {
80 12
        $expectedParts = explode('/', $expectedPath);
81 12
        $actualParts = explode('/', $path);
82
83 12
        if (sizeof($actualParts) < sizeof($expectedParts)) {
84 1
            return false;
85
        }
86
87 11
        foreach ($expectedParts as $key => $value) {
88 11
            if ($value !== $actualParts[$key]) {
89
                return false;
90
            }
91 11
        }
92
93 11
        return true;
94
    }
95
}