background image
HomeRecent PostsDrupalSearchTagsRSSContactAboutAccount
Eric.London's picture

In this code snippet tutorial, I'll show how you can use the PEAR library HTML_QuickForm2 to create a simple authentication form with a custom validation callback.

<?php
// start session
session_start();

// check if user needs to authenticate
if (empty($_SESSION['accountID'])) {
 
 
// show form
 
require_once('HTML/QuickForm2.php');
 
// NOTE: have the form submit to itself
 
$form = new HTML_QuickForm2('login', 'post', array('action' => $_SERVER['REQUEST_URI']));

 
// add username field
 
$username = $form->addElement('text', 'username')->setLabel('username:');
 
$username->addRule('required', 'username is required.');

 
// add password field
 
$password = $form->addElement('password', 'password')->setLabel('password:');
 
$password->addRule('required', 'password is required.');

 
// add submit button
 
$form->addElement('submit', null, array('value' => 'submit'));

 
// add filter to trim all elements
 
$form->addRecursiveFilter('trim');

 
// add custom validation rule
 
$form->addRule(
   
'callback',
   
'authentication failed.',
    array(
     
'callback' => 'portal_authentication_validation',
    )
  );

 
// check if form validates
 
if ($form->validate()) {
   
   
// at this point, the form has validated, set session data as authentication
    // NOTE: at this point, the account ID should be fetched from the database, etc
   
$_SESSION['accountID'] = 'some_val';
   
   
// redirect user (reload url)
   
header("Location: " . $_SERVER['REQUEST_URI']);
    die;
   
  }
 
// form did not pass validation, display form
 
else {

   
// display form
   
echo $form;
 
  }
  
}
// user is already authenticated..
else {

 
// do something here!
 
echo "Hello Auth User!";

}

// defines custom validation callback function
function portal_authentication_validation($form_args) {

 
/*
  Args..
  $form_args['username']
  $form_args['password']
  */

  // At this point, query the database to validate username/password, etc
 
if ($user_and_password_validates) {
    return
TRUE:
  }
 
  return
FALSE;

}
?>

The above code will result in the following form:
Authentication form

At some point you might want add validation to the user edit form to ensure username is a valid email address. You can accomplish this by adding a form_alter hook, testing for the user profile form, and adding a validation handler to the $form object.

<?php
function MYMODULE_form_alter(&$form, $form_state, $form_id) {
 
// test for the user profile edit form
 
if ($form_id == 'user_profile_form') {
   
// add another validation function to the list
   
$form['#validate'][] = '_MYMODULE_form_alter_user_profile_validate';
  }
}

// define the validation function
function _MYMODULE_form_alter_user_profile_validate($form, &$form_state) {
 
// validate the username and set a form error as necessary
 
if (!valid_email_address($form_state['values']['name']))
   
form_set_error('name', 'Username must be a valid email address.');
}
?>

In a module I was developing recently, I needed to add a javascript confirm popup before allowing the user to submit the form. Here is an excerpt from my code to show you how to add the jQuery

<?php
function MYMODULE_main() {
 
$page_contents  = "";
 
// ...code...
 
$page_contents .= drupal_get_form('MYMODULE_form');
 
// ...code...
 
return $page_contents;
}

function
MYMODULE_form() {
 
$form = array();
 
// ...code...
 
$js = "
    $(document).ready(function(){
      $('#"
. str_replace('_','-',__FUNCTION__) . "').submit(function(){
        if (confirm('Are you sure?')) {
          return true;
        } else {
          return false;
        }
      );
    });
  "
;
 
drupal_add_js($js, 'inline');
 
// ...code...
 
return $form;
}
?>

Eric.London's picture

Here's a code snippet that ensures the submitted title is unique across all nodes.

<?php
function MYMODULE_form_alter($form_id, $form) {
  if (
substr($form_id, -10)=='_node_form') {
   
// add custom form validation function
   
$form['#validate'] = array_merge(array('_MYMODULE_helper_validate' => array()), $form['#validate']);
  }
}

function
_MYMODULE_helper_validate($form_id, $form_values, $form) {
 
// ensure title is unique
 
if (strlen($form_values['title'])) {
   
// check for unique title
   
$sql = "select distinct title from {node} where 1=1 ";
   
// don't want to include current title
   
if ($form_values['nid']) $sql .= "and nid != '" . db_escape_string($form_values['nid']) . "'";
       
   
$resource = db_query($sql);
   
$titles = array();
    while(
$result = db_fetch_array($resource)) $titles[] = $result['title'];
   
    if (
in_array($form_values['title'],$titles))
     
form_set_error('title', $form['title']['#title'] . ' has already been submitted.');
  }
}
?>

Eric.London's picture

Normally when there is a form input error, Drupal highlights the form input by adding a red border and changing the text color. Unfortunately, nothing happens for checkboxes and radio buttons. Here's a little jQuery to add the error class to the label directly above a set of checkboxes or radios when an error occurs.

<?php
$('form#node-form div.form-item').each(function(){
  var
result = 0;
 
result += $(this).find('div.form-radios input.form-radio.error').length;
 
result += $(this).find('div.form-checkboxes input.form-checkbox.error').length;
  if (
result) $(this).find('label:first').removeClass('error').addClass('error');
});
?>

Syndicate content