0

In user.module, I need to alter the message that is displayed if the username/password is not recognized. I'm using the email registration module so I don't use usernames at all. I want the last form error message in the code below to show email/password instead, as well as add a custom redirect to it.

I've googled for quite some time, but cannot find how to hook onto this function. Any help would be appreciated!

function user_login_final_validate($form, &$form_state) { 
  if (empty($form_state['uid'])) {
  // Always register an IP-based failed login event.
  flood_register_event('failed_login_attempt_ip', variable_get('user_failed_login_ip_window', 3600));
  // Register a per-user failed login event.
  if (isset($form_state['flood_control_user_identifier'])) {
  flood_register_event('failed_login_attempt_user', variable_get('user_failed_login_user_window', 21600), $form_state['flood_control_user_identifier']);
}

if (isset($form_state['flood_control_triggered'])) {
  if ($form_state['flood_control_triggered'] == 'user') {
    form_set_error('name', format_plural(variable_get('user_failed_login_user_limit', 5), 'Sorry, there has been more than one failed login attempt for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', 'Sorry, there have been more than @count failed login attempts for this account. It is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => url('user/password'))));
  }
  else {
    // We did not find a uid, so the limit is IP-based.
    form_set_error('name', t('Sorry, too many failed login attempts from your IP address. This IP address is temporarily blocked. Try again later or <a href="@url">request a new password</a>.', array('@url' => url('user/password'))));
  }
}
else {
  // Fix password reset messages
  form_set_error('name', t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>', array('@password' => url('user/password', array('query' => array('name' => $form_state['values']['name']))))));
  watchdog('user', 'Login attempt failed for %user.', array('%user' => $form_state['values']['name']));
}

}

2 Answers 2

0

To change the validation function then you need to add it to the #validate part of the form array in hook_form_alter:

function MYMODULE_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'user_login') {
    $form['#validate'][] = 'MY_user_login_final_validate';
  }
}

You will need to examine the $form['#validate'] array to remove the current user module validation and possibly adjust the weight of the module in the system table.

To redirect you add something like the following to hook_form_alter:

$form['#submit'][] = 'my_redirect_node_form_submit';

Again bearing in mind you might need to alter/re-order the current contents of $form['#submit'] and the system table weight.

OR if you want to simply change the string then you could do it in a number of ways.

  1. The string overrides module: https://www.drupal.org/project/stringoverrides
  2. Put the overrides in the settings.php file:

    $conf['locale_custom_strings_en'][''] = array(
      'Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>' => 'YOUR MESSAGE HERE',
    );
    
  3. Put this in hook_boot() :

    global $conf;
    $conf['locale_custom_strings_en'][''] = array(
      'Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>' => 'YOUR MESSAGE HERE',
    );
    

The trick is to replicate exactly what is in the string surrounded by `t('') in the user module (currently this is line 2228).

      form_set_error('name', t('Sorry, unrecognized username or password. <a href="@password">Have you forgotten your password?</a>', array('@password' => url('user/password', array('query' => array('name' => $form_state['values']['name']))))));

Then you can let the Drupal string translation system take care of it for you. See here for a reference on Drupal.org

4
  • Great thanks for detailed resposne, I will try it today. Sep 30, 2015 at 16:01
  • Thanks for your suggestion, I was able to hook into that validation process but the user.module validation still is called last. I changed the user.module weight to 9018 (my module weight is 9001) in the system table, cleared caches several times but user.module's validation is still winning... I also tried pushing my hook's weight to the top as described in http://drupal.stackexchange.com/questions/21685/hook-module-implements-alter-not-working-for-me-what-am-i-doing-wrong Oct 1, 2015 at 16:51
  • I can't check today but I thought that the heavier weighted modules were called later, so is just that you need to make your module weight greater than the user module's?
    – bloke_zero
    Oct 2, 2015 at 7:52
  • You were right. I changed the user.module weight to 7018, and now it's working well! I was having another issue that was confusing since both the user.module and my module were throwing a form_set_error on the same element, therefore I would only see the user.module error. I had to use drupal_get_messages('error'); to clear the user's error, and then only my module's error was showing. Thanks again! Oct 2, 2015 at 13:02
0

Override login form with hook_form_alter()

You need to replace validation function with your custom function.

Your Answer

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

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