Birden Çok Form Gönderimini Önleme (Sunucu tarafı)


9

Bir kullanıcı Form API tarafından oluşturulan herhangi bir formu birden çok kez (hızlı tıklama birden çok istek sonuçlanan) gönderebilirsiniz bir sorunla karşılaşıyorum.

Düğmeyi devre dışı bırakma temel istemci tarafı (javascript) çözümü koydum, ancak bu durumu önlemek için en iyi yaklaşımın sunucu tarafında ne olduğunu merak ediyorum.

Bunu gerçekleştirmek için Drupal'ın form jetonunu kullanmanın önerilen bir yolu var mı? Özellikle küresel bir form çözümü (yani, hook_form_alter () kullanarak her forma özel bir doğrulayıcı eklemek).

Benim yaklaşımım şimdiye kadar böyle bir şey oldu:

function mymodule_form_alter(&$form, &$form_state, $form_id) {
  $form['#validate'][] = 'mymodule_form_validate';
}

function mymodule_form_validate(&$form, &$form_state){
  //initialize form array
  if (!isset($_SESSION['submitted_forms'])){
    $_SESSION['submitted_forms'] = array();
  }

  $form_token = $form_state['values']['form_token'];
  if ( isset($_SESSION['submitted_forms'][$form_token]) && $_SESSION['submitted_forms'][$form_token] = TRUE ){
    form_set_error('name]', 'This form has already been submitted');
  }
  else{
    $_SESSION['submitted_forms'][$form_token] = TRUE;
  }
}

Form_token forma özgü değil sorun yaşıyorum - ne olursa olsun aynı kalır gibi görünüyor. Muhtemelen simgenin api formunun büyük şemasında ne olduğunu yanlış anlıyorum.

Herhangi bir fikir takdir!


Takip olarak, jeton yerine $ form_state ['form_build_id'] kullanmaya başladım. Aynı form derleme kimliğini iki kez gönderirsem, formun yeniden oluşturulup yine de işlendiği yol boyunca bir yerde.
PrairieHippo

Yanıtlar:


8

Ben aynı sorunu vardı ve kullanarak düzeltmek için yönetilen Kilitleme mekanizmaları Drupal dan

Doğrulama fonksiyonunda kullandım:

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."));
  }
}

Ve gönder işlevinde kilidi serbest bıraktım:

function mymodule_custom_form_submit($form, &$form_state){
  // submit code
  lock_release('your_custom_lock_name');
}

1

Burada modül ağırlığını göz önünde bulundurmalısınız:

  1. Modül ağırlığı negatif maksimum_değeri (-2000 olabilir) olması gereken bir modül (let_module) burada aşağıdaki kod ile hook_form_alter () uygulamalıdır.
   function first_module_form_alter(&$form, &$form_state, $form_id)
    {
      $form['#validate'][] = 'mymodule_form_validate';
    }
function mymodule_form_validate(&$form, &$form_state){
  //a($form_state);
  //initialize form array
  if (!isset($_SESSION['submitted_forms'])){
    $_SESSION['submitted_forms'] = array();
  }

  $form_token = $form_state['values']['form_id'];
  if ( isset($_SESSION['submitted_forms'][$form_token]) && $_SESSION['submitted_forms'][$form_token] = TRUE ){
    form_set_error('name]', 'This form has already been submitted');
  }
  else{
    $_SESSION['submitted_forms'][$form_token] = TRUE;
  }
}
  1. Ağırlığı pozitif yüksek değere sahip olan ikinci_modül.Ayrıca, bir modüle geri gönderme isteği ekleyerek oturumun ayarını kaldırmalısınız.

işlev second_module_form_alter (& $ form, & $ form_state, $ form_id) {$ form ['# send'] [] = 'mymodule_form_submit'; }

function mymodule_form_submit(&$form, &$form_state){

  $form_token = $form_state['values']['form_id'];
  unset($_SESSION['submitted_forms'][$form_token]);

}

1

Bu işlevi tüm formlarda ve kodlamadan daha fazla kontrol istiyorsanız, Submit Button düğmesini gizle modülüne bakın.

Özellikleri:

  1. Gönder düğmesine tıklandıktan sonra gizleyin veya devre dışı bırakın
  2. Beklerken bir mesaj ve / veya resim görüntüleme

5
Submt Button modülünü gizle bir sunucu tarafı çözümü değildir. Modülün açıklamasından: "Javascript devre dışı bırakılmış tarayıcılar için bu modülün hiçbir etkisi olmayacaktır." drupal.org/project/hide_submit
Blake Frederick

0
$form['submit'] = array(
  '#type' => 'submit',
  '#value' => t('Save'),
  '#attributes' => array(
    'onclick' => 'javascript:var s=this;setTimeout(function(){s.value="Saving...";s.disabled=true;},1);',
  ),
);

umarım bu yardımcı olur ..

veya gönderme düğmesinin birden çok tıklanmasını önleme ve drupal'ın bir modülü var Gönderme düğmesini gizle

Bazı kullanıcılar, gönderilerinin kaydedilmesini beklerken yanlışlıkla gönder düğmesini bir kereden fazla tıklar. Bazı durumlarda, bu durum yinelenen kayıtlara veya yinelenen e-ticaret siparişlerine neden olabilir.


-1

Bu daha önce de benim sorunumdu. Benim çözümüm JS üzerinden düğmeyi devre dışı bırakmak.

.module:

/**
 * Implementation of hook_init().
 */
function myModule_init(){
if (arg(0) == 'node' && (arg(2) == 'edit' || arg(1) == 'add')) {
    //hide btn when clicked on article nodes
    drupal_add_js(drupal_get_path('module', myModule') . '/js/disable-submit.js');
}

JS:

Drupal.behaviors.module_disable_submit = function (context) {

/* 
 * Disable keypress on form fields.
 * Prevent browser to reload when pressing enter in input fields 
 */


$('.buttons input:submit').click(function() {
  $('.buttons input:submit').hide();
  $('#node-form .buttons').prepend('<input type="submit" style="margin:1px 0; box-shadow:0 1px 1px #DDDDDD; border-radius:3px 3px 3px 3px; background:url(/sites/all/themes/rubik/images/bleeds.png) repeat-x scroll 0 -41px #F4F4F4; border-color:#DDDDDD #DDDDDD #CCCCCC; border-style:solid; border-width:1px; color:#B8A98F; cursor:default; font-weight:normal; padding:2px 10px; text-align:center;" value="Saving..." name="op" onclick="return false;" />');
  if ('.buttons input:submit') {
    $('.buttons input:submit').keypress(function() {
      $('.buttons input:submit').parents("form").submit();
      $('.buttons input:submit').hide();
    });
  }
});
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.