You are here

lost_character_captcha.module in CAPTCHA Pack 5

File

text_captcha/lost_character_captcha/lost_character_captcha.module
View source
<?php

require_once drupal_get_path('module', 'lost_character_captcha') . '/../text_captcha.inc';
define('LOST_CHARACTER_CAPTCHA_DEFAULT_WORD_POOL', 'information language interesting vocabulary communication computer security presentation infrastructure videotape yesterday xylophone workforce validation supervisor standalone multimedia grapefruit friendship aboriginal alphabetical agriculture atmosphere candidature catastrophe audiovisual fingerprint keyboard testimonial supervision supermarket temperature terminology telephonist ultraviolet scholarship spaceflight shoplifting punctuation screwdriver quarterback');
define('LOST_CHARACTER_CAPTCHA_HINTER', '_');

/**
 * Implementation of hook_help().
 */
function lost_character_captcha_help($section) {
  switch ($section) {
    case 'admin/user/captcha/lost_character_captcha':
      return '<p>' . t('The challenge in this CAPTCHA is to determine the lost character(s) of a given word.') . '</p>';
  }
}

/**
 * Implementation of hook_menu().
 */
function lost_character_captcha_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/user/captcha/lost_character_captcha',
      'title' => t('Lost characters'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'lost_character_captcha_settings_form',
      ),
      'type' => MENU_LOCAL_TASK,
    );
  }
  return $items;
}

/**
 * Function for the settings form
 */
function lost_character_captcha_settings_form() {
  $form = array();

  // form element for the number of characters to lose
  $form['lost_character_captcha_quantity'] = array(
    '#type' => 'select',
    '#title' => t('Number of characters to lose'),
    '#default_value' => variable_get('lost_character_captcha_quantity', 1),
    '#description' => t('Select how many characters should be lost in the CAPTCHA.'),
    '#options' => array(
      1 => 1,
      2 => 2,
      3 => 3,
    ),
  );

  // form element for hinting
  $form['lost_character_captcha_enable_hint'] = array(
    '#type' => 'checkbox',
    '#title' => t('Put "%hinter" where the characters are lost as a hint', array(
      '%hinter' => LOST_CHARACTER_CAPTCHA_HINTER,
    )),
    '#default_value' => variable_get('lost_character_captcha_enable_hint', TRUE),
    '#description' => t('Enable this option to make it easier to determine the lost characters.'),
  );

  // form elements for the word pool
  _text_captcha_word_pool_form_items($form, 'lost_character_captcha_word_pool', 'Word pool', 'Enter the words to use, separated with spaces. Make sure every word is unambiguously recognizable when characters are lost. Avoid for example verbs, adverbs, plural forms, too short words, names. Also make sure the words are well known to your intended public.', LOST_CHARACTER_CAPTCHA_DEFAULT_WORD_POOL);

  // add a pre_render callback
  $form['#pre_render'] = (array) $form['#pre_render'] + array(
    'lost_character_captcha_settings_form_pre_render',
  );

  // add buttons and return
  return system_settings_form($form);
}

/**
 * Pre_render function
 */
function lost_character_captcha_settings_form_pre_render() {

  // set a warning if the numbers to lose is to big and if hinting is off
  if (variable_get('lost_character_captcha_quantity', 1) > 2 && !variable_get('lost_character_captcha_enable_hint', TRUE)) {
    drupal_set_message(t('Losing more than two characters without indication where they are lost could be too hard for a human. Check your settings.'), 'warning');
  }
}

/**
 * Validation function for the settings form
 */
function lost_character_captcha_settings_form_validate($form_id, $form_values) {
  if ($form_id == 'lost_character_captcha_settings_form') {
    $lost_quantity = (int) $form_values['lost_character_captcha_quantity'];
    $hinting = (int) $form_values['lost_character_captcha_enable_hint'];
    $min_length = 3 + 2 * $lost_quantity + (1 - $hinting);

    // check the number of words in the pool
    _text_captcha_word_pool_validate('lost_character_captcha_word_pool', $form_values, 3, $min_length, 'The following words are too short (at least @minimum_length characters needed for the current settings of characters to lose and hinting): <div>@words</div>');
  }
}

/**
 * Implementation of hook_captcha().
 */
function lost_character_captcha_captcha($op, $captcha_type = '', $response = '') {
  switch ($op) {
    case 'list':
      return array(
        "Lost characters",
      );
    case 'generate':
      if ($captcha_type == "Lost characters") {

        // get the word pool
        $words = _text_captcha_word_pool_get_content('lost_character_captcha_word_pool', NULL, LOST_CHARACTER_CAPTCHA_DEFAULT_WORD_POOL, TRUE);

        // pick a random word
        $word = $words[array_rand($words)];

        // split in characters
        $characters = _text_captcha_utf8_split($word);

        // lose characters
        $lost = array();
        $lose_quantity = variable_get('lost_character_captcha_quantity', 1);
        for ($i = 0; $i < $lose_quantity; $i++) {

          // pick a random character
          $n = array_rand($characters);
          while ($characters[$n] == LOST_CHARACTER_CAPTCHA_HINTER) {
            $n = array_rand($characters);
          }

          // save it for building the solution
          $lost[] = $characters[$n];

          // and lose it in the given word
          if (variable_get('lost_character_captcha_enable_hint', TRUE)) {
            $characters[$n] = LOST_CHARACTER_CAPTCHA_HINTER;
          }
          else {
            unset($characters[$n]);
          }
        }

        // build the CAPTCHA
        sort($lost);
        $given_word = implode('', $characters);
        $solution = implode('', $lost);
        if ($lose_quantity == 1) {
          $title = t('Enter the missing character from the following word');
        }
        else {
          $title = t('Enter the @num missing characters from the following word', array(
            '@num' => $lose_quantity,
          ));
        }

        //
        $captcha = array();
        $captcha['solution'] = $solution;
        $captcha['form']['captcha_response'] = array(
          '#type' => 'textfield',
          '#title' => $title,
          '#field_prefix' => "{$given_word}: ",
          '#size' => 3,
          '#maxlength' => 3,
          '#required' => TRUE,
        );
        $captcha['preprocess'] = TRUE;
        return $captcha;
      }
      break;
    case 'preprocess':
      if ($captcha_type == "Lost characters") {

        // remove white spaces
        $parts = _text_captcha_whitespace_explode($response);
        $response = implode('', $parts);

        // split in utf8 characters, sort and rejoin
        $characters = _text_captcha_utf8_split($response);
        sort($characters);
        $response = implode('', $characters);
        return $response;
      }
      break;
  }
}

Functions

Namesort descending Description
lost_character_captcha_captcha Implementation of hook_captcha().
lost_character_captcha_help Implementation of hook_help().
lost_character_captcha_menu Implementation of hook_menu().
lost_character_captcha_settings_form Function for the settings form
lost_character_captcha_settings_form_pre_render Pre_render function
lost_character_captcha_settings_form_validate Validation function for the settings form

Constants