0

我正在为我的一个客户开发简单的留言簿模块,为了防止垃圾邮件,我决定使用一系列简单的问题。为此,我必须从数组中选择随机问题并在表单中设置此问题的 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

我会在验证挂钩中执行此操作。函数 gb_guestbook_form_submit 中的另一个问题

你得到了问题,但没有得到答案数组,然后你试图比较它们。这也可能是您的问题的根源,您捕获了问题而不是答案,然后与空的答案数组进行比较。

于 2013-02-25T21:30:41.183 回答
0

您的问题(和我的)在这里描述: http ://www.sparklepod.com/myblog/drupal-form-same-form-for-build-and-validation/

简而言之。提交时,表单在运行验证代码之前重建。对我来说,博客中的解决方案不适用于我的 Drupal 7 站点。

我所做的是将以下行添加到论坛构建中:

$form_state['cache'] = true;

这将缓存表单,并且在 _submit 上我会将其设置为 false。

于 2014-09-12T09:43:28.807 回答
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

将您的随机问题生成器包装在条件语句中,以检查您的问题是否已在表单中定义。

$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 回答