'. t('Adds a Captcha to various forms to help prevent spam submissions.') .'

'; // TODO: More help needed here. break; } return $output; } /** * Implementation of hook_menu(). */ function captcha_menu($may_cache) { $items = array(); if ($may_cache) { $items[] = array( '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'), 'access' => user_access('administer site configuration'), ); } return $items; } /** * Helper function generates admin settings page. */ function captcha_admin_settings() { // This is where you can add more captcha points. $captcha_points = array( 'comment_form' => t('Comment form'), 'user_login' => t('User login form'), 'user_login_block' => t('User login form block'), 'user_edit' => t('User edit form'), 'user_register' => t('User registration form'), 'user_pass' => t('User forgot password form'), 'contact_mail_user' => t('User contact form'), 'contact_mail_page' => t('Sitewide contact form'), 'node_form' => t('Create a node'), ); $roles = user_roles(); foreach($roles as $role) { $varsuffix = strtr($role, ' ', '_') .'_captcha'; $form[$varsuffix] = array( '#type' => 'fieldset', '#title' => t('Captcha points for the role @role', array('@role' => $role)), '#collapsible' => TRUE, '#collapsed' => TRUE, ); foreach($captcha_points as $captcha_point => $captcha_point_description) { $varname = $captcha_point .'_'. $varsuffix; $form[$varsuffix][$varname] = array( '#type' => 'checkbox', '#title' => $captcha_point_description, '#default_value' => variable_get($varname, NULL), ); } } // preprocess array into a map foreach(module_implements('captchachallenge') as $module) { $captchamodules[$module] = $module; } $form['captcha_type'] = array( '#type' => 'select', '#title' => t('Type of captcha to use'), '#default_value' => variable_get('captcha_type', 'captcha'), '#options' => $captchamodules, '#description' => t('Select what kind of challenge you want to pose to the user.'), ); $form['captcha_description'] = array( '#type' => 'textfield', '#title' => t('Additional response description text'), '#default_value' => variable_get('captcha_description', ''), '#description' => t('This text will be added below the captcha response field.'), ); $form['captcha_override_module_description'] = array( '#type' => 'checkbox', '#title' => t("Override module's form item description"), '#default_value' => variable_get('captcha_override_module_description', 0), '#description' => t("Override the captcha module's form item description to the one set above."), ); return system_settings_form($form); } /** * Implementation of hook_form_alter(). */ function captcha_form_alter($form_id, &$form) { global $user; $captcha_type = variable_get("captcha_type", NULL); if (!$captcha_type) { return; } $flag = TRUE; $trigger = NULL; foreach($user->roles as $role) { $candidate_trigger = $form_id .'_'. strtr($role, ' ', '_') .'_captcha'; if (variable_get($candidate_trigger, NULL)) { $trigger = $candidate_trigger; } else { $flag = FALSE; break; } } if ($flag && isset($trigger)) { $function = $captcha_type. '_captcha'; if (function_exists($function)) { $form['#pre_render'][] = 'captcha_pre_render'; $form['#submit'] = array('captcha_submit' => array()) + $form['#submit']; $captcha_id = md5(mt_rand()); list($captcha_word, $challenge, $error_message) = $function($form); $form['captcha'] = array( '#tree' => TRUE, '#error_message' => $error_message, '#validate' => array('captcha_validate' => array()), 'challenge' => $challenge, ); $form['captcha']['captcha_id'] = array( '#type' => 'hidden', '#default_value' => $captcha_id, ); $_SESSION['form'][$captcha_id] = array('timestamp' => time()); $form['captcha']['response'] = array( '#type' => 'hidden', '#default_value' => drupal_get_token($captcha_word), ); if(variable_get('captcha_override_module_description', 0)) { unset($form['captcha_response']['#description']); } if (strlen(variable_get('captcha_description', '')) > 0) { if (isset($form['captcha_response']['#description'])) { $form['captcha_response']['#description'] .= ' '. variable_get('captcha_description', ''); } else { $form['captcha_response']['#description'] = variable_get('captcha_description', ''); } } } } } /** Captcha pre render callback. * * If the user has not yet submitted anything or submitted the good answer, * this is not going to fire. However, on each page load we calculate a new * captcha and we need to use that. */ function captcha_pre_render($form_id, &$form) { if (isset($form['captcha']['challenge']) && form_get_error($form['captcha']['challenge'])) { $form['captcha']['response']['#value'] = $form['captcha']['response']['#default_value']; $form['captcha']['challenge']['#value'] = ''; $form['captcha']['captcha_id']['#value'] = $form['captcha']['captcha_id']['#default_value']; } } /** * Validate captcha. */ function captcha_validate($element) { $captcha_id = $element['captcha_id']['#value']; if (drupal_get_token($element['challenge']['#value']) != $element['response']['#value'] || !isset($_SESSION['form'][$captcha_id]) || isset($_SESSION['form'][$captcha_id]['submitted'])) { form_set_error('captcha][challenge', $element['#error_message']); } } function captcha_submit($form_id, $form_values) { $_SESSION['form'][$form_values['captcha']['captcha_id']]['submitted'] = 1; } /** * Default implementation of hook_captcha */ function captcha_captcha() { $x = mt_rand(1,10); $y = mt_rand(1,10); $captcha_word = (string)($x + $y); $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.'), '#weight' => 0, '#required' => TRUE, ); return array($captcha_word, $challenge, t('The answer you entered to the math problem is incorrect.')); }