? .bzr
? captcha-rewrite.patch
? captcha.tar.gz
? captcha.zip
Index: captcha.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.info,v
retrieving revision 1.3
diff -u -b -B -u -p -r1.3 captcha.info
--- captcha.info	18 Jun 2007 22:53:32 -0000	1.3
+++ captcha.info	21 Jun 2007 06:54:35 -0000
@@ -1,4 +1,5 @@
-; $Id: captcha.info,v 1.3 2007/06/18 22:53:32 dww Exp $
+; $Id$
 name = Captcha
 description = "Implements a captcha to registration, comment, contact and node entry forms."
-package = SPAM Control
+package = Spam control
+version = "$Name$"
Index: captcha.install
===================================================================
RCS file: captcha.install
diff -N captcha.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ captcha.install	21 Jun 2007 06:54:35 -0000
@@ -0,0 +1,56 @@
+<?php
+// $Id$
+
+/**
+ * Create tables on install
+ */
+function captcha_install() {
+  switch ($GLOBALS['db_type']) {
+    case 'mysql':
+    case 'mysqli':
+      db_query("CREATE TABLE {captcha_points} (
+        form_id varchar(128) NOT NULL,
+        description varchar(256) NOT NULL,
+        captcha_type varchar(64),
+        visible tinyint NOT NULL default '0',
+        PRIMARY KEY (form_id)
+        ) /*!40100 DEFAULT CHARACTER SET utf8 */;"
+      );
+      $succes = TRUE;
+      break;
+    case 'pgsql':
+      db_query("CREATE TABLE {captcha_points} (
+        form_id varchar(128) NOT NULL,
+        description varchar(256) NOT NULL,
+        captcha_type varchar(64),
+        visible smallint NOT NULL default '0',
+        PRIMARY KEY (form_id)
+        );"
+      );
+      $succes = TRUE;
+      break;
+    default:
+      drupal_set_message(t('Unsupported database.'), 'error');
+      $succes = FALSE;
+  }
+  if ($succes) {
+    // insert some defaults
+    $forms = array(
+      'comment_form' => t('Comment form'),
+      'contact_mail_user' => t('User contact form'),
+      'contact_mail_page' => t('Sitewide contact form'),
+    );
+    foreach($forms as $form_id=>$description) {
+      db_query("INSERT INTO {captcha_points} (form_id, description, captcha_type, visible) VALUES ('%s', '%s', '%s', %d)", $form_id, $description, 'NULL', 1);
+    }
+  } else {
+    drupal_set_message(t('The installation of the captcha module was unsuccessful'), 'error');
+  }
+}
+
+/**
+ * Remove tables on uninstall.
+ */
+function captcha_uninstall() {
+  db_query("DROP TABLE {captcha_points}");
+}
Index: captcha.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/captcha/captcha.module,v
retrieving revision 1.41
diff -u -b -B -u -p -r1.41 captcha.module
--- captcha.module	19 Jun 2007 01:00:22 -0000	1.41
+++ captcha.module	21 Jun 2007 06:54:35 -0000
@@ -1,17 +1,19 @@
 <?php
-// $Id: captcha.module,v 1.41 2007/06/19 01:00:22 wundo Exp $
+// $Id$
+
+
+define('CAPTCHA_DESCRIPTION', 'This question is used to make sure you are a human user and to prevent spam submissions.');
 
 /**
  * Implementation of hook_help(). 
  */
 function captcha_help($section = 'admin/help#captcha') {
-  $output = '';
-
+  // TODO: More help needed here.
   switch ($section) {
   case 'admin/help#captcha':
-    $output .= '<p>'. t('Adds a Captcha to various forms to help prevent spam submissions.') .'</p>';
-    // TODO: More help needed here.
-    break;
+      return '<p>' . t('Adds a Captcha to various forms to help prevent spam submissions.') .'</p>';
+    case 'admin/settings/captcha':
+      return '<p>' . t('Captchas are meant to counter spam submissions. Captchas are extra fields on a form presented to the anonymous visitors. These fields present a challenge, which should be easy for a human to solve, but hard enough to keep automated scripts and bots out.') . '</p>';
   }
   return $output;
 }
