You are here

function image_captcha_captcha in CAPTCHA 8

Same name and namespace in other branches
  1. 5.3 image_captcha/image_captcha.module \image_captcha_captcha()
  2. 6.2 image_captcha/image_captcha.module \image_captcha_captcha()
  3. 6 image_captcha/image_captcha.module \image_captcha_captcha()
  4. 7 image_captcha/image_captcha.module \image_captcha_captcha()

Implements hook_captcha().

File

image_captcha/image_captcha.module, line 250
Implements image CAPTCHA for use with the CAPTCHA module.

Code

function image_captcha_captcha($op, $captcha_type = '', $captcha_sid = NULL) {
  $config = \Drupal::config('image_captcha.settings');
  switch ($op) {
    case 'list':

      // Only offer the image CAPTCHA if it is possible to generate an image
      // on this setup.
      if (!(_image_captcha_check_setup() & IMAGE_CAPTCHA_ERROR_NO_GDLIB)) {
        return [
          'Image',
        ];
      }
      else {
        return [];
      }
      break;
    case 'generate':
      if ($captcha_type == 'Image') {

        // In maintenance mode, the image CAPTCHA does not work because
        // the request for the image itself won't succeed (only ?q=user
        // is permitted for unauthenticated users). We fall back to the
        // Math CAPTCHA in that case.
        if (\Drupal::state()
          ->get('system.maintenance_mode') && \Drupal::currentUser()
          ->isAnonymous()) {
          return captcha_captcha('generate', 'Math');
        }

        // Generate a CAPTCHA code.
        $allowed_chars = _image_captcha_utf8_split($config
          ->get('image_captcha_image_allowed_chars'));
        $code_length = (int) $config
          ->get('image_captcha_code_length');
        $code = '';
        for ($i = 0; $i < $code_length; $i++) {
          $code .= $allowed_chars[array_rand($allowed_chars)];
        }

        // Build the result to return.
        $result = [];
        $result['solution'] = $code;

        // Generate image source URL (add timestamp to avoid problems with
        // client side caching: subsequent images of the same CAPTCHA session
        // have the same URL, but should display a different code).
        list($width, $height) = _image_captcha_image_size($code);
        $result['form']['captcha_image'] = [
          '#theme' => 'image',
          '#uri' => Url::fromRoute('image_captcha.generator', [
            'session_id' => $captcha_sid,
            'timestamp' => \Drupal::time()
              ->getRequestTime(),
          ])
            ->toString(),
          '#width' => $width,
          '#height' => $height,
          '#alt' => t('Image CAPTCHA'),
          '#title' => t('Image CAPTCHA'),
          '#weight' => -2,
        ];
        $result['form']['captcha_response'] = [
          '#type' => 'textfield',
          '#title' => t('What code is in the image?'),
          '#description' => t('Enter the characters shown in the image.'),
          '#weight' => 0,
          '#required' => TRUE,
          '#size' => 15,
          '#attributes' => [
            'autocomplete' => 'off',
          ],
          '#cache' => [
            'max-age' => 0,
          ],
        ];

        // Handle the case insensitive validation option combined with
        // ignoring spaces.
        switch (\Drupal::config('captcha.settings')
          ->get('default_validation')) {
          case CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE:
            $result['captcha_validate'] = 'captcha_validate_ignore_spaces';
            break;
          case CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE:
            $result['captcha_validate'] = 'captcha_validate_case_insensitive_ignore_spaces';
            break;
        }
        \Drupal::service('page_cache_kill_switch')
          ->trigger();
        return $result;
      }
      break;
  }
}