'JPG'), $_captcha_formats);
}
if ($_captcha_imagetypes & IMG_GIF) {
$_captcha_default_format = 1;
$_captcha_formats = array_merge(array(1 => 'GIF'), $_captcha_formats);
}
if ($_captcha_imagetypes & IMG_PNG) {
$_captcha_default_format = 0;
$_captcha_formats = array_merge(array(0 => 'PNG'), $_captcha_formats);
}
}
/**
* Implementation of hook_help().
*/
function captcha_help($section = "admin/help#captcha") {
$output = "";
switch ($section) {
case 'admin/help#captcha':
$output = t('Users would be shown a graphic image with some text which they will have to enter manually to verify they are not a bot. CAPTCHA requires PHP to be compiled with GD support.');
break;
case 'admin/modules#description':
$output = t("Adds a Captcha to specified forms.");
if (!function_exists('imagecreate')) {
$output .= " ".t("GD support is not detected. This module requires PHP to be compiled with GD support.");
}
break;
}
return $output;
}
/**
* Implementation of hook_settings().
*/
function captcha_settings() {
global $_captcha_default_format, $_captcha_formats;
$group .= form_select(t('Image format'), 'captcha_format', variable_get('captcha_format', $_captcha_default_format), $_captcha_formats, t("Output captcha image format. These are the formats supported in your PHP so if you can't see the image, try another one."));
$output .= form_group(t('Image Options'),$group);
if (function_exists('imagecreate')) {
$group = form_radios(t('user registration'), 'captcha_newuser', variable_get('captcha_newuser', 0), array(0 => t('No CAPTCHA support'), 1 => t('CAPTCHA support')));
$group .= form_radios(t('comments'), 'captcha_comment', variable_get('captcha_comment', 0), array(0 => t('No CAPTCHA support'), 1 => t('CAPTCHA support'), 2 => t('CAPTCHA support only for anonymous user')));
foreach (node_list() as $type) {
$group .= form_radios(t(node_invoke($type,'node_name')), "captcha_node_$type", variable_get("captcha_node_$type", 0), array(0 => t('No CAPTCHA support'), 1 => t('CAPTCHA support'), 2 => t('CAPTCHA support only for anonymous user')));
}
$output .= form_group(t('Form Options'),$group);
}
return $output;
}
/**
* Implementation of hook_menu().
*/
function captcha_menu($may_cache) {
$items = array();
$items[] = array('path' => 'captcha/image', 'title' => t('captcha image'),
'callback' => '_captcha_image', 'access' => user_access('access content'),
'type' => MENU_CALLBACK);
return $items;
}
/**
* Implementation of hook_link().
*/
function captcha_link($type, $node = 0, $main) {
if ($type == 'system') {
menu('captcha', t('captcha image'), 'captcha_image', 0, MENU_HIDE);
}
}
/**
* Implementation of hook_nodeapi().
*/
function captcha_nodeapi(&$node, $op, $arg) {
global $user;
$type = $node->type;
// check if captcha is enabled for form type
if (variable_get("captcha_node_$type",0) != 1 && !(variable_get("captcha_node_$type",0) == 2 && !$user->uid))
return;
// check for GD support
if (!function_exists('imagecreate')) return;
switch ($op) {
case 'validate':
$node->captcha = trim($node->captcha);
if (isset($node->captcha) && $node->captcha != variable_get('captcha_code','') || variable_get('captcha_code','') == '') {
form_set_error('captcha', t('The user verification code you entered is not correct.'));
}
break;
case 'form post':
variable_set('captcha_code', _captcha_generate_code());
$group = form_item('','
');
$group .= form_textfield(t('Code'), 'captcha', NULL, 15, 15, t('Enter the characters shown in the image above.'), NULL, TRUE);
$output = form_group(t('Human user verification'),$group);
return $output;
}
}
/**
* User callback; adds captcha field to new user form.
*/
function captcha_user($type, &$edit, &$user, $category = NULL) {
global $user;
// check if user is logged in
if ($user->uid) return;
// check if captcha is enabled for form type
if (variable_get('captcha_newuser',0) == 0) return;
// check for GD support
if (!function_exists('imagecreate')) return;
switch ($type) {
case 'validate':
if ($edit['captcha'] == '' || variable_get('captcha_code','') == '' || $edit['captcha'] != variable_get('captcha_code','')) {
form_set_error('captcha', t('The user verification code you entered is not correct.'));
// variable_set('captcha_code', _captcha_generate_code());
}
break;
case 'register':
variable_set('captcha_code', _captcha_generate_code());
$group = form_item('','
');
$group .= form_textfield(t('Code'), 'captcha', NULL, 15, 15, t('Enter the characters shown in the image above.'), NULL, TRUE);
return array(array('title' => t('Human user verification'), 'data'=>$group));
}
}
/**
* Comment callback; adds captcha field to new comment form.
*/
function captcha_comment($op,$edit) {
global $user;
// check if captcha is enabled for form type
if (variable_get('captcha_comment',0) != 1 && !(variable_get('captcha_comment',0) == 2 && !$user->uid))
return;
// check for GD support
if (!function_exists('imagecreate')) return;
switch ($op) {
case 'validate':
// only validate captcha if "Post comment" button is used
if ($_POST['op'] == t('Post comment') && (variable_get('captcha_code','') == '' || $edit['captcha'] != variable_get('captcha_code',''))) {
form_set_error('captcha', t('The user verification code you entered is not correct.'));
}
break;
case 'form':
// only show captcha form if the "Post comment" button is visible
if (!variable_get('comment_preview', 1) || ($_POST['op'] == t('Preview comment')) || ($_POST['op'] == t('Post comment'))) {
variable_set('captcha_code', _captcha_generate_code());
$group = form_item('','
');
$group .= form_textfield(t('Code'), 'captcha', NULL, 15, 15, t('Enter the characters shown in the image above.'), NULL, TRUE);
$output = form_group(t('Human user verification'),$group);
return $output;
}
}
}
/**
* Prints an image containing a captcha code.
*/
function _captcha_image() {
global $_captcha_default_format, $_captcha_formats;
// Check for captcha code and exit if not existant to prevent abuse
$captchaCode = variable_get('captcha_code','');
if ($captchaCode == '')
return drupal_goto();
// Check for GD support
if (!function_exists('imagecreate'))
return drupal_goto();
// define the image dimensions
$imageWidth = 280;
$imageHeight = 60;
$img = imagecreate($imageWidth,$imageHeight);
// draw image
$img = _captcha_image_arcs($img,$captchaCode);
// Set headers
header('Expires: Mon, 01 Jan 1997 05:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
switch (variable_get('captcha_format',$_captcha_default_format)) {
case 2:
header('Content-type: image/jpg');
break;
case 1:
header('Content-type: image/gif');
break;
default:
header('Content-type: image/png');
break;
}
// output the image
switch (variable_get('captcha_format',$_captcha_default_format)) {
case 2:
imagejpeg($img);
break;
case 1:
imagegif($img);
break;
default:
imagepng($img);
break;
}
// destroy the image
imagedestroy($img);
}
/**
* Returns a captcha code.
*/
function _captcha_generate_code() {
$charlist = 'QWERTYUPLKJHGFDSAZXCVBNM23456789';
$length = rand(6,8);
$code = '';
srand((double) microtime() * 1000000);
for ($i=0;$i<$length;$i++) {
$char = substr($charlist, rand() % strlen($charlist), 1);
if (preg_match("/".$char."/",$code) == 0) {
$code .= $char;
} else {
$i--;
}
}
return $code;
}
/**
* Returns an array of files with TTF extensions in the specified directory.
*/
function _captcha_font_list($dir) {
$filelist = array();
if ($handle = opendir($dir)) {
while ($file = readdir($handle)) {
if (preg_match("/\.ttf$/i",$file) == 1)
$filelist[] = $file;
}
closedir($handle);
}
return $filelist;
}
/**
* Draws a captcha image
*/
function _captcha_image_arcs($img,$code) {
// define colors
$backgroundColor = imagecolorallocate($img,224,224,224);
$borderColor = imagecolorallocate($img,0,0,0);
$textColor = imagecolorallocate($img,0,0,0);
$noiseColor = imagecolorallocate($img,0,0,0);
// define number of noise elements
$noiseCount = rand(imagesx($img)/30,imagesx($img)/10);
// draw image background
imagefill($img,0,0,$backgroundColor);
// draw image noise
for ($i=0;$i<$noiseCount;$i++) {
$segmentCount = rand(1,4);
$x = rand(10,imagesx($img)-10);
$y = rand(4,imagesy($img)-10);
$angle = rand(0,180);
for ($j=0;$j<$segmentCount;$j++) {
// randomly draw an arc or a line
if (rand(0,3) == 1) {
imagearc($img,$x,$y,rand(10,15),rand(10,15),rand(0,224),rand(180,360),$noiseColor);
$x += rand(-20,20);
$y += rand(-20,20);
} else {
$segmentAngle = $angle + rand(-2,2);
$segmentLength = rand(3,10);
$xLength = round($segmentLength * cos($segmentAngle));
$yLength = round($segmentLength * sin($segmentAngle));
imageline($img,$x,$y,$x+$xLength,$y+$yLength,$noiseColor);
$x += $xLength;
$y += $yLength;
}
}
}
// Get truetype font list
$fontDir = 'modules/captcha';
$fonts = _captcha_font_list($fontDir);
if (count($fonts) > 0) {
// write text using a truetype font
$charSize = 20; // font size
$charWidth = 0; // width of previous character
$x = 20; // initial x position
// iterate over characters
for ($i=0;$i