1

I'd like to track the number of times a user has failed a form validation.

It doesn't necessarily matter if the end user has access to the variable, or even the ability to manipulate it client side, as the purpose is to provide additional help to the user by detecting when they might not be in trouble.

At this point I think I'm leaning towards adding a hidden field and incrementing that value, but I'm interested to know if there's a cleaner method that does prevent access and manipulation in my quest for knowledge :)

Thanks for any advice.

UPDATE

As per tunic's advice below, I'm trying the $form_state route but this doesn't appear to be persisting. In my form validation function I have:

// Track the number of attempts.
if (!isset($form_state['mymodule']['attempts'])) {
  drupal_set_message('attempts not set');
  $form_state['mymodule']['attempts'] = 0;
}
$form_state['mymodule']['attempts']++;
drupal_set_message($form_state['mymodule']['attempts'] . ' attempts');

However repeatedly submitting a form with errors results in the following output each time:

attempts not set
1 attempts

SOLUTION

Having difficulty arguing with $form_state I instead went for the core flood module as suggested below, with the following code, in my validator:

function mymodule_booking_register_online_form_validate($form, &$form_state) {
  if (form_get_errors()) {
    form_set_error('', 'There was a problem registering your online account, please try again.');
    flood_register_event('mymodule_booking_register');
  }
}

And then to handle the result of this event, back in my form definition:

function mymodule_booking_register_online_form($form, &$form_state) {
  if (flood_is_allowed('mymodule_booking_register', 5, 3600)) {
    ...
  else {
    drupal_set_message('You have incorrectly entered your personal details too many times. Please call us on 12345678 to ask for your user code and then enter it in the form below.');
    ...
  }
}
2
  • Drupal 6 or Drupal 7?
    – sanzante
    Commented Oct 16, 2013 at 7:37
  • Drupal 7, sorry should have specified.
    – DanH
    Commented Oct 16, 2013 at 8:34

2 Answers 2

3

How about using drupal 'floding mechanism' for login attempts ,so using flood_register_event() to have entry for custom event in flood table,but might be too overkill !

A better picture can be seen inside user_login_authenticate_validate() in user.module

2
  • This works great, and I can't see why it'd be overkill. Arguably it's not a "flood" but the functionality it provides is a perfect fit. Thanks!
    – DanH
    Commented Oct 16, 2013 at 9:45
  • the reason it might be overkill is it makes database query and the reason I used "flood" was just to address the functionality :)
    – arpitr
    Commented Oct 16, 2013 at 10:02
5

Just use a variable insider $form_state.

In validate function

if ($validation_failed) {
  $form_state['error_count']++
  $form_state['cache'] = TRUE;
}

Then, in your form function just check $form_state['error_count'].

$form_state will be persistent between page petitions while validation fails thanks to $form_state['cache'].

You can also check for errors using form_get_errors().

7
  • Good answer. Will not work for client-side validation and if user force-purge his browser, so it will only work for honest mistakes and stupid robots, but I think most cases are covered.
    – Mołot
    Commented Oct 15, 2013 at 11:37
  • Usually editing code is a bad thing, but this time it was obvious typo. Note: correcting code typos in questions is different story.
    – Mołot
    Commented Oct 15, 2013 at 11:57
  • Unfortunately I can't get this to work, please see my updated question.
    – DanH
    Commented Oct 16, 2013 at 2:08
  • I didn't add the $form_state['cache'] = TRUE line, this will make your form_stage persistent. Sorry.
    – sanzante
    Commented Oct 16, 2013 at 11:22
  • Oh very interesting, maybe I'll try that as well, running into a few oddities with the flood route. Thanks!
    – DanH
    Commented Oct 17, 2013 at 1:54

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.