From 91fe06be0d59a5be8b055382873ee5b9a95de84c Mon Sep 17 00:00:00 2001 From: "stefanos.petrakis@gmail.com" Date: Thu, 8 Dec 2016 13:14:23 +0100 Subject: [PATCH] Patching for 2833965 --- .../dropzonejs_eb_widget.libraries.yml | 12 +++++ ...dropzonejs_eb_widget.form_submit_single.js | 19 +++++++ .../eb_widget/js/jquery.form-submit-single.js | 52 +++++++++++++++++++ .../Widget/DropzoneJsEbWidget.php | 40 ++++++++------ 4 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 modules/eb_widget/js/dropzonejs_eb_widget.form_submit_single.js create mode 100644 modules/eb_widget/js/jquery.form-submit-single.js diff --git a/modules/eb_widget/dropzonejs_eb_widget.libraries.yml b/modules/eb_widget/dropzonejs_eb_widget.libraries.yml index 6070223..212237c 100644 --- a/modules/eb_widget/dropzonejs_eb_widget.libraries.yml +++ b/modules/eb_widget/dropzonejs_eb_widget.libraries.yml @@ -10,3 +10,15 @@ ief_edit: js/dropzonejs_eb_widget.ief_edit.js: {} dependencies: - dropzonejs_eb_widget/common +jquery-form-submit-single: + version: VERSION + js: + js/jquery.form-submit-single.js: {} + dependencies: + - core/jquery +form_submit_single: + version: VERSION + js: + js/dropzonejs_eb_widget.form_submit_single.js: {} + dependencies: + - dropzonejs_eb_widget/jquery-form-submit-single \ No newline at end of file diff --git a/modules/eb_widget/js/dropzonejs_eb_widget.form_submit_single.js b/modules/eb_widget/js/dropzonejs_eb_widget.form_submit_single.js new file mode 100644 index 0000000..9d8cd45 --- /dev/null +++ b/modules/eb_widget/js/dropzonejs_eb_widget.form_submit_single.js @@ -0,0 +1,19 @@ +/** + * @file dropzonejs_eb_widget.form_submit_single.js + * + * Simple, easy solving out multiple form submission problem. + * We redirect all form submissions to the jquery.form-submit-single handler. + * This in turn will make sure that no multiple submissions of the same form + * will take place. + * N.B.: This can/should probably be placed in a different place. + */ +(function ($, Drupal, drupalSettings) { + "use strict"; + + Drupal.behaviors.dropzonejsFormSubmitSingle = { + attach: function(context) { + $('body').on('submit.formSubmitSingle', 'form:not([method~="GET"])', $.onFormSubmitSingle); + } + }; + +}(jQuery, Drupal, drupalSettings)); diff --git a/modules/eb_widget/js/jquery.form-submit-single.js b/modules/eb_widget/js/jquery.form-submit-single.js new file mode 100644 index 0000000..49607b6 --- /dev/null +++ b/modules/eb_widget/js/jquery.form-submit-single.js @@ -0,0 +1,52 @@ +/** + * jQuery Form Submit Single Plugin 1.0.0 + * https://github.com/sun/jquery-form-submit-single + * + * @version 1.0.0 + * @copyright 2013 Daniel F. Kudwien + * @license MIT http://sun.mit-license.org/2013 + */ + +;(function (factory) { + "use strict"; + if (typeof exports === 'object') { + factory(require('jquery')); + } + else if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } + else { + factory(jQuery); + } +}(function ($) { +"use strict"; + +$.extend({ + /** + * Prevents consecutive form submissions of identical form values. + * + * Repetitive form submissions that would submit the identical form values are + * prevented, unless the form values are different to the previously submitted + * values. + * + * @param event + * The submit event that triggered a form submit. + */ + onFormSubmitSingle: function (event) { + if (event.isDefaultPrevented()) { + return; + } + var $form = $(event.currentTarget); + var currentValues = $form.serialize(); + var previousValues = $form.attr('data-form-submit-single-last'); + if (previousValues === currentValues) { + event.preventDefault(); + } + else { + $form.attr('data-form-submit-single-last', currentValues); + } + } + +}); + +})); diff --git a/modules/eb_widget/src/Plugin/EntityBrowser/Widget/DropzoneJsEbWidget.php b/modules/eb_widget/src/Plugin/EntityBrowser/Widget/DropzoneJsEbWidget.php index 026922a..fe26bba 100644 --- a/modules/eb_widget/src/Plugin/EntityBrowser/Widget/DropzoneJsEbWidget.php +++ b/modules/eb_widget/src/Plugin/EntityBrowser/Widget/DropzoneJsEbWidget.php @@ -132,6 +132,9 @@ public function getForm(array &$original_form, FormStateInterface $form_state, a $form['#attached']['library'][] = 'dropzonejs_eb_widget/common'; $original_form['#attributes']['class'][] = 'dropzonejs-disable-submit'; + // Attach one-time-submit logic. + $form['#attached']['library'][] = 'dropzonejs_eb_widget/form_submit_single'; + return $form; } @@ -205,24 +208,31 @@ public function validate(array &$form, FormStateInterface $form_state) { // right extensions. Although DropzoneJS should not even upload those files // it's still better not to rely only on client side validation. if ($trigger['#type'] == 'submit' && $trigger['#name'] == 'op') { - $upload_location = $this->getUploadLocation(); - if (!file_prepare_directory($upload_location, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) { - $form_state->setError($form['widget']['upload'], t('Files could not be uploaded because the destination directory %destination is not configured correctly.', ['%destination' => $this->getConfiguration()['settings']['upload_location']])); - } + $lock = \Drupal::lock(); + if ($lock->acquire('dropzone_file_upload_lock_' . $form_state->getValue('form_token'))) { + $upload_location = $this->getUploadLocation(); + if (!file_prepare_directory($upload_location, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) { + $form_state->setError($form['widget']['upload'], t('Files could not be uploaded because the destination directory %destination is not configured correctly.', ['%destination' => $this->getConfiguration()['settings']['upload_location']])); + } - $files = $this->getFiles($form, $form_state); - if (in_array(FALSE, $files)) { - // @todo Output the actual errors from validateFile. - $form_state->setError($form['widget']['upload'], t('Some files that you are trying to upload did not pass validation. Requirements are: max file %size, allowed extensions are %extensions', ['%size' => $this->getConfiguration()['settings']['max_filesize'], '%extensions' => $this->getConfiguration()['settings']['extensions']])); - } + $files = $this->getFiles($form, $form_state); + if (in_array(FALSE, $files)) { + // @todo Output the actual errors from validateFile. + $form_state->setError($form['widget']['upload'], t('Some files that you are trying to upload did not pass validation. Requirements are: max file %size, allowed extensions are %extensions', ['%size' => $this->getConfiguration()['settings']['max_filesize'], '%extensions' => $this->getConfiguration()['settings']['extensions']])); + } - if (empty($files)) { - $form_state->setError($form['widget']['upload'], t('At least one valid file should be uploaded.')); - } + if (empty($files)) { + $form_state->setError($form['widget']['upload'], t('At least one valid file should be uploaded.')); + } - // If there weren't any errors set, run the normal validators. - if (empty($form_state->getErrors())) { - parent::validate($form, $form_state); + // If there weren't any errors set, run the normal validators. + if (empty($form_state->getErrors())) { + parent::validate($form, $form_state); + } + $lock->release('dropzone_file_upload_lock_' . $form_state->getValue('form_token')); + } + else { + \Drupal::logger('DropzoneJsEbWidget')->notice('Form with token @form_token already submitted.', ['@form_token' => $form_state->getValue('form_token')]); } } }