1

In Drupal 6.25.

I am building a custom user registration form that needs to run some actions on an external service after properly passing default form validation but before creating a new user record in Drupal. So far I am doing the following:

function mbrusers_form_alter(&$form, &$form_state, $form_id){
   if($form_id == "user_register"){
       if($default_form_validation_passed){
           $form['#validate'][] = 'mbrusers_infusionConnect_validate';
       }
   }
}

function mbrusers_infusionConnect_validate($form, &$form_state){
    // Run actions on external service
    if($error){
        form_set_error("", "SET ERROR");
    }
}

I feel like I'm overlooking something, but I haven't been able to figure out what to do. Maybe using validate is the wrong idea? Any help that sets me in the right direction is appreciated.

1

You should be able to rearrange the order of multiple validation functions in the $form['#validate'] array. After ensuring that your function runs in the correct order, wrap your code acting on your service in an if statement checking for existing form errors using form_get_errors(), like so:

// Validation has already failed if prior functions return errors, so this is safe.
if (empty(form_get_errors())) {
  // Run calls on external service here...
  if($error){
    form_set_error("", "SET ERROR");
  }
}

Since you need to validate the response from your service, doing it in the validation phase makes the most sense.

  • You are right. It is validation, and this solution is the right one. :) Thank you very much! – Todd Mar 5 '12 at 6:48
1

I'm pretty sure you have to re-arrange the order of the validators, and inject yours basically in the middle instead of just adding it at the end.

From user.module, $form['#validate'] = user_login_default_validators(); or:

/**
 * Set up a series for validators which check for blocked/denied users,
 * then authenticate against local database, then return an error if
 * authentication fails. Distributed authentication modules are welcome
 * to use hook_form_alter() to change this series in order to
 * authenticate against their user database instead of the local users
 * table.
 *
 * We use three validators instead of one since external authentication
 * modules usually only need to alter the second validator.
 *
 * @see user_login_name_validate()
 * @see user_login_authenticate_validate()
 * @see user_login_final_validate()
 * @return array
 *   A simple list of validate functions.
 */
function user_login_default_validators() {
  return array('user_login_name_validate', 'user_login_authenticate_validate', 'user_login_final_validate');
}

and

/**
 * A validate handler on the login form. Check supplied username/password
 * against local users table. If successful, sets the global $user object.
 */
function user_login_authenticate_validate($form, &$form_state) {
  user_authenticate($form_state['values']);
}

so I'd do something like:

$form['#validate'] = array('user_login_name_validate', 'mbrusers_infusionConnect_validate', 'user_login_authenticate_validate', 'user_login_final_validate');

instead of if <Default form validation passed> so that your validation function is called before the normal/usual second validator.

  • This sounded really good, but unfortunately it executes all validations in the array whether or not the preceding validation(s) passes. I think the idea of using hook_user to accomplish this is better suited than the form validation stuff. Thank you for your answer though. – Todd Mar 5 '12 at 5:28
  • Ugh. I read "login" not "register" in your question and that's what I answered. Glad it got resolved. – Jimajamma Mar 5 '12 at 16:07
1

Another way to achieve your functionality I reckon is to use hook_user and trap $op = 'insert' to do something before the user account is added to the Drupal database.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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