Drupal形式的随机隐藏值

时间:2013-02-23 14:08:20

标签: drupal-7

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

5 个答案:

答案 0 :(得分:1)

您应该在gb_guestbook_form_VALIDATE中执行此检查。

答案 1 :(得分:0)

我会在验证钩子中执行此操作。函数gb_guestbook_form_submit

中的另一个问题

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

答案 2 :(得分: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];

答案 3 :(得分: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'],
);

答案 4 :(得分:0)

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

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

我所做的是在论坛版本中添加以下内容:

$form_state['cache'] = true;

这将缓存表单,而on _submit我会将其设置为false。