All pastes #617339 Raw Edit

Untitled

public text v1 · immutable
·published 2007-07-13 05:05 UTC
rendered paste body
<?php
// $Id: captcha.module,v 1.30 2007/01/13 17:48:05 wundo Exp $

/**
 * Implementation of hook_help().
 */
function captcha_help($section = 'admin/help#captcha') {
  $output = '';

  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 $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.'));
}