You are here

recaptcha.module in reCAPTCHA 6.2

File

recaptcha.module
View source
<?php

/**
 * @file
 * Verifies if user is a human without necessity to solve a CAPTCHA.
 */
require_once dirname(__FILE__) . '/recaptcha-php/src/ReCaptcha/ReCaptcha.php';
require_once dirname(__FILE__) . '/recaptcha-php/src/ReCaptcha/RequestMethod.php';
require_once dirname(__FILE__) . '/recaptcha-php/src/ReCaptcha/RequestParameters.php';
require_once dirname(__FILE__) . '/recaptcha-php/src/ReCaptcha/Response.php';
require_once dirname(__FILE__) . '/src/ReCaptcha/RequestMethod/Drupal6Post.php';

/**
 * Implementation of hook_help().
 */
function recaptcha_help($path, $arg) {
  switch ($path) {
    case 'admin/user/captcha/recaptcha':
      return t('Google <a href="@url">reCAPTCHA</a> is a free service to protect your website from spam and abuse. reCAPTCHA uses an advanced risk analysis engine and adaptive CAPTCHAs to keep automated software from engaging in abusive activities on your site. It does this while letting your valid users pass through with ease.', array(
        '@url' => 'https://www.google.com/recaptcha',
      ));
  }
}

/**
 * Implementation of hook_theme().
 */
function recaptcha_theme() {
  return array(
    'recaptcha_widget_noscript' => array(
      'arguments' => array(
        'widget' => NULL,
      ),
      'template' => 'recaptcha-widget-noscript',
    ),
  );
}

/**
 * Implementation of hook_menu().
 */
function recaptcha_menu() {
  $items['admin/user/captcha/recaptcha'] = array(
    'title' => 'reCAPTCHA',
    'description' => 'Administer the Google No CAPTCHA reCAPTCHA web service.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'recaptcha_admin_settings',
    ),
    'access arguments' => array(
      'administer recaptcha',
    ),
    'type' => MENU_LOCAL_TASK,
    'file' => 'recaptcha.admin.inc',
    'weight' => 1,
  );
  return $items;
}

/**
 * Implementation of hook_perm().
 */
function recaptcha_perm() {
  return array(
    'administer recaptcha',
  );
}

/**
 * Implementation of hook_captcha().
 */
function recaptcha_captcha($op, $captcha_type = '') {
  global $language;
  switch ($op) {
    case 'list':
      return array(
        'reCAPTCHA',
      );
    case 'generate':
      $captcha = array();
      if ($captcha_type == 'reCAPTCHA') {
        $recaptcha_site_key = variable_get('recaptcha_site_key', '');
        $recaptcha_secret_key = variable_get('recaptcha_secret_key', '');
        if (!empty($recaptcha_site_key) && !empty($recaptcha_secret_key)) {

          // Build the reCAPTCHA captcha form if site_key and secret_key are
          // configured. Captcha requires TRUE to be returned in solution.
          $captcha['solution'] = TRUE;
          $captcha['captcha_validate'] = 'recaptcha_captcha_validation';
          $captcha['form']['captcha_response'] = array(
            '#type' => 'hidden',
            '#value' => 'Google no captcha',
          );
          $noscript = '';
          if (variable_get('recaptcha_noscript', 0)) {
            $variables = array(
              'sitekey' => $recaptcha_site_key,
              'language' => $language->language,
            );
            $noscript = theme('recaptcha_widget_noscript', $variables);
          }
          $attributes = array(
            'class' => 'g-recaptcha',
            'data-sitekey' => $recaptcha_site_key,
            'data-theme' => variable_get('recaptcha_theme', 'light'),
            'data-type' => variable_get('recaptcha_type', 'image'),
            'data-size' => variable_get('recaptcha_size', ''),
            'data-tabindex' => variable_get('recaptcha_tabindex', 0),
          );

          // Filter out empty tabindex/size.
          $attributes = array_filter($attributes);
          $captcha['form']['recaptcha_widget'] = array(
            '#type' => 'item',
            '#value' => '<div' . drupal_attributes($attributes) . '></div>' . $noscript,
          );

          // D6 does not support "async" and "external" in drupal_add_js().
          drupal_set_html_head('<script type="text/javascript" src="' . url('https://www.google.com/recaptcha/api.js', array(
            'query' => array(
              'hl' => $language->language,
            ),
            'absolute' => TRUE,
          )) . '" async="async" defer="defer"></script>');
        }
        else {

          // Fallback to Math captcha as reCAPTCHA is not configured.
          $captcha = captcha_captcha('generate', 'Math');
        }
      }
      return $captcha;
  }
}

/**
 * CAPTCHA Callback; Validates the reCAPTCHA code.
 */
function recaptcha_captcha_validation($solution, $response, $element, $form_state) {
  $recaptcha_secret_key = variable_get('recaptcha_secret_key', '');
  if (empty($_POST['g-recaptcha-response']) || empty($recaptcha_secret_key)) {
    return FALSE;
  }

  // Use drupal_http_request() to circumvent all issues with the Google library.
  $recaptcha = new \ReCaptcha\ReCaptcha($recaptcha_secret_key, new \ReCaptcha\RequestMethod\Drupal6Post());
  $resp = $recaptcha
    ->verify($_POST['g-recaptcha-response'], ip_address());
  if ($resp
    ->isSuccess()) {

    // Verified!
    return TRUE;
  }
  else {

    // Error code reference, https://developers.google.com/recaptcha/docs/verify
    $error_codes = array(
      'missing-input-secret' => t('The secret parameter is missing.'),
      'invalid-input-secret' => t('The secret parameter is invalid or malformed.'),
      'missing-input-response' => t('The response parameter is missing.'),
      'invalid-input-response' => t('The response parameter is invalid or malformed.'),
      'invalid-json' => t('The json response is invalid or malformed.'),
      'unknown' => t('Unknown error.'),
    );
    foreach ($resp
      ->getErrorCodes() as $code) {
      if (!isset($error_codes[$code])) {
        $code = 'unknown';
      }
      watchdog('reCAPTCHA', '@error', array(
        '@error' => $error_codes[$code],
      ), WATCHDOG_ERROR);
    }
  }
  return FALSE;
}

/**
 * Process variables for recaptcha-widget-noscript.tpl.php.
 *
 * @see recaptcha-widget-noscript.tpl.php
 */
function template_preprocess_recaptcha_widget_noscript(&$variables) {
  $variables['sitekey'] = check_plain($variables['widget']['sitekey']);
  $variables['language'] = check_plain($variables['widget']['language']);
  $variables['url'] = check_url(url('https://www.google.com/recaptcha/api/fallback', array(
    'query' => array(
      'k' => $variables['widget']['sitekey'],
      'hl' => $variables['widget']['language'],
    ),
    'absolute' => TRUE,
  )));
}

Functions

Namesort descending Description
recaptcha_captcha Implementation of hook_captcha().
recaptcha_captcha_validation CAPTCHA Callback; Validates the reCAPTCHA code.
recaptcha_help Implementation of hook_help().
recaptcha_menu Implementation of hook_menu().
recaptcha_perm Implementation of hook_perm().
recaptcha_theme Implementation of hook_theme().
template_preprocess_recaptcha_widget_noscript Process variables for recaptcha-widget-noscript.tpl.php.