You are here

lost_character_captcha.module in CAPTCHA Pack 8

Contains general functionality of the module.

File

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

/**
 * @file
 * Contains general functionality of the module.
 */
use Drupal\Core\Form\FormStateInterface;
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', '_');

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

/**
 * Implements hook_form_alter().
 */
function lost_character_captcha_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  if ($form_id == 'lost_character_captcha_settings') {
    $config = Drupal::config('lost_character_captcha.settings');

    // Set a warning if the numbers to lose is to big and if hinting is off.
    if ($config
      ->get('lost_character_captcha_quantity') > 2 && !$config
      ->get('lost_character_captcha_enable_hint')) {
      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');
    }
  }
}

/**
 * Implements hook_captcha().
 */
function lost_character_captcha_captcha($op, $captcha_type = '') {
  $config = \Drupal::config('lost_character_captcha.settings');
  switch ($op) {
    case 'list':
      return [
        "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 = [];
        $lose_quantity = $config
          ->get('lost_character_captcha_quantity');
        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 ($config
            ->get('lost_character_captcha_enable_hint')) {
            $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', [
            '@num' => $lose_quantity,
          ]);
        }
        $captcha = [];
        $captcha['solution'] = $solution;
        $captcha['form']['captcha_response'] = [
          '#type' => 'textfield',
          '#title' => $title,
          '#field_prefix' => "{$given_word}: ",
          '#size' => 3,
          '#maxlength' => 3,
          '#required' => TRUE,
          '#process' => [
            'lost_character_process',
          ],
          '#cache' => [
            'max-age' => 0,
          ],
        ];
        \Drupal::service('page_cache_kill_switch')
          ->trigger();
        return $captcha;
      }
  }
}

/**
 * Process the response before validation.
 */
function lost_character_process($element, $edit) {
  $response = $element['#value'];

  // 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);

  // Put back in element and return.
  $element['#value'] = $response;
  return $element;
}

Functions

Namesort descending Description
lost_character_captcha_captcha Implements hook_captcha().
lost_character_captcha_form_alter Implements hook_form_alter().
lost_character_captcha_help Implements hook_help().
lost_character_process Process the response before validation.

Constants