@@ -26,136 +28,223 @@ function captcha_menu($may_cache) {
       'path' => 'admin/settings/captcha',
       'title' => t('Captcha'),
       'description' => t('Administer how and where Captchas are used.'),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => array('captcha_admin_settings'),
+      'callback' => 'captcha_admin',
       'access' => user_access('administer site configuration'),
       'type' => MENU_NORMAL_ITEM,
     );
-    $items[] = array(
-      'path' => 'admin/settings/captcha/captcha',
-      'title' => t('Captcha'),
-      'description' => t('Administer how and where Captchas are used.'),
-      'access' => user_access('administer site configuration'),
-      'type' => MENU_DEFAULT_LOCAL_TASK,
-    );
-    $items[] = array(
-      'path' => 'admin/settings/captcha/points',
-      'title' => t('Captcha Points'),
-      'description' => t('Administer in what forms Captchas are applied.'),
-      'callback' => 'drupal_get_form',
-      'callback arguments' => array('captcha_admin_points'),
-      'access' => user_access('administer site configuration'),
-      'type' => MENU_LOCAL_TASK,
-    );
   }
   return $items;
 }
 
-
+/**
+ * Return an array with the available captcha types
+ */
 function _captcha_supported_challenges_types(){
   static $captcha_challenges = NULL;
-  
+  // if cached: return cache
   if($captcha_challenges != NULL) {
   	return $captcha_challenges; 
   }	
-  
   $captcha_challenges['none'] = 'none';
-  
   foreach(module_implements('captcha') as $module) {
     $result = call_user_func_array($module .'_captcha', 'list');
     if (isset($result)) { //&& is_array($result)) {
       foreach($result as $challenge) {
-      	$captcha_challenges[$module.'/'.$challenge] = $module.'/'.$challenge;
+        $captcha_challenges["$module::$challenge"] = "$module::$challenge";
       }
     }
   }
-  
-  
   return $captcha_challenges;
 }
 
