...
 
Commits (41)
*.patch
*.diff
.idea/
.idea/*
.DS_Store
This diff is collapsed.
This diff is collapsed.
......@@ -12,6 +12,18 @@ function captcha_schema() {
// Table for positions and types of the challenges.
$schema['captcha_points'] = array(
'description' => 'This table describes which challenges should be added to which forms.',
'export' => array(
'key' => 'form_id',
'identifier' => 'captcha',
'default hook' => 'captcha_default_points', // Function hook name.
'status' => 'mark_status',
'api' => array(
'owner' => 'captcha',
'api' => 'captcha', // Base name for api include files.
'minimum_version' => 1,
'current_version' => 1,
),
),
'fields' => array(
'form_id' => array(
'description' => 'The form_id of the form to add a CAPTCHA to.',
......@@ -57,7 +69,7 @@ function captcha_schema() {
'sid' => array(
'description' => "Session ID of the user.",
'type' => 'varchar',
'length' => 64,
'length' => 128,
'not null' => TRUE,
'default' => '',
),
......@@ -97,7 +109,7 @@ function captcha_schema() {
'type' => 'int',
'not null' => TRUE,
'default' => 0,
)
),
),
'primary key' => array('csid'),
'indexes' => array(
......@@ -109,7 +121,7 @@ function captcha_schema() {
}
/**
* Implementation of hook_requirements().
* Implements of hook_requirements().
*/
function captcha_requirements($phase) {
$requirements = array();
......@@ -130,29 +142,10 @@ function captcha_requirements($phase) {
}
/**
* Implementation of hook_install().
* Implements of hook_install().
*/
function captcha_install() {
$t = get_t();
// Insert some default CAPTCHA points.
$form_ids = array(
'contact_site_form', 'contact_personal_form',
'user_register_form', 'user_pass', 'user_login', 'user_login_block',
'forum_node_form'
);
// Add form_ids of all currently known node types too.
foreach (node_type_get_names() as $type => $name) {
$form_ids[] = 'comment_node_' . $type . '_form';
}
foreach ($form_ids as $form_id) {
db_insert('captcha_points')
->fields(array(
'form_id' => $form_id,
'module' => NULL,
'captcha_type' => NULL,
))
->execute();
}
// Be friendly to your users: what to do after install?
drupal_set_message($t('You can now <a href="!captcha_admin">configure the CAPTCHA module</a> for your site.',
......@@ -167,7 +160,7 @@ function captcha_install() {
}
/**
* Implementation of hook_uninstall().
* Implements of hook_uninstall().
*/
function captcha_uninstall() {
drupal_uninstall_schema('captcha');
......@@ -176,7 +169,7 @@ function captcha_uninstall() {
}
/**
* Implementation of hook_update_N()
* Implements of hook_update_N().
*/
function captcha_update_6200() {
$items = array();
......@@ -239,7 +232,7 @@ function captcha_update_6200() {
'type' => 'int',
'not null' => TRUE,
'default' => 0,
)
),
),
'primary key' => array('csid'),
'indexes' => array(
......@@ -253,7 +246,8 @@ function captcha_update_6200() {
}
/**
* Implementation of hook_update_N()
* Implements of hook_update_N().
*
* Change the captcha points with the old text CAPTCHA, which was
* removed from the 6.x-2.x branch, to the simple math CAPTCHA.
*/
......@@ -263,9 +257,9 @@ function captcha_update_6201() {
return $items;
}
/**
* Implementation of hook_update_N()
* Implements of hook_update_N().
*
* Add a CAPTCHA token column to captcha_sessions table.
*/
function captcha_update_6202() {
......@@ -274,10 +268,9 @@ function captcha_update_6202() {
return $ret;
}
/**
* Implementation of hook_update_N()
* Implements of hook_update_N().
*
* Rename the type field to captcha_type in captcha_points.
*/
function captcha_update_6203() {
......@@ -286,7 +279,6 @@ function captcha_update_6203() {
return $ret;
}
/**
* Migrate form configuration for changed form ids in Drupal 7.
*/
......@@ -334,3 +326,18 @@ function captcha_update_7000() {
->execute();
}
}
/**
* Increase the Session Id field size.
*/
function captcha_update_7001() {
$schema = captcha_schema();
db_change_field('captcha_sessions', 'sid', 'sid', array(
'description' => "Session ID of the user.",
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
));
}
......@@ -4,7 +4,7 @@
attach: function (context) {
// Turn off autocompletion for the CAPTCHA response field.
// We do it here with Javascript (instead of directly in the markup)
// We do it here with JavaScript (instead of directly in the markup)
// because this autocomplete attribute is not standard and
// it would break (X)HTML compliance.
$("#edit-captcha-response").attr("autocomplete", "off");
......@@ -14,25 +14,25 @@
Drupal.behaviors.captchaAdmin = {
attach: function (context) {
// Add onclick handler to checkbox for adding a CAPTCHA description
// so that the textfields for the CAPTCHA description are hidden
// when no description should be added.
// Add onclick handler to checkbox for adding a CAPTCHA description
// so that the textfields for the CAPTCHA description are hidden
// when no description should be added.
// @todo: div.form-item-captcha-description depends on theming, maybe
// it's better to add our own wrapper with id (instead of a class).
$("#edit-captcha-add-captcha-description").click(function() {
if ($("#edit-captcha-add-captcha-description").is(":checked")) {
// Show the CAPTCHA description textfield(s).
$("div.form-item-captcha-description").show('slow');
}
else {
// Hide the CAPTCHA description textfield(s).
$("div.form-item-captcha-description").hide('slow');
}
});
// Hide the CAPTCHA description textfields if option is disabled on page load.
if (!$("#edit-captcha-add-captcha-description").is(":checked")) {
$("div.form-item-captcha-description").hide();
}
$("#edit-captcha-add-captcha-description").click(function() {
if ($("#edit-captcha-add-captcha-description").is(":checked")) {
// Show the CAPTCHA description textfield(s).
$("div.form-item-captcha-description").show('slow');
}
else {
// Hide the CAPTCHA description textfield(s).
$("div.form-item-captcha-description").hide('slow');
}
});
// Hide the CAPTCHA description textfields if option is disabled on page load.
if (!$("#edit-captcha-add-captcha-description").is(":checked")) {
$("div.form-item-captcha-description").hide();
}
}
};
......
This diff is collapsed.
......@@ -60,7 +60,11 @@ abstract class CaptchaBaseWebTestCase extends DrupalWebTestCase {
function setUp() {
// Load two modules: the captcha module itself and the comment module for testing anonymous comments.
parent::setUp('captcha', 'comment');
$modules = func_get_args();
if (isset($modules[0]) && is_array($modules[0])) {
$modules = $modules[0];
}
parent::setUp(array_merge(array('captcha', 'comment'), $modules));
module_load_include('inc', 'captcha');
// Create a normal user.
......@@ -413,7 +417,6 @@ class CaptchaAdminTestCase extends CaptchaBaseWebTestCase {
function testAdminAccess() {
$this->drupalLogin($this->normal_user);
$this->drupalGet(self::CAPTCHA_ADMIN_PATH);
file_put_contents('tmp.simpletest.html', $this->drupalGetContent());
$this->assertText(t('Access denied'), 'Normal users should not be able to access the CAPTCHA admin pages', 'CAPTCHA');
$this->drupalLogin($this->admin_user);
......@@ -602,16 +605,16 @@ class CaptchaAdminTestCase extends CaptchaBaseWebTestCase {
// Set CAPTCHA on user register form.
captcha_set_form_id_setting('user_register', 'captcha/Math');
// Put Javascript snippet in CAPTCHA description.
// Put JavaScript snippet in CAPTCHA description.
$this->drupalLogin($this->admin_user);
$xss = '<script type="text/javascript">alert("xss")</script>';
$edit = array('captcha_description' => $xss);
$this->drupalPost(self::CAPTCHA_ADMIN_PATH, $edit, 'Save configuration');
// Visit user register form and check if Javascript snippet is there.
// Visit user register form and check if JavaScript snippet is there.
$this->drupalLogout();
$this->drupalGet('user/register');
$this->assertNoRaw($xss, 'Javascript should not be allowed in CAPTCHA description.', 'CAPTCHA');
$this->assertNoRaw($xss, 'JavaScript should not be allowed in CAPTCHA description.', 'CAPTCHA');
}
......
This documentation is for developers that want to implement their own
challenge type and integrate it with the base CAPTCHA module.
......@@ -216,4 +215,3 @@ This will place the CAPTCHA element
- in the 'my_fancy_form' form inside the container $form['items']['buttons'],
just before the element $form['items']['buttons']['sacebutton'].
- in the 'another_form' form at the toplevel of the form, with a weight 34.
It possible to put your own fonts for the Image CAPTCHA in this folder.
However, this is not the recommended way, as they can get lost easily during
a module update. The recommended way to provide your own fonts is putting them
in the files directory of your Drupal setup or, just like with contributed
modules and themes, in the "libraries" folders sites/all/libraries/fonts
or sites/<site>/libraries/fonts.
or sites/<site>/libraries/fonts.
......@@ -3,10 +3,8 @@
/**
* @file
* Functions for administration/settings interface.
*
*/
/**
* Configuration form for image_captcha.
*/
......@@ -16,10 +14,9 @@ function image_captcha_settings_form() {
// Add CSS for theming of admin form.
$form['#attached']['css'] = array(drupal_get_path('module', 'image_captcha') . '/image_captcha.css');
// Use javascript for some added usability on admin form.
// Use JavaScript for some added usability on admin form.
$form['#attached']['js'] = array(drupal_get_path('module', 'image_captcha') . '/image_captcha.js');
// First some error checking.
$setup_status = _image_captcha_check_setup(FALSE);
if ($setup_status & IMAGE_CAPTCHA_ERROR_NO_GDLIB) {
......@@ -70,11 +67,10 @@ function image_captcha_settings_form() {
);
}
// Font related stuff.
$form['image_captcha_font_settings'] = _image_captcha_settings_form_font_section();
// Color and file format settings.
// Color and file format settings.
$form['image_captcha_color_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Color and image settings'),
......@@ -121,13 +117,13 @@ function image_captcha_settings_form() {
),
);
// distortion and noise settings
// Distortion and noise settings.
$form['image_captcha_distortion_and_noise'] = array(
'#type' => 'fieldset',
'#title' => t('Distortion and noise'),
'#description' => t('With these settings you can control the degree of obfuscation by distortion and added noise. Do not exaggerate the obfuscation and assure that the code in the image is reasonably readable. For example, do not combine high levels of distortion and noise.'),
);
// distortion
// Distortion.
$form['image_captcha_distortion_and_noise']['image_captcha_distortion_amplitude'] = array(
'#type' => 'select',
'#title' => t('Distortion level'),
......@@ -153,7 +149,7 @@ function image_captcha_settings_form() {
'#default_value' => variable_get('image_captcha_bilinear_interpolation', FALSE),
'#description' => t('This option enables bilinear interpolation of the distortion which makes the image look smoother, but it is more CPU intensive.'),
);
// noise
// Noise.
$form['image_captcha_distortion_and_noise']['image_captcha_dot_noise'] = array(
'#type' => 'checkbox',
'#title' => t('Add salt and pepper noise'),
......@@ -192,7 +188,6 @@ function image_captcha_settings_form() {
return $form;
}
/**
* Form elements for the font specific setting.
*
......@@ -200,7 +195,8 @@ function image_captcha_settings_form() {
* general form function image_captcha_settings_form with some
* specific logic.
*
* @return $form, the font settings specific form elements.
* @return array
* the font settings specific form elements.
*/
function _image_captcha_settings_form_font_section() {
// Put it all in a fieldset.
......@@ -212,7 +208,7 @@ function _image_captcha_settings_form_font_section() {
// First check if there is TrueType support.
$setup_status = _image_captcha_check_setup(FALSE);
if ($setup_status & IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT) {
// Show a warning that there is no TrueType support
// Show a warning that there is no TrueType support.
$form['no_ttf_support'] = array(
'#type' => 'item',
'#title' => t('No TrueType support'),
......@@ -221,7 +217,6 @@ function _image_captcha_settings_form_font_section() {
}
else {
// Build a list of all available fonts.
$available_fonts = array();
......@@ -231,7 +226,7 @@ function _image_captcha_settings_form_font_section() {
// in separate requests, and we don't want to rescan the filesystem
// every time, so we cache the result.
variable_set('image_captcha_fonts_preview_map_cache', $fonts);
// Put these fonts with preview image in the list
// Put these fonts with preview image in the list.
foreach ($fonts as $token => $font) {
$img_src = check_url(url('admin/config/people/captcha/image_captcha/font_preview/' . $token));
$title = t('Font preview of @font (@file)', array('@font' => $font->name, '@file' => $font->uri));
......@@ -261,7 +256,6 @@ function _image_captcha_settings_form_font_section() {
'#process' => array('form_process_checkboxes'),
);
// Font size.
$form['image_captcha_font_size'] = array(
'#type' => 'select',
......@@ -302,16 +296,18 @@ function _image_captcha_settings_form_font_section() {
/**
* Helper function to get fonts from the given directories.
*
* @param $directories (optional) an array of directories
* @param array|null $directories
* an array of directories
* to recursively search through, if not given, the default
* directories will be used.
*
* @return an array of fonts file objects (with fields 'name',
* @return array
* an array of fonts file objects (with fields 'name',
* 'basename' and 'filename'), keyed on the md5 hash of the font
* path (to have an easy token that can be used in an url
* without en/decoding issues).
*/
function _image_captcha_get_available_fonts_from_directories($directories=NULL) {
function _image_captcha_get_available_fonts_from_directories($directories = NULL) {
// If no fonts directories are given: use the default.
if ($directories === NULL) {
$directories = array(
......@@ -331,9 +327,8 @@ function _image_captcha_get_available_fonts_from_directories($directories=NULL)
return $fonts;
}
/**
* Validation function for image_captcha configuration form
* Validation function for image_captcha configuration form.
*/
function image_captcha_settings_form_validate($form, &$form_state) {
// Check image_captcha_image_allowed_chars for spaces.
......@@ -360,7 +355,7 @@ function image_captcha_settings_form_validate($form, &$form_state) {
}
}
// check color settings
// Check color settings.
if (!preg_match('/^#([0-9a-fA-F]{3}){1,2}$/', $form_state['values']['image_captcha_background_color'])) {
form_set_error('image_captcha_background_color', t('Background color is not a valid hexadecimal color value.'));
}
......@@ -382,7 +377,6 @@ function image_captcha_settings_form_submit($form, &$form_state) {
/**
* Menu handler for font preview request.
*
*/
function image_captcha_font_preview($font_token) {
......@@ -394,14 +388,14 @@ function image_captcha_font_preview($font_token) {
// Get the mapping of font tokens to font file objects.
$fonts = variable_get('image_captcha_fonts_preview_map_cache', array());
if (!isset($fonts[$font_token])) {
echo('bad token');
echo ('bad token');
exit();
}
// Get the font path.
$font = $fonts[$font_token]->uri;
// Some sanity checks if the given font is valid.
if (!is_file($font) || !is_readable($font)) {
echo('bad font');
echo ('bad font');
exit();
}
}
......@@ -422,12 +416,12 @@ function image_captcha_font_preview($font_token) {
$color = imagecolorallocate($image, 0, 0, 0);
imagefilledrectangle($image, 0, 0, $width, $height, $background_color);
// Draw preview text
// Draw preview text.
if ($font == 'BUILTIN') {
imagestring($image, 5, 1, .5*$height-10, $text, $color);
imagestring($image, 5, 1, .5 * $height - 10, $text, $color);
}
else {
imagettftext($image, $font_size, 0, 1, 1.5*$font_size, $color, realpath($font), $text);
imagettftext($image, $font_size, 0, 1, 1.5 * $font_size, $color, realpath($font), $text);
}
// Set content type.
......
......@@ -27,4 +27,3 @@
.image_captcha_admin_fonts_selection img {
vertical-align: middle;
}
name = "Image CAPTCHA"
description = "Provides an image based CAPTCHA."
description = "Provides an image based CAPTCHA challenge."
package = "Spam control"
dependencies[] = captcha
core = 7.x
......@@ -9,3 +9,4 @@ files[] = image_captcha.install
files[] = image_captcha.module
files[] = image_captcha.admin.inc
files[] = image_captcha.user.inc
files[] = image_captcha.test
......@@ -18,10 +18,10 @@ function image_captcha_requirements($phase) {
if (_image_captcha_check_setup(FALSE) & IMAGE_CAPTCHA_ERROR_NO_GDLIB) {
$requirements['image_captcha_requires_gd'] = array(
'title' => $t('Image CAPTCHA requires GD library'),
'description' =>
$t('The Image CAPTCHA module can not be installed because your PHP setup does not provide the <a href="!gddoc">GD library</a>, which is required to generate images.',
array('!gddoc' => 'http://www.php.net/manual/en/book.image.php',)
),
'description' => $t(
'The Image CAPTCHA module can not be installed because your PHP setup does not provide the <a href="!gddoc">GD library</a>, which is required to generate images.',
array('!gddoc' => 'http://www.php.net/manual/en/book.image.php')
),
'severity' => REQUIREMENT_ERROR,
);
}
......@@ -30,7 +30,7 @@ function image_captcha_requirements($phase) {
}
/**
* On uninstall: remove module variables and clear variable cache
* On uninstall: remove module variables and clear variable cache.
*/
function image_captcha_uninstall() {
db_delete('variable')
......
......@@ -6,13 +6,12 @@
// Helper function to show/hide noise level widget.
var noise_level_shower = function(speed) {
speed = (typeof speed == 'undefined') ? 'slow' : speed;
if ($("#edit-image-captcha-dot-noise").is(":checked")
|| $("#edit-image-captcha-line-noise").is(":checked")) {
if ($("#edit-image-captcha-dot-noise").is(":checked") || $("#edit-image-captcha-line-noise").is(":checked")) {
$(".form-item-image-captcha-noise-level").show(speed);
} else {
$(".form-item-image-captcha-noise-level").hide(speed);
}
}
};
// Add onclick handler to the dot and line noise check boxes.
$("#edit-image-captcha-dot-noise").click(noise_level_shower);
$("#edit-image-captcha-line-noise").click(noise_level_shower);
......@@ -27,12 +26,12 @@
} else {
$(".form-item-image-captcha-bilinear-interpolation").hide(speed);
}
}
};
// Add onchange handler to the distortion level select widget.
$("#edit-image-captcha-distortion-amplitude").change(
smooth_distortion_shower);
// Show or hide appropriately on page load.
smooth_distortion_shower(0)
smooth_distortion_shower(0);
}
};
......
......@@ -16,7 +16,6 @@ define('IMAGE_CAPTCHA_FILE_FORMAT_JPG', 1);
define('IMAGE_CAPTCHA_FILE_FORMAT_PNG', 2);
define('IMAGE_CAPTCHA_FILE_FORMAT_TRANSPARENT_PNG', 3);
/**
* Implements hook_help().
*/
......@@ -33,7 +32,7 @@ function image_captcha_help($path, $arg) {
*/
function image_captcha_menu() {
$items = array();
// add an administration tab for image_captcha
// Add an administration tab for image_captcha.
$items['admin/config/people/captcha/image_captcha'] = array(
'title' => 'Image CAPTCHA',
'file' => 'image_captcha.admin.inc',
......@@ -50,7 +49,7 @@ function image_captcha_menu() {
'access arguments' => array('administer CAPTCHA settings'),
'type' => MENU_CALLBACK,
);
// callback for generating an image
// Callback for generating an image.
$items['image_captcha'] = array(
'file' => 'image_captcha.user.inc',
'page callback' => 'image_captcha_image',
......@@ -63,7 +62,8 @@ function image_captcha_menu() {
/**
* Helper function for getting the fonts to use in the image CAPTCHA.
*
* @return a list of font paths.
* @return array
* a list of font paths.
*/
function _image_captcha_get_enabled_fonts() {
if (IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT & _image_captcha_check_setup(FALSE)) {
......@@ -81,8 +81,11 @@ function _image_captcha_get_enabled_fonts() {
/**
* Helper function for checking if the specified fonts are available.
*
* @param $fonts paths of fonts to check.
* @return list($readable_fonts, $problem_fonts)
* @param array $fonts
* paths of fonts to check.
*
* @return array
* list($readable_fonts, $problem_fonts)
*/
function _image_captcha_check_fonts($fonts) {
$readable_fonts = array();
......@@ -100,25 +103,30 @@ function _image_captcha_check_fonts($fonts) {
/**
* Helper function for splitting an utf8 string correctly in characters.
*
* Assumes the given utf8 string is well formed.
* See http://en.wikipedia.org/wiki/Utf8 for more info
*/
function _image_captcha_utf8_split($str) {
$characters = array();
$len = strlen($str);
for ($i=0; $i < $len; ) {
for ($i = 0; $i < $len;) {
$chr = ord($str[$i]);
if (($chr & 0x80) == 0x00) { // one byte character (0zzzzzzz)
// One byte character (0zzzzzzz)
if (($chr & 0x80) == 0x00) {
$width = 1;
}
else {
if (($chr & 0xE0) == 0xC0) { // two byte character (first byte: 110yyyyy)
// Two byte character (first byte: 110yyyyy)
if (($chr & 0xE0) == 0xC0) {
$width = 2;
}
elseif (($chr & 0xF0) == 0xE0) { // three byte character (first byte: 1110xxxx)
// Three byte character (first byte: 1110xxxx)
elseif (($chr & 0xF0) == 0xE0) {
$width = 3;
}
elseif (($chr & 0xF8) == 0xF0) { // four byte character (first byte: 11110www)
// Four byte character (first byte: 11110www)
elseif (($chr & 0xF8) == 0xF0) {
$width = 4;
}
else {
......@@ -140,13 +148,15 @@ function _image_captcha_utf8_split($str) {
* font files should be readable.
* This functions checks these things.
*
* @param $check_fonts whether or not the enabled fonts should be checked.
* @param bool $check_fonts
* whether or not the enabled fonts should be checked.
*
* @return status code: bitwise 'OR' of status flags like
* @return int
* status code: bitwise 'OR' of status flags like
* IMAGE_CAPTCHA_ERROR_NO_GDLIB, IMAGE_CAPTCHA_ERROR_NO_TTF_SUPPORT,
* IMAGE_CAPTCHA_ERROR_TTF_FILE_READ_PROBLEM.
*/
function _image_captcha_check_setup($check_fonts=TRUE) {
function _image_captcha_check_setup($check_fonts = TRUE) {
// Start clean.
$status = 0;
// Check if we can use the GD library.
......@@ -170,30 +180,29 @@ function _image_captcha_check_setup($check_fonts=TRUE) {
}
/**
* Helper function for calculating image height and width
* based on given code and current font/spacing settings.
* Helper function for calculating image height and width based on given code and current font/spacing settings.
*
* @return array($width, $heigh)
* @return array
* array($width, $heigh)
*/
function _image_captcha_image_size($code) {
// Get settings
// Get settings.
$font_size = (int) variable_get('image_captcha_font_size', 30);
$character_spacing = (float) variable_get('image_captcha_character_spacing', '1.2');
$characters = _image_captcha_utf8_split($code);
$character_quantity = count($characters);
// Calculate height and width
// Calculate height and width.
$width = $character_spacing * $font_size * $character_quantity;
$height = 2 * $font_size;
return array($width, $height);
}
/**
* Implements hook_captcha().
*/
function image_captcha_captcha($op, $captcha_type='', $captcha_sid=NULL) {
function image_captcha_captcha($op, $captcha_type = '', $captcha_sid = NULL) {
switch ($op) {
case 'list':
// Only offer the image CAPTCHA if it is possible to generate an image on this setup.
......@@ -214,15 +223,15 @@ function image_captcha_captcha($op, $captcha_type='', $captcha_sid=NULL) {
if (variable_get('maintenance_mode', 0) && $user->uid == 0) {
return captcha_captcha('generate', 'Math');
}
// generate a CAPTCHA code
// Generate a CAPTCHA code.
$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_length = (int) variable_get('image_captcha_code_length', 5);
$code = '';
for ($i = 0; $i < $code_length; $i++) {
$code .= $allowed_chars[array_rand($allowed_chars)];
}
// build the result to return
// Build the result to return.
$result = array();
$result['solution'] = $code;
......@@ -235,15 +244,16 @@ function image_captcha_captcha($op, $captcha_type='', $captcha_sid=NULL) {
'ts' => REQUEST_TIME,
),
);
$img_src = check_url(url("image_captcha", $options));
$img_src = drupal_strip_dangerous_protocols(url("image_captcha", $options));
list($width, $height) = _image_captcha_image_size($code);
// TODO: start using a theming funtion for generating the image markup?
$result['form']['captcha_image'] = array(
'#type' => 'markup',
'#markup' => '<img src="' . $img_src
. '" width="'. $width . '" height="' . $height
. '" alt="' . t('Image CAPTCHA') . '" title="' . t('Image CAPTCHA') . '" />',
'#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',
......@@ -259,6 +269,7 @@ function image_captcha_captcha($op, $captcha_type='', $captcha_sid=NULL) {
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;
......
<?php
/**
* @file
* Tests for the Image CAPTCHA module.
*/
class ImageCaptchaWebTestCase extends CaptchaBaseWebTestCase {
public static function getInfo() {
return array(
'name' => 'General Image CAPTCHA functionality',
'description' => 'Testing of the basic Image CAPTCHA functions.',
'group' => 'CAPTCHA',
);
}
public function setUp() {
parent::setUp('image_captcha');
}
/**
* Helper function to get the CAPTCHA image element from the current form.
*/
protected function getCaptchaImageFromForm() {
$elements = $this->xpath('//input[@name="captcha_sid"]/../img');
return $elements[0];
}
/**
* Helper function to get a CAPTCHA form.
*/
protected function getImageCaptchaForm($form_id = 'user_login', $page = 'user') {
// Set a CAPTCHA on supplied form.
captcha_set_form_id_setting($form_id, 'image_captcha/Image');
// Fetch the page and make sure that we got a CAPTCHA.
$this->drupalGet($page);
$this->assertCaptchaPresence(TRUE);
}
/**
* Asserts that the image URL actually returns an image.
*/
protected function assertNonEmptyImage() {
$img = $this->getCaptchaImageFromForm();
// Try to fetch the image.
$this->drupalGet($this->getAbsoluteUrl($img['src']));
$this->assertTrue($this->drupalGetHeader('Content-Length') > 0,
'Image CAPTCHA image is not empty.');
}
/**
* Tests if the image URL actually returns an image with clean URLs enabled.
*/
public function testNonEmptyImageCleanURLs() {
variable_set('clean_url', 1);
$this->getImageCaptchaForm();
$this->assertNonEmptyImage();
}
/**
* Tests if the image URL actually returns an image with clean URLs disabled.
*/
public function testNonEmptyImageDirtyURLs() {
variable_set('clean_url', 0);
$this->getImageCaptchaForm();
$this->assertNonEmptyImage();
}
}
This diff is collapsed.