(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 '
<tr>
<td align="right">
<b>', $txt['visual_verification_label'], ':</b>
<div class="smalltext">', $txt['visual_verification_description'], '</div>
</td>
<td>';
if ($context['use_graphic_library'])
echo '
<img src="', $context['verificiation_image_href'], '" alt="', $txt['visual_verification_description'], '" id="verificiation_image" /><br />';
else
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>
</div>
<br />
</td>
</tr>';
}
// <<<<<<<<<<<< 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
loadLanguage('Post');
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.