[Tip 1.1RC3] Let guests post using captcha

Started by pctwo, September 28, 2006, 11:33:45 AM

Previous topic - Next topic


(I posted this at http://www.smfhelper.com)

Say you have a board you want to let guests post in w/o registering, but you don't want an open invitation to spammers, here's a little hack to force guest posters to pass catpcha test.  It uses the captcha built into 1.1 rc3

In Post.template.php, add the capcha picture and text input to the form

// Guests have to put in their name and email...
if (isset($context['name']) && isset($context['email']))

// begin insert >>>>>>>>>>>>>>
if ($context['visual_verification'])
echo '
<td align="right">
<b>', $txt['visual_verification_label'], ':</b>
<div class="smalltext">', $txt['visual_verification_description'], '</div>
if ($context['use_graphic_library'])
echo '
<img src="', $context['verificiation_image_href'], '" alt="', $txt['visual_verification_description'], '" id="verificiation_image" /><br />';
echo '
<img src="', $context['verificiation_image_href'], ';letter=1" alt="', $txt['visual_verification_description'], '" id="verificiation_image_1" />
<img src="', $context['verificiation_image_href'], ';letter=2" alt="', $txt['visual_verification_description'], '" id="verificiation_image_2" />
<img src="', $context['verificiation_image_href'], ';letter=3" alt="', $txt['visual_verification_description'], '" id="verificiation_image_3" />
<img src="', $context['verificiation_image_href'], ';letter=4" alt="', $txt['visual_verification_description'], '" id="verificiation_image_4" />
<img src="', $context['verificiation_image_href'], ';letter=5" alt="', $txt['visual_verification_description'], '" id="verificiation_image_5" />';
echo '
<input type="text" name="visual_verification_code" size="30" tabindex="', $context['tabindex']++, '" />
<div class="smalltext">
<a href="', $context['verificiation_image_href'], ';sound" onclick="return reqWin(this.href, 400, 120);">', $txt['visual_verification_sound'], '</a>
<br />

// <<<<<<<<<<<< end insert

Note: I took out the "request another image", which only works in IE anyway.

In Sources/Post.php

1) load in the language file we need that contains the text "type in letters you see in picture..." etc

loadLanguage('Login'); //<<<<<<<< add this line, need this file for the descriptive text

2) generate the captcha and stick it in the session variable

cache_put_data('response_prefix', $context['response_prefix'], 600);

//begin insert >>>>>>>>>>>>>
// Generate a visual verification code to make sure the user is no bot.
$context['visual_verification'] = $user_info['is_guest'] && empty($modSettings['disable_visual_verification']);

if ($context['visual_verification'])
$context['use_graphic_library'] = in_array('gd', get_loaded_extensions());
$context['verificiation_image_href'] = $scripturl . '?action=verificationcode;rand=' . md5(rand());

// HINT: comment out the if below if you want to generate a new image when user clicks refresh
if (!isset($_SESSION['visual_verification_code']))
// Skip I, J, L, O and Q.
$character_range = array_merge(range('A', 'H'), array('K', 'M', 'N', 'P'), range('R', 'Z'));

// Generate a new code.
$_SESSION['visual_verification_code'] = '';
for ($i = 0; $i < 5; $i++)
$_SESSION['visual_verification_code'] .= $character_range[array_rand($character_range)];
// <<<<<<<< end insert

// Previewing, modifying, or posting?
if (isset($_REQUEST['message']) || !empty($context['post_error']))

3) verify that the user typed it in right

// Now make sure this email address is not banned from posting.
isBannedEmail($_POST['email'], 'cannot_post', sprintf($txt['you_are_post_banned'], $txt[28]));

// begin insert >>>>>>>>>>>>>>>>
if ($user_info['is_guest'] && empty($modSettings['disable_visual_verification']) && (empty($_REQUEST['visual_verification_code']) || strtoupper($_REQUEST['visual_verification_code']) !== $_SESSION['visual_verification_code']))
$post_errors[] = 'visual_verification_failed';
// <<<<<<<<<<<<<< end insert

Lastly add this txt to the language file Errors.english.php.  Substitute english for the appropriate language

$txt['error_visual_verification_failed'] = 'The verification code you entered did not match the code in the picture.';

Doesn't matter where you put; maybe place it with the other $txt['error_XXXXXX']

as usual, YMMV, use at your own risk etc :)

EDIT: in step 3), I added $user_info['is_guest'] to the if() condition.  Otherwise, it'll try to do a visual verification check when an admin or moderator tries to edit the post, which of course will fail.