-function _captcha_points() {
-  $captcha_points = variable_get('captcha_points',NULL);
-  if($captcha_points == NULL) {
-    $captcha_points = array(
-      'comment_form' => t('Comment form'),
-      'contact_mail_user' => t('User contact form'),
-      'contact_mail_page' => t('Sitewide contact form'),
-    );
-    variable_set('captcha_points',serialize($captcha_points));
+/**
+ * General Captcha settings handler
+ */
+
+function captcha_admin($form_id='', $op='') {
+  // if $form_id and action $op given: do the action
+  if ($form_id) {
+    switch ($op) {
+      case 'disable':
+        db_query("UPDATE {captcha_points} SET visible=0 WHERE form_id='%s'", $form_id);
+        drupal_set_message(t('Disabled captcha point %form_id.', array('%form_id'=>$form_id)));
+        drupal_goto('admin/settings/captcha');
+        break;
+      case 'hide':
+        db_query("UPDATE {captcha_points} SET visible=0 WHERE form_id='%s'", $form_id);
+        drupal_goto('admin/settings/captcha');
+        break;
+      case 'edit':
+        return drupal_get_form('captcha_admin_captcha_point_edit', $form_id);
+        break;
+      case 'enable':
+        $present = db_result(db_query("SELECT 1 FROM {captcha_points} WHERE form_id='%s'", $form_id));
+        if ($present) {
+          db_query("UPDATE {captcha_points} SET visible=1 WHERE form_id='%s'", $form_id);
   }
   else {
-    $captcha_points = unserialize($captcha_points);
+          db_query("INSERT INTO {captcha_points} (form_id, description, captcha_type, visible) VALUES ('%s', '', NULL, 1)", $form_id);
   }
-  return $captcha_points;
+        drupal_goto("admin/settings/captcha/$form_id/edit");
+        break;
+    }
+  }
+  // no action: generate general captcha settings form
+  return drupal_get_form('captcha_admin_settings');
 }
 
-function captcha_admin_points() {
-  $captcha_points = _captcha_points();
-  $output = '';
   
-  if(function_exists('form_store_get_all')) {
-    $form = array('#description' => t('Enable/Disable captcha points.'));
-    $known_forms = form_store_get_all();
-    $form['captcha_points']['#tree'] = true;
-    foreach($known_forms as $item) {
-      $form['captcha_points'][$item->form_id] = array(
+function captcha_admin_settings() {
+  // captcha adminstration mode
+  $form['captcha_administration_mode'] = array(
         '#type' => 'checkbox',
-        '#title' => $item->form_id.' - '.$item->description,
-        '#default_value' => isset($captcha_points[$item->form_id]),
+    '#title' => t('Add captcha adminstration links to forms.'),
+    '#default_value' => variable_get('captcha_administration_mode', FALSE),
+    '#description' => t('This option is very helpfull to enable/disable captchas on forms. When enabled, users with the "administer site configuration" permission will see captcha adminstration links on all forms. Do not forget to disable this option when you finished configuring your captcha points.'),
+  );
+  // set captcha type for captcha points
+  $form["captcha_types"] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Select captcha types'),
+    '#description' => t('Select what kind of captcha challenge you want for each captcha point. You can edit the description of each form with the "edit" links. With the "hide" links you can hide a form in this list. To "unhide" you should use the "captcha administration links" on the forms in question (see previous option).'),
+    '#tree' => TRUE,
+    '#collapsible' => TRUE,
+    '#collapsed' => FALSE,
+    '#theme' => 'captcha_admin_settings_captcha_points',
+  );
+  $captcha_challenges = _captcha_supported_challenges_types();
+  $result = db_query("SELECT * FROM {captcha_points} WHERE visible=1 ORDER BY form_id");
+  while ($captcha_point = db_fetch_object($result)) {
+    $form['captcha_types'][$captcha_point->form_id]['form_id'] = array(
+      '#value' => $captcha_point->form_id,
+    );
+    $form['captcha_types'][$captcha_point->form_id]['captcha_type'] = array(
+      '#type' => 'select',
+      '#default_value' => $captcha_point->captcha_type,
+      '#options' => $captcha_challenges,
+    );
+    $form['captcha_types'][$captcha_point->form_id]['description'] = array(
+      '#value' => $captcha_point->description,
+    );
+    $form['captcha_types'][$captcha_point->form_id]['operations'] = array(
+      '#value' => implode(", ", array(
+        l(t('edit'), "admin/settings/captcha/{$captcha_point->form_id}/edit"),
+        l(t('hide'), "admin/settings/captcha/{$captcha_point->form_id}/hide"),
+      ))
       );
     }
-    $output = system_settings_form($form);
-  }
-  else {
-    drupal_set_message(t('Unable to find Form Store module, Captcha needs it to allow you to change the capcha points.'),'error');
-  }
+  // additional captcha description
+  $form["captcha_description"] = array(
+    '#type' => 'textfield',
+    '#title' => t('Captcha description'),
+    '#description' => t('This description should explain to the anonymous visitor why the captcha needs to be solved.'),
+    '#default_value' => variable_get('captcha_description', t(CAPTCHA_DESCRIPTION)),
+  );
+  // captcha persistens
+  $form["captcha_persist"] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Persistent captchas'),
+    '#description' => t('If checked, a captcha will be presented to the user each time (s)he wants to submit a form. If not checked, once the user successfully solved a captcha for a form, (s)he will not be presented a captcha for subsequent instances of that form.'),
+    '#default_value' => variable_get('captcha_persist', FALSE),
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Submit'),
+  );
+  return $form;
+}
 
+/**
+ * Theme function for a table of captcha points widgets
+ */
+function theme_captcha_admin_settings_captcha_points($form) {
+  foreach (element_children($form) as $key) {
+    $row = array();
+    $row[] = drupal_render($form[$key]['form_id']);
+    $row[] = drupal_render($form[$key]['description']);
+    $row[] = drupal_render($form[$key]['captcha_type']);
+    $row[] = drupal_render($form[$key]['operations']);
+    $rows[] = $row;
+  }
+  $header = array('form_id', t('Description'), t('Captcha type'), t('Operations'));
+  $output = theme('table', $header, $rows);
   return $output;
 }
 
-function captcha_admin_points_submit($form_id, $form_values) {
-  if($form_id == 'captcha_admin_points') {
-    $known_forms = form_store_get_all();
-    $captcha_points = array();
-    foreach($form_values['captcha_points'] as $key => $selected) {
-      if($selected)
-        $captcha_points[$key] = $known_forms[$key]->description;
+/**
+ * Submission function for captcha_admin_settings form
+ */
+function captcha_admin_settings_submit($form_id, $form_values) {
+  if ($form_id == 'captcha_admin_settings') {
+    variable_set('captcha_administration_mode', $form_values['captcha_administration_mode']);
+    foreach($form_values['captcha_types'] as $form_id => $data) {
+      $captcha_type = $data['captcha_type'];
+      if ($captcha_type == 'none') {
+        db_query("UPDATE {captcha_points} SET captcha_type=NULL WHERE form_id='%s'", $form_id);
+      }
+      else {
+        db_query("UPDATE {captcha_points} SET captcha_type='%s' WHERE form_id='%s'", $captcha_type, $form_id);
     }
-    variable_set('captcha_points',serialize($captcha_points));
-    drupal_set_message(t('Your captcha points were sucessful updated, please configure the challenge options in the other tab.'),'status');
+    }
+    variable_set('captcha_description', $form_values['captcha_description']);
+    variable_set('captcha_persist', $form_values['captcha_persist']);
+    drupal_set_message(t('Your captcha settings were saved.'), 'status');
   }
 }
 
 /**
- * Helper function generates admin settings page.
+ * form generator for captcha point edit form
  */
-function captcha_admin_settings() {
-  $captcha_points = _captcha_points();
-  $roles = variable_get('captcha_roles',user_roles());
+function captcha_admin_captcha_point_edit($form_id) {
   $captcha_challenges = _captcha_supported_challenges_types();
-  
-  foreach($roles as $role) {
-    $varsuffix = strtr($role, ' ', '_') .'_captcha';
-    $form[$varsuffix] = array(
-      '#type' => 'fieldset',
-      '#title' => t('Captcha points for the role @role', array('@role' => $role)),
-      '#description' => t('Select what kind of challenge you want to pose to the user in each captcha point.'),
-      '#collapsible' => TRUE,
-      '#collapsed' => TRUE,
+  $captcha_point = db_fetch_object(db_query("SELECT * FROM {captcha_points} WHERE form_id='%s'", $form_id));
+  drupal_set_title(t('Form with form_id "@form_id"', array('@form_id' => $form_id)));
+  if ($captcha_point) {
+    $form = array();
+    $form['_form_id'] = array(
+      '#type' => 'hidden',
+      '#value' => $form_id,
+    );
+    $form['description'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Description'),
+      '#description' => t('Describe the selected form.'),
+      '#default_value' => $captcha_point->description,
     );
-    foreach($captcha_points as $captcha_point => $captcha_point_description) {
-      $varname = $captcha_point .'_'. $varsuffix;
-      $form[$varsuffix][$varname] = array(
+    $form['captcha_type'] = array(
         '#type' => 'select',
-        '#title' => t('@point', array('@point' => $captcha_point_description)),
-        '#default_value' => variable_get($varname, 'captcha/Math'),
+      '#title' => t('Captcha type'),
+      '#default_value' => $captcha_point->captcha_type,
         '#options' => $captcha_challenges,
       );
+    $form['visible'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Visible'),
+      '#description' => t('If enabled, this Form ID will be listed on the general Captcha settings page'),
+      '#default_value' => $captcha_point->visible,
+    );
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => t('Submit'),
+    );
+    return $form;
     }
+}
+/**
+ * Submission function for captcha point edit form
+ */
+function captcha_admin_captcha_point_edit_submit($form_id, $form_values) {
+  if ($form_id == 'captcha_admin_captcha_point_edit') {
+    db_query("DELETE FROM {captcha_points} WHERE form_id='%s'", $form_values['_form_id']);
+    if ($form_values['captcha_type'] == 'none'){
+      db_query("INSERT INTO {captcha_points} (form_id, description, captcha_type, visible) VALUES ('%s', '%s', NULL, %d)", $form_values['_form_id'], $form_values['description'], $form_values['visible']);
   }
-  
-  return system_settings_form($form);
+    else {
+      db_query("INSERT INTO {captcha_points} (form_id, description, captcha_type, visible) VALUES ('%s', '%s', '%s', %d)", $form_values['_form_id'], $form_values['description'], $form_values['captcha_type'], $form_values['visible']);
+    }
+  }
+  drupal_set_message(t('Captcha point "@form_id" updated.', array('@form_id'=>$form_values['_form_id'])));
+  drupal_goto("admin/settings/captcha");
 }
 
 /**
@@ -165,81 +254,114 @@ function captcha_form_alter($form_id, &$
   global $captcha;
   global $user;
 
-  $seed = $form['form_token']['#default_value'];
-  if($_SESSION['captcha'][$seed]['success'] === TRUE)
-    return;
-
-  foreach($user->roles as $role) {	
-  	$candidate_trigger = $form_id .'_'. strtr($role, ' ', '_') .'_captcha';
-  	$captcha_type = variable_get($candidate_trigger,NULL);
-
-  	if($captcha_type != NULL) {
-  	  //Found one valid captcha challenge for this point.
-  	  break;
+  if (user_access('administer site configuration') && variable_get('captcha_administration_mode', FALSE)) {
+    // For administrators: show captcha info and offer link to configure it
+    $captcha_type = db_result(db_query("SELECT captcha_type FROM {captcha_points} WHERE visible=1 AND form_id='%s'", $form_id));
+    if ($captcha_type) {
+      $form['captcha'] = array(
+        '#type' => 'item',
+        '#title' => t('Captcha administration'),
+        '#description' => t('The captcha challenge %captcha_type is enabled at this point for anonymous users: !edit, !disable.', array(
+          '%captcha_type' => $captcha_type,
+          '!edit' => l(t('edit captcha type'), "admin/settings/captcha/$form_id/edit"),
+          '!disable' => l(t('remove captcha from this form'), "admin/settings/captcha/$form_id/disable"))),
+      );
   	}
+    else {
+      $form['captcha'] = array(
+        '#type' => 'item',
+        '#title' => t('Captcha administration'),
+        '#description' => t('Click !here to enable a captcha challenge at this point for anonymous users.', array(
+          '!here' => l(t('here'), "admin/settings/captcha/$form_id/enable"))),
+      );
   }
-
-  if($captcha_type == 'none') {
-    //One of the user roles doesn't have captcha challenge for this point, aborting.
+  }
+  elseif ($user->uid) {
+    // captcha is only for anonymous users, so return
     return;
   }
-  elseif($captcha_type == NULL) {
-  	//captcha_type null;
+  else {
+    $seed = $form['form_token']['#default_value'];
+    // do not present captcha if not captcha-persistent and user has already solved a captcha for this form
+    if(!variable_get('captcha_persist', FALSE) && ($_SESSION['captcha'][$seed]['success'] === TRUE)) {
   	return;
   }
-     
-  $challenge = explode('/',$captcha_type);
-   
-  $result = module_invoke($challenge[0], 'captcha', 'generate', $challenge[1]);
-  
-  $form = array_merge($form,$result['form']);
-  
-  if(!isset($form['#validate']))
+    // get captcha type and return if no captcha set
+    $captcha_type = db_result(db_query("SELECT captcha_type FROM {captcha_points} WHERE form_id='%s'", $form_id));
+    if (!$captcha_type) {
+      return;
+    }
+    // get captcha module
+    list($captcha_module, $captcha_type) = explode('::', $captcha_type);
+    $result = module_invoke($captcha_module, 'captcha', 'generate', $captcha_type);
+    $captcha_description = variable_get('captcha_description', t(CAPTCHA_DESCRIPTION));
+    if ($captcha_description) {
+      $form['captcha'] = array(
+        '#type' => 'fieldset',
+        '#title' => t('Captcha'),
+        '#description' => $captcha_description,
+      );
+    }
+    else {
+      $form['captcha'] = array();
+    }
+    $form['captcha'] = array_merge($form['captcha'], $result['form']);
+    // handle validate and prerender attributes
+    if(!isset($form['#validate'])) {
     $form['#validate'] = array();
+    }
   $form['#validate'] += array('captcha_validate' => array());
   $form['#pre_render'] = array('captcha_prerender');
-
+    // save captcha data in session
   $_SESSION['captcha'][$seed]['success'] = FALSE;
   $_SESSION['captcha'][$seed]['form_id'] = $form_id;
   $_SESSION['captcha'][$seed]['form'] = $result['form'];
-  $_SESSION['captcha'][$seed]['new_value'] = $result['value'];
+    $_SESSION['captcha'][$seed]['new_captcha_solution'] = $result['value'];
   $_SESSION['captcha'][$seed]['preprocess'] = isset($result['preprocess'])? $result['preprocess'] : FALSE;
-  $_SESSION['captcha'][$seed]['module'] = $challenge[0];
-  $_SESSION['captcha'][$seed]['type'] = $challenge[1];
+    $_SESSION['captcha'][$seed]['module'] = $captcha_module;
+    $_SESSION['captcha'][$seed]['type'] = $captcha_type;
+  }
+  //handle position of captcha: just above (last) submit button
+  foreach(element_children($form) as $key) {
+    if ($form[$key]['#type'] == 'submit') {
+      $submit_key = $key;
+    }
+  }
+  if (!$form[$submit_key]['#weight']) {
+    $form[$submit_key]['#weight'] = 30;
+  }
+  $form['captcha']['#weight'] = $form[$submit_key]['#weight'] - 1;
 }
 
-function captcha_validate($form_id, $form_item) {
-  $seed = $form_item['form_token'];
-
+/**
+ * Implementation of form #validate.
+ */
+function captcha_validate($form_id, $form_values) {
+  $seed = $form_values['form_token'];
+  // get answer and preprocess if needed
+  $captcha_answer = $form_values['captcha_challenge'];
   if($_SESSION['captcha'][$seed]['preprocess']) {
-    $value = module_invoke($_SESSION['captcha'][$seed]['module'],'captcha','process',$_SESSION['captcha'][$seed]['type'],$form_item['captcha_challenge']);
+    $captcha_answer = module_invoke($_SESSION['captcha'][$seed]['module'], 'captcha', 'process', $_SESSION['captcha'][$seed]['type'], $captcha_answer);
   }
-  else {
-  	$value = $form_item['captcha_challenge'];
-  } 
-
-  if($value == $_SESSION['captcha'][$seed]['value']) {
+  // check answer
+  if($captcha_answer == $_SESSION['captcha'][$seed]['captcha_solution']) {
   	$_SESSION['captcha'][$seed]['success'] = TRUE;
     return;
   }
-  form_set_error('captcha_response', t('The answer you entered to the captcha challenge is incorrect.'));  
+  else {
+    form_set_error('captcha_challenge', t('The answer you entered to the captcha challenge is incorrect.'));
+  }
 }
 
 /**
  * Implementation of form #pre_render.
- *
  */
 function captcha_prerender($form_id, $form) {
-  $seed = $form['#post']['form_token'];
-  $_SESSION['captcha'][$seed]['value'] = $_SESSION['captcha'][$seed]['new_value'];
-  if($_SESSION['captcha'][$seed]['success']) {
-    unset($form['captcha_challenge']);
-    unset($_SESSION['captcha'][$seed]);
-  }
+  $seed = $form['form_token']['#default_value'];
+  // store the captcha solution in the session array
+  $_SESSION['captcha'][$seed]['captcha_solution'] = $_SESSION['captcha'][$seed]['new_captcha_solution'];
 }
 
-
-
 /**
  * Default implementation of hook_captcha
  */
@@ -256,12 +378,11 @@ function captcha_captcha() {
         $answer = mt_rand(1, 20);
         $x = mt_rand(1, $answer);
         $y = $answer - $x;
- 
-        $result['value'] = (string)($answer);
+        $result['value'] = "$answer";
         $result['form']['captcha_challenge'] = array (
           '#type' => 'textfield',
-          '#title' => t('Math Question: What is %problem?', array('%problem' => $x .' + '. $y)),
-          '#description' => t('Please solve the math problem above and type in the result. e.g. for 1+1, type 2.'),
+          '#title' => t('Math Question: What is %problem?', array('%problem' => "$x + $y")),
+          '#description' => t('Solve this simple math problem and enter the result. E.g. for 1+3, type 4.'),
           '#weight' => 0,
           '#required' => TRUE,
         );
