3 namespace Drupal\Core\Flood;
5 use Symfony\Component\HttpFoundation\RequestStack;
8 * Defines the memory flood backend. This is used for testing.
10 class MemoryBackend implements FloodInterface {
15 * @var \Symfony\Component\HttpFoundation\RequestStack
17 protected $requestStack;
20 * An array holding flood events, keyed by event name and identifier.
22 protected $events = [];
25 * Construct the MemoryBackend.
27 * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
28 * The request stack used to retrieve the current request.
30 public function __construct(RequestStack $request_stack) {
31 $this->requestStack = $request_stack;
37 public function register($name, $window = 3600, $identifier = NULL) {
38 if (!isset($identifier)) {
39 $identifier = $this->requestStack->getCurrentRequest()->getClientIp();
41 // We can't use REQUEST_TIME here, because that would not guarantee
43 $time = microtime(TRUE);
44 $this->events[$name][$identifier][$time + $window] = $time;
50 public function clear($name, $identifier = NULL) {
51 if (!isset($identifier)) {
52 $identifier = $this->requestStack->getCurrentRequest()->getClientIp();
54 unset($this->events[$name][$identifier]);
60 public function isAllowed($name, $threshold, $window = 3600, $identifier = NULL) {
61 if (!isset($identifier)) {
62 $identifier = $this->requestStack->getCurrentRequest()->getClientIp();
64 if (!isset($this->events[$name][$identifier])) {
65 return $threshold > 0;
67 $limit = microtime(TRUE) - $window;
68 $number = count(array_filter($this->events[$name][$identifier], function ($timestamp) use ($limit) {
69 return $timestamp > $limit;
71 return ($number < $threshold);
77 public function garbageCollection() {
78 foreach ($this->events as $name => $identifiers) {
79 foreach ($this->events[$name] as $identifier => $timestamps) {
80 // Filter by key (expiration) but preserve key => value associations.
81 $this->events[$name][$identifier] = array_filter($timestamps, function () use (&$timestamps) {
82 $expiration = key($timestamps);
84 return $expiration > microtime(TRUE);