From 8258853051dd1de70390c44cb43027603f3a45fe Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Fri, 27 Jan 2006 01:53:10 +0000 Subject: [PATCH] committing progress so i don't forget to save changes this month * add some semi-useful help text * fix tab order when the captcha form comes up * work with more than 16 image files *cough* --- ConfirmEdit.php | 45 +++++++++++++++++++++++++-------- FancyCaptcha.php | 66 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 83 insertions(+), 28 deletions(-) diff --git a/ConfirmEdit.php b/ConfirmEdit.php index ffb4abd51..772c65eb3 100644 --- a/ConfirmEdit.php +++ b/ConfirmEdit.php @@ -38,9 +38,32 @@ $ceAllowConfirmedEmail = false; */ function ceSetup() { global $wgMessageCache, $wgHooks, $wgCaptcha, $wgCaptchaClass; - $wgMessageCache->addMessage('captcha-short', "Your edit includes new URL links; as a protection - against automated spam, you'll need to enter the answer to this - simple arithmetic test:" ); + $wgMessageCache->addMessages( array( + 'captcha-short' => + "Your edit includes new URL links; as a protection against automated " . + "spam, you'll need to type in the words that appear in this image:\n" . + "
([[Special:Captcha/help|What is this?]])", + 'captchahelp-title' => + 'Captcha help', + 'captchahelp-text' => + "Web sites that accept postings from the public, like this wiki, " . + "are often abused by spammers who use automated tools to post their " . + "links to many sites. While these spam links can be removed, they " . + "are a significant nuisance." . + "\n\n" . + "Sometimes, especially when adding new web links to a page, " . + "the wiki may show you an image of colored or distorted text and " . + "ask you to type the words shown. Since this is a task that's hard " . + "to automate, it will allow most real humans to make their posts " . + "while stopping most spammers and other robotic attackers." . + "\n\n" . + "Unfortunately this may inconvenience users with limited vision or " . + "using text-based or speech-based browsers. At the moment we do not " . + "have an audio alternative available. Please contact the site " . + "administrators for assistance if this is unexpectedly preventing " . + "you from making legitimate posts." . + "\n\n" . + "Hit the 'back' button in your browser to return to the page editor." ) ); SpecialPage::addPage( new SpecialPage( 'Captcha', false, /*listed*/ false, /*function*/ false, /*file*/ false ) ); @@ -102,7 +125,12 @@ class SimpleCaptcha { $numLinks = count( $addedLinks ); if( $numLinks > 0 ) { - wfDebug( "SimpleCaptcha: found $numLinks new links; triggered...\n" ); + global $wgUser, $wgTitle; + wfDebugLog( "captcha", sprintf( "ConfirmEdit: %dx url trigger by %s at [[%s]]: %s", + $numLinks, + $wgUser->getName(), + $wgTitle->getPrefixedText(), + implode( ", ", $addedLinks ) ) ); return true; } } @@ -182,13 +210,8 @@ END function showHelp() { global $wgOut, $ceAllowConfirmedEmail; - $wgOut->setPageTitle( 'Captcha help' ); - $wgOut->addWikiText( <<setPageTitle( wfMsg( 'captchahelp-title' ) ); + $wgOut->addWikiText( wfMsg( 'captchahelp-text' ) ); } } diff --git a/FancyCaptcha.php b/FancyCaptcha.php index 7cacd23ca..ec867e873 100644 --- a/FancyCaptcha.php +++ b/FancyCaptcha.php @@ -18,9 +18,9 @@ class FancyCaptcha extends SimpleCaptcha { return false; } - $var = $_SESSION['ceAnswerVar']; - $salt = $_SESSION['captchaSalt']; - $hash = $_SESSION['captchaHash']; + $var = @$_SESSION['ceAnswerVar']; + $salt = @$_SESSION['captchaSalt']; + $hash = @$_SESSION['captchaHash']; $answer = $wgRequest->getVal( $var ); $digest = $wgCaptchaSecret . $salt . $answer . $wgCaptchaSecret . $salt; @@ -35,12 +35,15 @@ class FancyCaptcha extends SimpleCaptcha { } } + /** + * Insert the captcha prompt into the edit form. + */ function formCallback( &$out ) { $dest = 'wpCaptchaWord' . mt_rand(); $img = $this->pickImage(); if( !$img ) { - die( 'aaargh' ); + die( "out of captcha images; this shouldn't happen" ); } $_SESSION['ceAnswerVar'] = $dest; @@ -50,37 +53,66 @@ class FancyCaptcha extends SimpleCaptcha { wfDebug( "Picked captcha with hash ${img['hash']}, salt ${img['salt']}.\n" ); $title = Title::makeTitle( NS_SPECIAL, 'Captcha/image' ); - $url = $title->getLocalUrl(); - $out->addWikiText( wfMsg( "captcha-short" ) ); - $out->addHTML( <<Oh noes

-

-END - ); + $out->addHTML( "

" . + wfElement( 'img', array( + 'src' => $title->getLocalUrl(), + 'width' => $img['width'], + 'height' => $img['height'], + 'alt' => '' ) ) . + "

\n" . + "

" ); } + /** + * Select a previously generated captcha image from the queue. + * @fixme subject to race conditions if lots of files vanish + * @return mixed tuple of (salt key, text hash) or false if no image to find + */ function pickImage() { global $wgCaptchaDirectory; + $pick = mt_rand( 0, $this->countFiles( $wgCaptchaDirectory ) ); $dir = opendir( $wgCaptchaDirectory ); $n = mt_rand( 0, 16 ); $count = 0; $entry = readdir( $dir ); + $pick = false; while( false !== $entry ) { $entry = readdir( $dir ); if( preg_match( '/^image_([0-9a-f]+)_([0-9a-f]+)\\.png$/', $entry, $matches ) ) { - if( $count++ % 16 == $n ) { - return array( - 'salt' => $matches[1], - 'hash' => $matches[2], - ); + $size = getimagesize( "$wgCaptchaDirectory/$entry" ); + $pick = array( + 'salt' => $matches[1], + 'hash' => $matches[2], + 'width' => $size[0], + 'height' => $size[1] + ); + if( $count++ == $n ) { + break; } } } - return false; + closedir( $dir ); + return $pick; + } + + /** + * Count the number of files in a directory. + * @return int + */ + function countFiles( $dirname ) { + $dir = opendir( $dirname ); + $count = 0; + while( false !== ($entry = readdir( $dir ) ) ) { + if( $dir != '.' && $dir != '..' ) { + $count++; + } + } + closedir( $dir ); + return $count; } function showImage() {