View source
<?php
define('IMAGE_CAPTCHA_ALLOWED_CHARACTERS', 'aAbBCdEeFfGHhijKLMmNPQRrSTtWXYZ23456789');
define('IMAGE_CAPTCHA_ERROR_NO_GDLIB', 1);
define('IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT', 2);
define('IMAGE_CAPTCHA_ERROR_TTF_FILE_READ_PROBLEM', 4);
define('IMAGE_CAPTCHA_FILE_FORMAT_JPG', 1);
define('IMAGE_CAPTCHA_FILE_FORMAT_PNG', 2);
define('IMAGE_CAPTCHA_FILE_FORMAT_TRANSPARENT_PNG', 3);
function image_captcha_help($path, $arg) {
switch ($path) {
case 'admin/config/people/captcha/image_captcha':
$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>';
return $output;
}
}
function image_captcha_menu() {
$items = array();
$items['admin/config/people/captcha/image_captcha'] = array(
'title' => 'Image CAPTCHA',
'file' => 'image_captcha.admin.inc',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'image_captcha_settings_form',
),
'access arguments' => array(
'administer CAPTCHA settings',
),
'type' => MENU_LOCAL_TASK,
);
$items['admin/config/people/captcha/image_captcha/font_preview'] = array(
'title' => 'Font example',
'file' => 'image_captcha.admin.inc',
'page callback' => 'image_captcha_font_preview',
'access arguments' => array(
'administer CAPTCHA settings',
),
'type' => MENU_CALLBACK,
);
$items['image_captcha'] = array(
'file' => 'image_captcha.user.inc',
'page callback' => 'image_captcha_image',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
return $items;
}
function _image_captcha_get_enabled_fonts() {
if (IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT & _image_captcha_check_setup(FALSE)) {
return array(
'BUILTIN',
);
}
else {
$default = array(
drupal_get_path('module', 'image_captcha') . '/fonts/Tesox/tesox.ttf',
drupal_get_path('module', 'image_captcha') . '/fonts/Tuffy/Tuffy.ttf',
);
return variable_get('image_captcha_fonts', $default);
}
}
function _image_captcha_check_fonts($fonts) {
$readable_fonts = array();
$problem_fonts = array();
foreach ($fonts as $font) {
if ($font != 'BUILTIN' && (!is_file($font) || !is_readable($font))) {
$problem_fonts[] = $font;
}
else {
$readable_fonts[] = $font;
}
}
return array(
$readable_fonts,
$problem_fonts,
);
}
function _image_captcha_utf8_split($str) {
$characters = array();
$len = strlen($str);
for ($i = 0; $i < $len;) {
$chr = ord($str[$i]);
if (($chr & 0x80) == 0x0) {
$width = 1;
}
else {
if (($chr & 0xe0) == 0xc0) {
$width = 2;
}
elseif (($chr & 0xf0) == 0xe0) {
$width = 3;
}
elseif (($chr & 0xf8) == 0xf0) {
$width = 4;
}
else {
watchdog('CAPTCHA', 'Encountered an illegal byte while splitting an utf8 string in characters.', array(), WATCHDOG_ERROR);
return $characters;
}
}
$characters[] = substr($str, $i, $width);
$i += $width;
}
return $characters;
}
function _image_captcha_check_setup($check_fonts = TRUE) {
$status = 0;
if (!function_exists('imagepng')) {
$status = $status | IMAGE_CAPTCHA_ERROR_NO_GDLIB;
}
if (!function_exists('imagettftext')) {
$status = $status | IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT;
}
if ($check_fonts) {
$fonts = _image_captcha_get_enabled_fonts();
list($readable_fonts, $problem_fonts) = _image_captcha_check_fonts($fonts);
if (count($problem_fonts) != 0) {
$status = $status | IMAGE_CAPTCHA_ERROR_TTF_FILE_READ_PROBLEM;
}
}
return $status;
}
function _image_captcha_image_size($code) {
$font_size = (int) variable_get('image_captcha_font_size', 30);
$character_spacing = (double) variable_get('image_captcha_character_spacing', '1.2');
$characters = _image_captcha_utf8_split($code);
$character_quantity = count($characters);
$width = $character_spacing * $font_size * $character_quantity;
$height = 2 * $font_size;
return array(
$width,
$height,
);
}
function image_captcha_captcha($op, $captcha_type = '', $captcha_sid = NULL) {
switch ($op) {
case 'list':
if (!(_image_captcha_check_setup() & IMAGE_CAPTCHA_ERROR_NO_GDLIB)) {
return array(
'Image',
);
}
else {
return array();
}
break;
case 'generate':
if ($captcha_type == 'Image') {
global $user;
if (variable_get('maintenance_mode', 0) && $user->uid == 0) {
return captcha_captcha('generate', 'Math');
}
$allowed_chars = _image_captcha_utf8_split(variable_get('image_captcha_image_allowed_chars', IMAGE_CAPTCHA_ALLOWED_CHARACTERS));
$code_length = (int) variable_get('image_captcha_code_length', 5);
$code = '';
for ($i = 0; $i < $code_length; $i++) {
$code .= $allowed_chars[array_rand($allowed_chars)];
}
$result = array();
$result['solution'] = $code;
$options = array(
'query' => array(
'sid' => $captcha_sid,
'ts' => REQUEST_TIME,
),
);
$img_src = drupal_strip_dangerous_protocols(url("image_captcha", $options));
list($width, $height) = _image_captcha_image_size($code);
$result['form']['captcha_image'] = array(
'#theme' => 'image',
'#weight' => -2,
'#path' => $img_src,
'#width' => $width,
'#height' => $height,
'#title' => t('Image CAPTCHA'),
'#alt' => t('Image CAPTCHA'),
);
$result['form']['captcha_response'] = array(
'#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,
);
switch (variable_get('captcha_default_validation', CAPTCHA_DEFAULT_VALIDATION_CASE_INSENSITIVE)) {
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;
}
return $result;
}
break;
}
}