1

I'm working on a two-factor login form that sends a text message to the user. With a "did not recieve message" button. I would like to limit the number of times a user can request for a new text message.

I know that I can register flood for a certain event like: \Drupal::flood()->register('eventName', 1800, $user->getUuid()). The FloodInterface has a isAllowed($name, $threshold, $window = 3600, $identifier = NULL); method that, I imagine, tests when a user tries to do a certain $name event, it tests if that event has been done more often than the $threshold within the $window. If so then the method returns false and otherwise true.

In my example I can register the event somewhere in the chain of events/functions that send the message and also check there if the event isAllowed?

Something like so:?

public function someFunction() {
  \Drupal::flood()->register('send message', 900, $user->getUuid());
  $token = 12345;
  $this->sendMessage($token);
}

private function sendMessage($token) {
  $is_allowed = \Drupal::flood()->isAllowed('send message', 3, 900, $user->getUuid());
  if ($is_allowed) {
    // Send the message
  }
}

What I don't get is why I also have to indicate the $window in the isAllowed method when I already assign that in the register method?

1 Answer 1

4

They are two different parameters that share the same name (and can share the same value by default). Per the docs for FloodInterface:

  • ::register():

    • int $window: (optional) Number of seconds before this event expires. Defaults to 3600 (1 hour). Typically uses the same value as the isAllowed() $window parameter. Expired events are purged on cron run to prevent the flood table from growing indefinitely.

  • ::isAllowed():

    • int $window: (optional) Number of seconds in the time window for this event (default is 3600 seconds, or 1 hour).

The register() parameter specifies how long that flood event will be stored (remembered) after the time of registration before ::garbageCollection() clears it out. The isAllowed() parameter specifies the max number of instances that can occur within that window before isAllowed() will return FALSE

2
  • So I get the difference between the two $window variables. But it's not clear to me if the $itentifier for the ::isAllowed method will use the same value that you used when registering the even when you do not include it in the isAllowed:: call. Commented Nov 1, 2020 at 22:26
  • It will depend on the implementing class of course, but the default for core flood classes is to use the client IP address when $identifer hasn't been specified. To make things more concrete, take a look @ DatabaseBackend class that implements the interface via the flood table.
    – Shawn Conn
    Commented Nov 2, 2020 at 15:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.