source: sipes/modules_contrib/captcha/image_captcha/image_captcha.module @ 92213c1

stableversion-3.0
Last change on this file since 92213c1 was 177a560, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se agrego el directorio de modulos contribuidos de drupal

  • Propiedad mode establecida a 100755
File size: 8.4 KB
Línea 
1<?php
2
3/**
4 * @file
5 * Implementation of image CAPTCHA for use with the CAPTCHA module
6 */
7
8// TODO: add test for fallback to simple math challenge in maintenance mode.
9
10define('IMAGE_CAPTCHA_ALLOWED_CHARACTERS', 'aAbBCdEeFfGHhijKLMmNPQRrSTtWXYZ23456789');
11
12// Setup status flags.
13define('IMAGE_CAPTCHA_ERROR_NO_GDLIB', 1);
14define('IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT', 2);
15define('IMAGE_CAPTCHA_ERROR_TTF_FILE_READ_PROBLEM', 4);
16
17define('IMAGE_CAPTCHA_FILE_FORMAT_JPG', 1);
18define('IMAGE_CAPTCHA_FILE_FORMAT_PNG', 2);
19define('IMAGE_CAPTCHA_FILE_FORMAT_TRANSPARENT_PNG', 3);
20
21
22/**
23 * Implementation of hook_help().
24 */
25function image_captcha_help($path, $arg) {
26  switch ($path) {
27    case 'admin/user/captcha/image_captcha':
28      $output = '<p>'. t('The image CAPTCHA is a popular challenge where a random textual code is obfuscated in an image. The image is generated on the fly for each request, which is rather CPU intensive for the server. Be careful with the size and computation related settings.') .'</p>';
29      return $output;
30  }
31}
32
33/**
34 * Implementation of hook_menu().
35 */
36function image_captcha_menu() {
37  $items = array();
38  // add an administration tab for image_captcha
39  $items['admin/user/captcha/image_captcha'] = array(
40    'title' => 'Image CAPTCHA',
41    'file' => 'image_captcha.admin.inc',
42    'page callback' => 'drupal_get_form',
43    'page arguments' => array('image_captcha_settings_form'),
44    'access arguments' => array('administer CAPTCHA settings'),
45    'type' => MENU_LOCAL_TASK,
46  );
47  // Menu path for generating font example.
48  $items['admin/user/captcha/image_captcha/font_preview'] = array(
49    'title' => 'Font example',
50    'file' => 'image_captcha.admin.inc',
51    'page callback' => 'image_captcha_font_preview',
52    'access arguments' => array('administer CAPTCHA settings'),
53    'type' => MENU_CALLBACK,
54  );
55  // callback for generating an image
56  $items['image_captcha'] = array(
57    'file' => 'image_captcha.user.inc',
58    'page callback' => 'image_captcha_image',
59    'access callback' => TRUE,
60    'type' => MENU_CALLBACK,
61  );
62  return $items;
63}
64
65/**
66 * Helper function for getting the fonts to use in the image CAPTCHA.
67 *
68 * @return a list of font paths.
69 */
70function _image_captcha_get_enabled_fonts() {
71  if (IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT & _image_captcha_check_setup(FALSE)) {
72    return array('BUILTIN');
73  }
74  else {
75    $default = array(
76      drupal_get_path('module', 'image_captcha') .'/fonts/Tesox/tesox.ttf',
77      drupal_get_path('module', 'image_captcha') .'/fonts/Tuffy/Tuffy.ttf',
78    );
79    return variable_get('image_captcha_fonts', $default);
80  }
81}
82
83/**
84 * Helper function for checking if the specified fonts are available.
85 *
86 * @param $fonts paths of fonts to check.
87 * @return list($readable_fonts, $problem_fonts)
88 */
89function _image_captcha_check_fonts($fonts) {
90  $readable_fonts = array();
91  $problem_fonts = array();
92  foreach ($fonts as $font) {
93    if ($font != 'BUILTIN' && (!is_file($font) || !is_readable($font))) {
94      $problem_fonts[] = $font;
95    }
96    else {
97      $readable_fonts[] = $font;
98    }
99  }
100  return array($readable_fonts, $problem_fonts);
101}
102
103/**
104 * Helper function for splitting an utf8 string correctly in characters.
105 * Assumes the given utf8 string is well formed.
106 * See http://en.wikipedia.org/wiki/Utf8 for more info
107 */
108function _image_captcha_utf8_split($str) {
109  $characters = array();
110  $len = strlen($str);
111  for ($i=0; $i < $len; ) {
112    $chr = ord($str[$i]);
113    if (($chr & 0x80) == 0x00) { // one byte character (0zzzzzzz)
114      $width = 1;
115    }
116    else {
117      if (($chr & 0xE0) == 0xC0) { // two byte character (first byte: 110yyyyy)
118        $width = 2;
119      }
120      elseif (($chr & 0xF0) == 0xE0) { // three byte character (first byte: 1110xxxx)
121        $width = 3;
122      }
123      elseif (($chr & 0xF8) == 0xF0) { // four byte character (first byte: 11110www)
124        $width = 4;
125      }
126      else {
127        watchdog('CAPTCHA', 'Encountered an illegal byte while splitting an utf8 string in characters.', array(), WATCHDOG_ERROR);
128        return $characters;
129      }
130    }
131    $characters[] = substr($str, $i, $width);
132    $i += $width;
133  }
134  return $characters;
135}
136
137/**
138 * Helper function for checking the setup of the Image CAPTCHA.
139 *
140 * The image CAPTCHA requires at least the GD PHP library.
141 * Support for TTF is recommended and the enabled
142 * font files should be readable.
143 * This functions checks these things.
144 *
145 * @param $check_fonts whether or not the enabled fonts should be checked.
146 *
147 * @return status code: bitwise 'OR' of status flags like
148 *   IMAGE_CAPTCHA_ERROR_NO_GDLIB, IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT,
149 *   IMAGE_CAPTCHA_ERROR_TTF_FILE_READ_PROBLEM.
150 */
151function _image_captcha_check_setup($check_fonts=TRUE) {
152  // Start clean.
153  $status = 0;
154  // Check if we can use the GD library.
155  // We need at least the imagepng function (for font previews on the settings page).
156  // Note that the imagejpg function is optionally also used, but not required.
157  if (!function_exists('imagepng')) {
158    $status = $status | IMAGE_CAPTCHA_ERROR_NO_GDLIB;
159  }
160  if (!function_exists('imagettftext')) {
161    $status = $status | IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT;
162  }
163  if ($check_fonts) {
164    // Check availability of enabled fonts.
165    $fonts = _image_captcha_get_enabled_fonts();
166    list($readable_fonts, $problem_fonts) = _image_captcha_check_fonts($fonts);
167    if (count($problem_fonts) != 0) {
168      $status = $status | IMAGE_CAPTCHA_ERROR_TTF_FILE_READ_PROBLEM;
169    }
170  }
171  return $status;
172}
173
174/**
175 * Implementation of hook_captcha().
176 */
177function image_captcha_captcha($op, $captcha_type='', $captcha_sid=NULL) {
178  switch ($op) {
179    case 'list':
180      // Only offer the image CAPTCHA if it is possible to generate an image on this setup.
181      if (!(_image_captcha_check_setup() & IMAGE_CAPTCHA_ERROR_NO_GDLIB)) {
182        return array('Image');
183      }
184      else {
185        return array();
186      }
187      break;
188
189    case 'generate':
190      if ($captcha_type == 'Image') {
191        // In offline mode, the image CAPTCHA does not work because the request
192        // for the image itself won't succeed (only ?q=user is permitted for
193        // unauthenticated users). We fall back to the Math CAPTCHA in that case.
194        global $user;
195        if (variable_get('site_offline', FALSE) && $user->uid == 0) {
196          return captcha_captcha('generate', 'Math');
197        }
198        // generate a CAPTCHA code
199        $allowed_chars = _image_captcha_utf8_split(variable_get('image_captcha_image_allowed_chars', IMAGE_CAPTCHA_ALLOWED_CHARACTERS));
200        $code_length = (int)variable_get('image_captcha_code_length', 5);
201        $code = '';
202        for ($i = 0; $i < $code_length; $i++) {
203          $code .= $allowed_chars[array_rand($allowed_chars)];
204        }
205
206        // build the result to return
207        $result = array();
208
209        // Use javascript for some added usability (e.g. image reload).
210        drupal_add_js(drupal_get_path('module', 'image_captcha') .'/image_captcha.js');
211
212        $result['solution'] = $code;
213        // Generate image source URL (add timestamp to avoid problems with
214        // client side caching: subsequent images of the same CAPTCHA session
215        // have the same URL, but should display a different code).
216        $img_src = check_url(url("image_captcha/$captcha_sid/". time()));
217        $result['form']['captcha_image'] = array(
218          '#type' => 'markup',
219          '#value' => '<img src="'. $img_src .'" class="captcha_image" id="captcha_image_'. $captcha_sid .'" alt="'. t('Image CAPTCHA') .'" title="'. t('Image CAPTCHA') .'" />',
220          '#weight' => -2,
221        );
222        $result['form']['captcha_response'] = array(
223          '#type' => 'textfield',
224          '#title' => t('What code is in the image?'),
225          '#description' => t('Enter the characters shown in the image.'),
226          '#weight' => 0,
227          '#required' => TRUE,
228          '#size' => 15,
229        );
230
231        // Handle the case insensitive validation option combined with ignoring spaces.
232        switch (variable_get('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE)) {
233          case CAPTCHA_DEFAULT_VALIDATION_CASE_SENSITIVE:
234            $result['captcha_validate'] = 'captcha_validate_ignore_spaces';
235            break;
236          case CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE:
237            $result['captcha_validate'] = 'captcha_validate_case_insensitive_ignore_spaces';
238            break;
239        }
240
241
242        return $result;
243      }
244      break;
245
246  }
247}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.