Projet

Général

Profil

Paste
Télécharger (4,35 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / hidden_captcha / hidden_captcha.module @ 211d6cee

1
<?php
2

    
3
/**
4
 * @file
5
 * All code for the Hidden CAPTCHA module, except installation-related code.
6
 */
7

    
8
/**
9
 * Implements hook_help().
10
 */
11
function hidden_captcha_help($path, $arg) {
12
  switch ($path) {
13
    case 'admin/config/people/captcha/hidden_captcha':
14
      return '<p>' . t('This CAPTCHA presents a text field that we expect no one to fill. The text field can be given any name and will be hidden from view using CSS.') . '</p>';
15
  }
16
}
17

    
18
/**
19
 * Implements hook_menu().
20
 */
21
function hidden_captcha_menu() {
22
  $items = array();
23
  $items['admin/config/people/captcha/hidden_captcha'] = array(
24
    'title' => 'Hidden CAPTCHA',
25
    'page callback' => 'drupal_get_form',
26
    'page arguments' => array('hidden_captcha_settings_form'),
27
    'access arguments' => array('administer CAPTCHA settings'),
28
    'type' => MENU_LOCAL_TASK,
29
    'weight' => -10,
30
  );
31
  return $items;
32
}
33

    
34
/**
35
 * Function for the hidden captcha settings form.
36
 */
37
function hidden_captcha_settings_form() {
38
  $form = array();
39
  $form['hidden_captcha_label'] = array(
40
    '#type' => 'textfield',
41
    '#title' => t('Hidden text field label'),
42
    '#description' => t("This is the hidden captcha form field's label, describing the expected input.<br /><strong>It is highly recommended to change it!</strong><br />The label should be as \"machine-readable\" as possible, encouraging spambots to fill in the field. An example might be a simple math challenge.<br />The label will only be visible to people who do not have CSS enabled and to robots."),
43
    '#default_value' => variable_get('hidden_captcha_label', 'Website URL'),
44
  );
45
  return system_settings_form($form);
46
}
47

    
48
/**
49
 * Implements hook_captcha().
50
 */
51
function hidden_captcha_captcha($op, $captcha_type = '') {
52
  switch ($op) {
53
    case 'list':
54
      return array('Hidden CAPTCHA');
55

    
56
    case 'generate':
57
      if ($captcha_type == 'Hidden CAPTCHA') {
58
        $captcha = array();
59
        $captcha['solution'] = '';
60

    
61
        // Ensure this captcha is cacheable.
62
        // @see https://www.drupal.org/project/captcha/issues/2449209
63
        $captcha['cacheable'] = TRUE;
64

    
65
        // The CAPTCHA solution provided by hook_captcha() is updated in the
66
        // 'captcha_session' table on pre-render phase of element process.
67
        // @see captcha_pre_render_process()
68
        // @see _captcha_update_captcha_session()
69
        // However, if the cache is enabled, solution would be empty for the
70
        // first attempt of the cached form. For the next attempt, there will
71
        // not be any 'sid' in form_state
72
        // (i.e. $form_state['captcha_info']['captcha_sid'] = null).
73
        // So a new solution would get generated at captcha_element_process().
74
        // The default 'captcha_validate' function,
75
        // captcha_validate_strict_equality(), would fail in this case.
76
        // @see captcha_validate()
77
        // Adding custom validation function to check solution is always empty.
78
        $captcha['captcha_validate'] = 'hidden_captcha_captcha_validate';
79

    
80
        $captcha['form']['captcha_response'] = array(
81
          '#type' => 'textfield',
82
          '#title' => variable_get('hidden_captcha_label', 'Website URL'),
83
          '#required' => FALSE,
84
          '#attributes' => array('tabindex' => '-1'),
85
        );
86
        return $captcha;
87
      }
88
      break;
89
  }
90
}
91

    
92
/**
93
 * CAPTCHA validation callback; checks that the response is empty.
94
 */
95
function hidden_captcha_captcha_validate($solution, $captcha_response, $element, $form_state) {
96
  return $captcha_response === '';
97
}
98

    
99
/**
100
 * Implements hook_theme().
101
 */
102
function hidden_captcha_theme() {
103
  return array(
104
    'captcha' => array(
105
      'arguments' => array('element' => NULL),
106
      'function' => 'theme_hidden_captcha_captcha',
107
    ),
108
  );
109
}
110

    
111
/**
112
 * Implements theme_hook().
113
 */
114
function theme_hidden_captcha_captcha($element) {
115
  $captcha = theme_captcha($element);
116
  if (strncmp($element["element"]["#captcha_type"], "hidden_captcha/", 15) == 0) {
117
    // Generate a random class name.
118
    $chars = "abcdfghjkmnpqrstvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
119
    $class = "";
120
    for ($i = 0; $i < 64; ++$i) {
121
      $class .= substr($chars, rand(0, strlen($chars) - 1), 1);
122
    }
123
    // Hide the random class via CSS.
124
    // @todo Move the random class to an external file.
125
    drupal_add_css(".$class{width:0;height:0;overflow:hidden;}", "inline");
126
    // HTML for the captcha.
127
    $captcha = "<div class=\"$class\">" . $captcha . "</div>";
128
  }
129
  return $captcha;
130
}