Passed
Pull Request — master (#203)
by
unknown
12:43
created

Counter::generateId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 3
c 1
b 0
f 1
nc 2
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Web\RateLimiter;
6
7
use Psr\Http\Message\ServerRequestInterface;
8
9
final class Counter implements CounterInterface
10
{
11
    private int $interval = 360;
12
13
    private ?string $id = null;
14
15
    /**
16
     * @var callable
17
     */
18
    private $idCallback;
19
20
    private bool $init = false;
21
22
    private StorageInterface $storage;
23
24
    public function __construct(StorageInterface $storage)
25
    {
26
        $this->storage = $storage;
27
    }
28
29
    public function init(ServerRequestInterface $request): self
30
    {
31
        $this->id = $this->generateId($request);
32
33
        if (!$this->storage->hasCounterValue($this->id)) {
34
            $this->storage->setCounterValue($this->id, 0, $this->interval);
35
        }
36
37
        $this->init = true;
38
39
        return $this;
40
    }
41
42
    public function setIdCallback(callable $callback): self
43
    {
44
        $this->idCallback = $callback;
45
46
        return $this;
47
    }
48
49
    public function setId(string $id): self
50
    {
51
        $this->id = $id;
52
53
        return $this;
54
    }
55
56
    public function setInterval(int $interval): self
57
    {
58
        $this->interval = $interval;
59
60
        return $this;
61
    }
62
63
    public function increment(): void
64
    {
65
        $value = $this->getCounterValue();
66
        $value++;
67
68
        $this->storage->setCounterValue($this->id, $value, $this->interval);
0 ignored issues
show
Bug introduced by
It seems like $this->id can also be of type null; however, parameter $id of Yiisoft\Yii\Web\RateLimi...face::setCounterValue() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

68
        $this->storage->setCounterValue(/** @scrutinizer ignore-type */ $this->id, $value, $this->interval);
Loading history...
69
    }
70
71
    public function getCounterValue(): int
72
    {
73
        $this->checkInit();
74
        return $this->storage->getCounterValue($this->id);
0 ignored issues
show
Bug introduced by
It seems like $this->id can also be of type null; however, parameter $id of Yiisoft\Yii\Web\RateLimi...face::getCounterValue() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

74
        return $this->storage->getCounterValue(/** @scrutinizer ignore-type */ $this->id);
Loading history...
75
    }
76
77
    private function hasIdCallback(): bool
78
    {
79
        return $this->idCallback !== null;
80
    }
81
82
    private function generateId(ServerRequestInterface $request): string
83
    {
84
        if ($this->hasIdCallback()) {
85
            return \call_user_func($this->idCallback, $request);
86
        }
87
88
        return $this->id ?? $this->generateIdFromRequest($request);
89
    }
90
91
    private function generateIdFromRequest(ServerRequestInterface $request): string
92
    {
93
        return strtolower('rate-limiter-' . $request->getMethod() . '-' . $request->getUri()->getPath());
94
    }
95
96
    private function checkInit(): void
97
    {
98
        if (!$this->init) {
99
            throw new \RuntimeException('The counter was not initiated');
100
        }
101
    }
102
}
103