transients->get($key); $start = is_array($bucket) ? (int) ($bucket['start'] ?? 0) : 0; $hits = is_array($bucket) ? (int) ($bucket['hits'] ?? 0) : 0; // A bucket whose window has lapsed is a new window, whether or not the // transient itself has been collected yet — an object cache may hand // back a value past its expiry, and the arithmetic must not depend on // it having been swept. if ($start + self::WINDOW <= $now) { $start = $now; $hits = 0; } $hits++; // Written on every request, refused ones included: a caller who keeps // knocking does not get a quieter window for it. $this->transients->set($key, ['start' => $start, 'hits' => $hits], self::WINDOW); return $hits <= self::ALLOWED; } }