Multiple correct answers
xurizaemon - November 13, 2008 - 02:21
| Project: | CAPTCHA |
| Version: | 5.x-3.1 |
| Component: | Code |
| Category: | support request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Jump to:
Description
Hi,
I've built a Captcha module which works OK, but I want to be able to allow people to give multiple "correct" answers.
Our use case is that we are building this module for people to register on a site if they own a recent copy of our publication.
We want to accept two correct answers for the same question ("What's the first word on page 212?"), where page 212 might be from the 2008 or 2009 edition.
Does v2 or v3 of Captcha support such a thing?
For now, I'll do it via hook_user(), but I'd love to make this module which supports multiple correct answers available to the community as a CAPTCHA module also.
Cheers

#1
It could ALMOST be done in the preprocess phase, if I knew which QUESTION had been asked; then I could return a true/false based on whether the supplied answer was in the correct answers for that question.
Would be interested to hear any other methods I could try - for now I'll just have to implement as a _user() hook in our module, but I'd really like to get this one worthy of release.
#2
It can be done in the preprocess phase, and you don't have to know the original question actually.
I guess you have a fixed set of questions with known possible answers. You then can build a mapping of the possible answers as follows.
Say you have a question with possible answers "foo" and "bar". You put the following entries in the map:
<?php$map['foo'] = 'foo';
$map['bar'] = 'foo';
?>
Then, during preprocess phase, you can then translate 'foo' and 'bar' to 'foo', so the validation phase has only to check for 'foo'.
This trick only works easily of course if all the possible answers of all your questions are different.
If there is another question with answers 'mzo' and 'bar', there is a bit of a problem, but you could use
<?php$map['foo'] = 'bar';
$map['bar'] = 'bar';
$map['mzo'] = 'bar';
?>
to make it work. In other cases it could however be impossible to build a map.
I hope this helps.
#3
Thanks Stefaan
I eventually realised that I could do it if I put the array of correct answers into the session using sess_write, and then compared with that value in preprocess. I'll probably do this using a keyed variable name, so that accessing two CAPTCHA pages with different questions out of order doesn't cause a conflict,
Can you see any disadvantages to this approach?
EDIT: Duh! Can't use a keyed variable name, because I face the same issue in preprocess - not knowing the key!
#4
There are some disadvantages with using sessions for CAPTCHA related functionality. In fact, CAPTCHA module 5.x-3.x and 6.x-1.x use sessions to store the solution, but because it causes a lot of problems (and support requests/bug reports), I am trying to make a version (6.x-2.x) that does not use sessions.
The problems are generally related to cookies (a requirement for drupal sessions to work) and various browser settings/policies for cookies, that break sessions for anonymous users.
Another problem is that using sessions for anonymous users blows up the sessions table if you have a lot of (anon) visitors.
If you have a fixed set of questions and answers I would recommend just to hard code these questions and answer mapping in you module. Or you could use your own table for storing the questions and answers. It depends on how many questions you have and how frequently they have to change.
#5
I had noticed the session code in 5.x-3.1 actually this afternoon - after implementing something very similar in my version :)
As the CAPTCHA module I'm using depends on session functionality, I don't see making this module depend on the same as a disadvantage. And hardcoding the questions and answers means the module wouldn't be available for use for other folks, which I would prefer.
The cookie requirement is OK for our use case (the site we're porting from also requires sessions for the same functionality). But, if you do produce a version for 6.x which works without depending on sessions, I'm happy to backport that code to both this module and to CAPTCHA 5.x.
My current code is available here, if you'd like to take a look: http://www.giantrobot.co.nz/tmp/question_captcha-5.x-0.1alpha1.tgz
I saw also that 5.x-3.1 talks directly to $_SESSION while I'd used the sess_write() / sess_read() functions - maybe you can tell me if there is an advantage to speaking directly to $_SESSION? Now that I look again at the API docs for the sess_* functions, while they aren't clearly marked as private, they also aren't really documented for general use either.
Thanks for all the good input, Stefaan!
#6
As far as I know, this is how working with sessions should be done in Drupal. You only have to get/set from/to $_SESSION and Drupal/PHP will take care of the loading/saving with sess_write/sess_read.
If you look in Drupal core, you'll find almost no use of sess_foo directly, only $_SESSION stuff.