RateLimitStore
The shared fixed-window counter behind every rate limit in the plugin — today the REST limiter and the [benecaster_follower_signup] abuse throttle.
If you need a limit, call hit(). Do not hand-roll another get_transient / set_transient pair. That is what this class exists to prevent. Before it there was exactly one limiter, Benecaster\REST\RateLimiter, and it only works for REST routes because it hooks rest_pre_dispatch and matches on route patterns — the follower signup form is a plain front-end POST and never passes through it. A third consumer is already anticipated. Three bespoke transient guards, each with its own off-by-one in the window reset, is the outcome this class was written to avoid.
Storage is transients, so an object cache (Redis, Memcached) is used automatically where one is present and the database is the fallback.
It is a fixed window, not a sliding one. Up to 2 × limit requests can land across a window boundary. That is the standard trade-off and is fine for abuse control. It is not fine if you need a hard guarantee, and this class is the wrong tool for that.