Add an additional validation function to an existing Drupal form

There are many reasons why you might want to add extra validation rules to a Drupal form. This is a simple tutorial on how to add a validation function to an existing form that is generated from a module that you have not created yourself. It could be in a core or contributed module.

The problem

A form has been created by another module, but we need to add additional validation.

The solution

1) Use hook_form_alter to alter the form and add an additional validation function

<?php
/**
 * Implementation of hook_form_alter().
 */
function my_module_form_alter(&$form, $form_state, $form_id) {
 if ($form_id == 'example_form_id') {
  array_unshift($form['#validate'], 'example_validate');
 }
}
?>

array_unshift will add the validation function to the beginning of the $form['#validate'] array. This is helpful if you require other validation function to process after your new one. For example, if the form is the user login form (form ID is user_login), then the user_login_final_validate function should happen last. Therefore, we wouldn't want to add a validation function to the end of the $form['#validate'] array.

If it doesn't matter if the validation function goes at the end of the $form['#validate'] array, then the standard way to add a validation function is as follows:

$form['#validate'][] = example_validate;

2) Add the custom validation function

/**
 * Validate profile form
 *
 */
function example_validate ($form, $form_state) {
  //perform some validation logic
}

Working example

As an example, I want to add extra validation when a user changes his/her email address. If the new email address is the same as their existing email address, I want the form to not validation and display a validation error (since the user should add a different email address).

/**
 * Implementation of hook_form_alter().
 */function my_module_form_alter(&$form, $form_state, $form_id)  {
 if ($form_id == 'user_profile_form') {
  array_unshift($form['#validate'], 'email_check_validate');
 }
}
 
/**
 * Validate profile form
 * Force form error if new email address matches current email address
 *
 */
function email_check_validate ($form, $form_state)  {
  global $user;
  $old_email = $user->mail;
  $new_email = $form_state['values']['mail'];
 
  if ($old_email ==  $new_email) {
    form_set_error('mail', t('Your email could not be changed'));
  }
}

In the above validation function, I am comparing the user's current email address, as defined by the user object of the current logged in user($user->mail), with the new email address from the form itself ($form_state['values']['mail']). If they match, the user has entered the same email address as their current email address, therefore the form does not validate and the user receives an error message.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options