0

私は顧客の 1 人のために簡単なゲストブック モジュールを開発しています。スパム対策として、一連の簡単な質問を使用することにしました。このために、配列からランダムな質問を選択し、この質問の ID (配列要素 ID) をフォームに設定して、送信ハンドラーで回答を確認できるようにする必要があります。問題は、送信ハンドラーが評価される前にフォームが再生成されるため、ランダム値が変更されることです。

まもなく:$form_state['values']['queston_id']送信ハンドラー関数でフォームにある他の値を取得しています。それはなぜですか、どうすればこれを変更できますか?

どうもありがとう!

これは私のモジュールです:

function gb_menu() {
  $items = array();

  $items['gb'] = array(
    'title' => t('Guestbook'),
    'description' => t('Guestbook page'),
    'page callback' => 'gb_guestbook',
    //'page arguments' => array('gb_guestbook'),
    'access arguments' => array('view guestbook'),
  );

  return $items;
}

function gb_guestbook() {
  dpm('generating page');
  $page = NULL;

  $page .= drupal_render(drupal_get_form('gb_guestbook_form'));

  $page .= 'list of guestbook messages here';
  return $page;
}

function gb_guestbook_form($form, &$form_state) {

  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Name'),
    '#description' => t('Please, enter your name.'),
  );

  $form['message'] = array(
    '#type' => 'textarea',
    '#cols' => 5,
    '#title' => t('Message'),
    '#description' => t('Please, enter your message.'),
  );

  $questions = gb_get_question();
  $question_id = rand(0, count($questions)-1);
  $question = $questions[$question_id];

  $form['question_id'] = array(
    '#type' => 'hidden',
    '#value' => $question_id,
  );

  $form['spam'] = array(
    '#title' => $question['question'],
    '#description' => t('Please, answer the simple question so we know that you are a human.'),
    '#type' => 'textfield',
  );

  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Submit'),
  );

  return $form;
}

function gb_guestbook_form_submit($form, &$form_state) {
  // spam check
  $values = $form_state['values'];

  $questions = gb_get_question();
  $answers = $questions[$values['question_id']]['answers'];
  if (!in_array(strtolower($values['spam']), $answers)) {
    drupal_set_message(t('You did not reply the answer correctly. Are you sure it was not typo?'), 'error');
  }
  else {
    drupal_set_message(t('Thanks for the contribution!'), 'status'); 
    // processing input
  }
}

function gb_get_question() {
return array(
  array (
    'question' => t('What is the capital of Slovakia?'),
    'answers' => array('bratislava'),
  ),
  array (
    'question' => t('What is the name of this band?'),
    'answers'=> array('divozel'),
  ),
  array (
    'question' => t('What is the biggest town in east part of Slovakia?'),
    'answers' => array('košice','kosice'),
  ),
);
}
4

5 に答える 5

1

おそらく、代わりに gb_guestbook_form_VALIDATE でこのチェックを行う必要があります。

于 2013-02-25T10:01:38.597 に答える
0

ランダムな質問ジェネレーターを、質問がフォームでまだ定義されているかどうかを確認する条件ステートメントでラップします。

$question_id = NULL;
$questions = gb_get_question();
if (!isset($form['question_id'])) {
  $question_id = rand(0, count($questions)-1);
}
else {
    $question_id = $form['question_id']['#value'];
}
$question = $questions[$question_id];
于 2013-02-26T01:41:17.437 に答える
0

これは検証フックで行います。関数 gb_guestbook_form_submit の別の問題

質問は取得できますが、回答配列は取得できず、それらを比較しようとしています。これが問題の原因である可能性もあります。質問をキャプチャしますが、回答はキャプチャせず、回答の空の配列と比較します。

于 2013-02-25T21:30:41.183 に答える
0

私の他の答えがうまくいかない理由はわかりませんが、別のアプローチがあります。アイデアは、質問 ID を $form_state['storage'] に保存することです。

まず、フォーム宣言を修正して、参照として $form_state を渡します。

function gb_guestbook_form($form, &$form_state) {

$form_state['storage'] 配列で質問 ID を確認し、まだ設定していない場合は、フォーム値 question_id を設定する前に設定します。

$questions = gb_get_question();
if (!isset($form_state['storage']['question_id'])) {
  $form_state['storage']['question_id'] = array_rand($questions);
}

$form['question_id'] = array(
  '#type' => 'hidden',
  '#value' => $form_state['storage']['question_id'],
);
于 2013-02-26T15:49:11.840 に答える
0

あなたの問題(および私のもの)はここで説明されています: http://www.sparklepod.com/myblog/drupal-form-same-form-for-build-and-validation/

要するに。送信時に、検証コードが実行される前にフォームが再構築されます。私にとって、ブログのソリューションは私の Drupal 7 サイトでは機能しません。

私が行ったことは、フォーラムビルドに次の行を追加することです:

$form_state['cache'] = true;

これにより、フォームがキャッシュされ、on _submit が false に設定されます。

于 2014-09-12T09:43:28.807 に答える