Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drupal 7 how to prevent multiple form submissions (server side)

Tags:

drupal-7

Here is the working module code I am testing with:

/**
 * @file myform.module
 */

 /**
 * Implements hook_menu().
 */
 function myform_menu() {
   $items['myform'] = array(
     'title' => 'myform',
     'page callback' => 'drupal_get_form',
     'page arguments' => array('myform'),
     'access callback' => true,
     'type' => MENU_NORMAL_ITEM
   );
   return $items;
 }

 /**
 * Form
 */
 function myform() {
   $form['Value'] = array(
     '#title' => t('Value'),
     '#type' => 'textfield',
     '#description' => t('You may not enter the same value twice. (unless you hit enter really fast).'),
     '#required' => true,
   );
   $form['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Submit')
   );
   return $form;
 }

 /**
 * Validate
 */
 function myform_validate($form, &$form_state) {
   if (isset($form_state['values']['Value']) && trim($form_state['values']['Value'])!=''){
     // prevent duplicates
     db_set_active('test');
     $r = db_query("SELECT id FROM test WHERE value = '".$form_state['values']['Value']."'");
     $n = $r->rowCount();
     if ($n) {
       form_set_error('Value', t('This value has already been submitted.'));
     }
     db_set_active();
   }
 }

 /**
 * Submit
 */
 function myform_submit($form, &$form_state) {

   for ($i=0; $i<=10000000; $i++) {
     // do nothing
   }

   db_set_active('test');
   db_insert('test')->fields(array('value'=>$form_state['values']['Value']))->execute();
   db_set_active();
 }

The validation hook prevents duplicate values from being inserted, unless I hit the enter key or submit button really fast in which case the same value is inserted into the database multiple times.

How do I prevent duplicate values from being inserted?

like image 247
ooXei1sh Avatar asked Sep 06 '25 18:09

ooXei1sh


2 Answers

If you mean users being accidentally clicking the submit button more than once, then you should look into Hide submit button module. You can define it as dependency in your module's INFO file.

like image 100
osman Avatar answered Sep 11 '25 03:09

osman


I had the exact same problem and managed to fix it using the Locking mechanisms from Drupal

In the validate function I used:

function mymodule_custom_form_validate($form, &$form_state){
  if (lock_acquire('your_custom_lock_name')) {
    // long operations here
  } else {
    form_set_error("", t("You submitted this form already."));
  }
}

And in the submit function I released the lock:

function mymodule_custom_form_submit($form, &$form_state){
  // submit code
  lock_release('your_custom_lock_name');
}
like image 42
Marius Ilie Avatar answered Sep 11 '25 04:09

Marius Ilie