1 | <?php |
||
40 | class RateLimiter extends ActionFilter |
||
41 | { |
||
42 | /** |
||
43 | * @var bool whether to include rate limit headers in the response |
||
44 | */ |
||
45 | public $enableRateLimitHeaders = true; |
||
46 | /** |
||
47 | * @var string the message to be displayed when rate limit exceeds |
||
48 | */ |
||
49 | public $errorMessage = 'Rate limit exceeded.'; |
||
50 | /** |
||
51 | * @var RateLimitInterface the user object that implements the RateLimitInterface. |
||
52 | * If not set, it will take the value of `Yii::$app->user->getIdentity(false)`. |
||
53 | */ |
||
54 | public $user; |
||
55 | /** |
||
56 | * @var Request the current request. If not set, the `request` application component will be used. |
||
57 | */ |
||
58 | public $request; |
||
59 | /** |
||
60 | * @var Response the response to be sent. If not set, the `response` application component will be used. |
||
61 | */ |
||
62 | public $response; |
||
63 | |||
64 | |||
65 | /** |
||
66 | * @inheritdoc |
||
67 | */ |
||
68 | 12 | public function init() |
|
69 | { |
||
70 | 12 | if ($this->request === null) { |
|
71 | 11 | $this->request = Yii::$app->getRequest(); |
|
72 | } |
||
73 | 12 | if ($this->response === null) { |
|
74 | 11 | $this->response = Yii::$app->getResponse(); |
|
75 | } |
||
76 | 12 | } |
|
77 | |||
78 | /** |
||
79 | * @inheritdoc |
||
80 | */ |
||
81 | 3 | public function beforeAction($action) |
|
98 | |||
99 | /** |
||
100 | * Checks whether the rate limit exceeds. |
||
101 | * @param RateLimitInterface $user the current user |
||
102 | * @param Request $request |
||
103 | * @param Response $response |
||
104 | * @param \yii\base\Action $action the action to be executed |
||
105 | * @throws TooManyRequestsHttpException if rate limit exceeds |
||
106 | */ |
||
107 | 3 | public function checkRateLimit($user, $request, $response, $action) |
|
108 | { |
||
109 | 3 | $current = time(); |
|
110 | |||
111 | 3 | list ($limit, $window) = $user->getRateLimit($request, $action); |
|
112 | 3 | list ($allowance, $timestamp) = $user->loadAllowance($request, $action); |
|
113 | |||
114 | 3 | $allowance += (int) (($current - $timestamp) * $limit / $window); |
|
115 | 3 | if ($allowance > $limit) { |
|
116 | $allowance = $limit; |
||
117 | } |
||
118 | |||
119 | 3 | if ($allowance < 1) { |
|
120 | 1 | $user->saveAllowance($request, $action, 0, $current); |
|
121 | 1 | $this->addRateLimitHeaders($response, $limit, 0, $window); |
|
122 | 1 | throw new TooManyRequestsHttpException($this->errorMessage); |
|
123 | } else { |
||
124 | 2 | $user->saveAllowance($request, $action, $allowance - 1, $current); |
|
125 | 2 | $this->addRateLimitHeaders($response, $limit, $allowance - 1, (int) (($limit - $allowance) * $window / $limit)); |
|
126 | } |
||
127 | 2 | } |
|
128 | |||
129 | /** |
||
130 | * Adds the rate limit headers to the response |
||
131 | * @param Response $response |
||
132 | * @param int $limit the maximum number of allowed requests during a period |
||
133 | * @param int $remaining the remaining number of allowed requests within the current period |
||
134 | * @param int $reset the number of seconds to wait before having maximum number of allowed requests again |
||
135 | */ |
||
136 | 4 | public function addRateLimitHeaders($response, $limit, $remaining, $reset) |
|
145 | } |
||
146 |
It seems like the method you are trying to call exists only in some of the possible types.
Let’s take a look at an example:
Available Fixes
Add an additional type-check:
Only allow a single type to be passed if the variable comes from a parameter: