Welcome, Guest
Username: Password: Remember me

TOPIC: Preventing Duplicate Form Submissions

Preventing Duplicate Form Submissions 13 Jul 2015 16:44 #13334

  • rnevins
  • rnevins's Avatar
  • Offline
  • Junior Member
  • Posts: 24
  • Thank you received: 6
  • Karma: 1
I have been having some issues with duplicate database records being created because sometimes my users will be impatient and click the "Save & Close" multiple times before the processing of the first click has completed. This is easy to duplicate. I did some research and found there are several techniques employed to prevent duplicates, such as:
1. After click disable the Button via Javascript
2. After click disable the Button via jQuery
3. Use form tokens to skip the processing of a submission if the form was already processed.

After experimenting a bit, I have implemented in test mode the 3rd technique, following the approach found here: spotlesswebdesign.com/blog.php?id=11

In my case, I put the following in the view.html.php displayXXX function: (no need to do the session_start()
if (!isset($_SESSION)) {
$_SESSION = array();
}
$_SESSION[] = uniqid('', true);
Then I put this in the form tmplate:
<input type="hidden" name="page_instance_id" value="<?php echo end($_SESSION); ?>" />

And finally, in the controller save() function, I modified the first part of it as follows:

CkJSession::checkToken() or CkJSession::checkToken('get') or jexit(JText::_('JINVALID_TOKEN'));


//Check the ACLs
$model = $this->getModel();
$item = $model->getItem();

$app = JFactory::getApplication();
$data = $app->input->post->get('jform', array(), 'array');
//rbn - prevent duplicate form submissions
$page_id_index = array_search($_POST, $_SESSION);
if ($page_id_index !== false) {

unset($_SESSION[$page_id_index]);



$result = false;
if ($model->canEdit($item, true))
{
$result = parent::save();
//Get the model through postSaveHook()
if ($this->model)
{
$model = $this->model;
$item = $model->getItem();
}
}
else
JError::raiseWarning( 403, JText::sprintf('ACL_UNAUTORIZED_TASK', JText::_('VOLUNTEER_JTOOLBAR_SAVE')) );

$this->_result = $result;

}


This seems to work but I would appreciate input on the following:

1. Is there any easier/simpler approach (must modify/fork three files for this solution).
2. Do you see where this could cause any unintended problems or interactions elsewhere?

Thanks
The administrator has disabled public write access.
Time to create page: 0.107 seconds

Get Started