phpvalidationdrupal-7user-registrationform-api

how to intetrupt a form submission in drupal


I have made a custom module where I create one page. In that page I load the existing form for creating a new content and also add a password field. In my loaded form I have an email field. I want before submitting the form to check if there exists a user with the username the value found in the email field and the password offered by the password field. Here I have 3 scenarios:

  1. if the user does not exist I take the email and password and create an account then create the content
  2. if the user exists and the password is correct , I create the content
  3. if the user exists but the password is incorrect I stop the form submission

My problem is I don't know how to stop the form submission ( I am refering to scenario number 3). Any suggestions are most aprerciated

Here are the callback for the page function:

function add_new_article_simple_page() {
  module_load_include('inc', 'node', 'node.pages');
  $node_form = new stdClass;
  $node_form->type = 'announcement';
  $node_form->language = LANGUAGE_NONE;
  $form = drupal_get_form('announcement_node_form', $node_form);
  return $form;
}

the alter function to insert the password field :

function add_new_article_form_alter(&$form, &$form_state, $form_id){
  if($form_id=='announcement_node_form')
  {
    $form['#after_build'][] = 'add_new_article_after_build';
    $form['account_password'] = array(
        '#title' => 'Parola',
        '#type' => 'password',
        '#required' => TRUE,
    );
    $form['#submit'][] = 'add_new_article_form_submit';

    return $form;
  }
}

and the form submit function

function add_new_article_form_submit($form, &$form_state){
  $email=$form_state['values']['field_email']['und'][0]['value'];
  $password=$form_state['values']['account_password'];
  //check if the email even exists
  if(!db_query("SELECT COUNT(*) FROM {users} WHERE name = '".$email."';")->fetchField())
  //create the new account
  {     
    $edit = array(
        'name' => $email,
        'pass' => $password,
        'mail' => $email,
        'init' => $email,
        'roles' => array('4' => 'standard user'),
        'status' => 0,
        'access' => REQUEST_TIME,
    );
    $loc_var=user_save(drupal_anonymous_user(), $edit);
    $GLOBALS['new_user']=$loc_var->uid;     
  }
  else
  {
    //check if username + password are valid combination
    if($uid = user_authenticate($email,$password))
        //log in user after account creation
    else
        //this is where I want to interrupt the submission of the form
        form_set_error('account_password', 'Parola nu este buna pentru acest email.');
  }
}

UPDATE

My bad , I forgot to explain what happens when i test the 3rd scenario. The content is created , the page jumps to that content page and that is where the error message appears

UPDATE 2 I have followed D34dman suggestion and wrote a simple validation function which should always give an error. The problem is that the content is still submited and saved. It doesn't seem to even call hook_form_validate .. Here is the function :

function add_new_article_form_validate($form, &$form_state) 
{
    $email=$form_state['values']['field_email']['und'][0]['value'];
    $password=$form_state['values']['account_password'];
    form_set_error('account_password',t('The form is being validated.'.$email.' and '.$password));
}

Thank you, Cristi


Solution

  • It is not a good practice to prevent a form from submitting. Instead use hook_form_validate as below.

    /**
     * Implements hook_form_validate().
     */
    function add_new_article_form_validate(&$form, &$form_state) {
      // Validate email address.
      $mail = $form_state['values']['personal']['email_address'];
      $password=$form_state['values']['account_password'];
      if (!valid_email_address($mail)) {
        form_set_error('personal][email_address', t('The email address appears to be invalid.'));
      }
      else if (user_load_by_mail($mail)) {
        if($uid = user_authenticate($email,$password)) {
          $account = user_load($uid);
          // Check if the user would have permission to create content after login!!!
          // not asked by OP, but just a suggestion.
          if (!user_access($string, $account)) {
            form_set_error('personal][email_address', t('You donot have sufficient priviledge to create the content.'));
          }
        }
        else {
          form_set_error('personal][email_address', t('Email or password incorrect.'));
        }
      }
    }
    

    NOTE: Please don't try to create a user in validate function. Do that in form submit function. Since there could be other validators which might fail, you may not be sure how many times your form would be submitted for validation.