maxAttempts = $maxAttempts; $this->timeWindow = $timeWindow; $this->cache = $cache ?? new FileCache(); } /** * Bepaal of een nieuwe poging voor de identifier is toegestaan. * * Verwijder eerst pogingen die buiten het tijdvenster vallen. Wanneer het * aantal resterende pogingen onder het maximum ligt wordt de huidige * poging geregistreerd en true teruggegeven; anders false. * * @since 2.6.4 * * @param string $identifier Unieke sleutel voor de te beperken actor (bijv. IP of gebruikersnaam). * @return bool True wanneer de poging is toegestaan, false wanneer het limiet is bereikt. */ public function isAllowed(string $identifier): bool { $key = 'ratelimit_' . md5($identifier); $attempts = $this->cache->get($key) ?? []; // Clean old attempts $now = time(); $windowStart = $now - $this->timeWindow; $attempts = array_filter($attempts, fn($time) => $time > $windowStart); $attemptCount = count($attempts); if ($attemptCount >= $this->maxAttempts) { return false; } $attempts[] = $now; $this->cache->set($key, $attempts, $this->timeWindow); return true; } /** * Geef het aantal nog resterende pogingen voor de identifier. * * Telt alleen pogingen die binnen het tijdvenster vallen. Het resultaat * is nooit negatief. * * @since 2.6.4 * * @param string $identifier Unieke sleutel voor de te beperken actor. * @return int Aantal resterende pogingen; minimaal 0. */ public function getRemainingAttempts(string $identifier): int { $key = 'ratelimit_' . md5($identifier); $attempts = $this->cache->get($key) ?? []; // Clean old attempts $now = time(); $windowStart = $now - $this->timeWindow; $attempts = array_filter($attempts, fn($time) => $time > $windowStart); return max(0, $this->maxAttempts - count($attempts)); } /** * Wis alle geregistreerde pogingen voor een identifier. * * @since 2.6.4 * * @param string $identifier Unieke sleutel voor de te beperken actor. * @return void */ public function reset(string $identifier): void { $key = 'ratelimit_' . md5($identifier); $this->cache->delete($key); } }