This issue is closely related to #463002: Drop preprocess op of hook_captcha?
Case insensitive validation is now part of CAPTCHA core, but there are other kinds of CAPTCHA validation that go further than a simple equality test. For example:
http://drupal.org/node/440490#comment-1601638 (handling multiple possible responses)
#472450: image_captcha RTL support
I'm currently thinking along the lines of adding a '#captcha_validate' property to the generate op of hook_captcha like for example
case 'generate':
if ($captcha_type == 'Foo CAPTCHA') {
$captcha = array();
$captcha['solution'] = 'foo';
$captcha['form']['captcha_response'] = array(
'#type' => 'textfield',
'#title' => t('Enter "foo"'),
);
$captcha['form']['#captcha_validate'] = 'foo_custom_validation';
return $captcha;
We just can't reuse the '#validate' property because the arguments we should pass differ from a standard Drupal FAPI validate function. e.g.
function foo_custom_validation($solution, $response) {
}
Maybe we could also pass the CAPTCHA session id? But we could add this later too.
Comment | File | Size | Author |
---|---|---|---|
#5 | 473002_custom_captcha_validation_01.patch | 8.64 KB | soxofaan |
#5 | 473002_custom_captcha_validation_01_example.patch | 701 bytes | soxofaan |
Comments
Comment #1
soxofaan CreditAttribution: soxofaan commentedthis one should be fixed before 6.x-2.0-rc2
Comment #2
thekevinday CreditAttribution: thekevinday commentedpoke. subscribing.
Comment #3
soxofaan CreditAttribution: soxofaan commentedmarked #496806: Do more with $result as duplicate
Comment #4
awolfey CreditAttribution: awolfey commentedsubscribe
Comment #5
soxofaan CreditAttribution: soxofaan commentedHere is a first patch to implement this.
For challenge implementing modules: custom CAPTCHA validation can be defined as follows:
function foo_custom_validation() will be called instead of the traditional equality test, it should return TRUE/FALSE for correct/wrong response.
Also attached: proof of concept example for the image CAPTCHA module to make it only accept the answer 'foo'.
Also note that the global case sensitive/insensitive option is implemented through this mechanism now.
edit: typo
Comment #6
awolfey CreditAttribution: awolfey commentedThis works perfectly form me. For validating a response against multiple possible solutions in the riddler module I used:
I did see that captcha will pass an empty response to the custom validation, which could require checking there. I'm not sure if there is a case where you would want to see an empty response, so maybe it's better to check for that before response is passed.
Thanks!
Comment #7
soxofaan CreditAttribution: soxofaan commented@awolfey: thanks for testing
I'm not sure I understand what you mean, but to block empty responses you can flag a texfield as required, which will make drupal complain about the empty response, even before CAPTCHA kicks in. Take the simple math challenge for example:
note the
'#required' => TRUE,
as the last property.Comment #8
awolfey CreditAttribution: awolfey commentedI have required set to TRUE. I first did my test this way:
Which, on an empty response, gave me this php warning: warning: stristr() [function.stristr]: Empty delimiter in C:\wamp\www\sandbox\sites\all\modules\riddler\riddler.module on line 180. There is ALSO a message that the field is required.
Returning FALSE on !$response catches it before stristr(). It's not a problem for in_array().
Thanks
Comment #9
soxofaan CreditAttribution: soxofaan commentedThat warning is because of the behavior of the stristr() function when the second argument is an empty string, it has nothing to do with the CAPTCHA module or even Drupal.
In this case you should indeed catch it before calling stristr().
Note that you are not limited to oneliner validation functions (maybe the examples suggest this): you can add for loops and if test all you want. As long as they return TRUE on success en FALSE on failure.
Comment #10
awolfey CreditAttribution: awolfey commentedRight. I wasn't expecting empty results to get passed to the validation function. Not a big deal.
Anyway, looking forward to this being committed.
Thanks.
Comment #11
soxofaan CreditAttribution: soxofaan commentedThe patch from #5 went in with some further tweaks:
http://drupal.org/cvs?commit=232866
Question to the module developers that want to use this functionality:
the custom CAPTCHA validation function are expected to be of the form:
Is this enough or would there be interest to receive more input, like $form, $form_state?
Comment #12
awolfey CreditAttribution: awolfey commentedWorking for me. Updated the D6 version of riddler to be compatible. For that module there's no need for $form, $form_state that I can see now.
Thanks.
Comment #13
soxofaan CreditAttribution: soxofaan commentedadded optional $element and $form_state for captcha validate functions as suggested in #11
http://drupal.org/cvs?commit=256822
this issue can finally be closed