-function wfSpecialCaptcha( $par = null ) {
- global $wgCaptcha;
- switch( $par ) {
- case "image":
- return $wgCaptcha->showImage();
- case "help":
- default:
- return $wgCaptcha->showHelp();
- }
-}
-
-class SimpleCaptcha {
- /**
- * Insert a captcha prompt into the edit form.
- * This sample implementation generates a simple arithmetic operation;
- * it would be easy to defeat by machine.
- *
- * Override this!
- *
- * @param OutputPage $out
- */
- function formCallback( &$out ) {
- $a = mt_rand(0, 100);
- $b = mt_rand(0, 10);
- $op = mt_rand(0, 1) ? '+' : '-';
-
- $test = "$a $op $b";
- $answer = ($op == '+') ? ($a + $b) : ($a - $b);
-
- $index = $this->storeCaptcha( array( 'answer' => $answer ) );
-
- $out->addWikiText( wfMsg( "captcha-short" ) );
- $out->addHTML( "<p><label for=\"wpCaptchaWord\">$test</label> = " .
- wfElement( 'input', array(
- 'name' => 'wpCaptchaWord',
- 'id' => 'wpCaptchaWord',
- 'tabindex' => 1 ) ) . // tab in before the edit textarea
- "</p>\n" .
- wfElement( 'input', array(
- 'type' => 'hidden',
- 'name' => 'wpCaptchaId',
- 'id' => 'wpCaptchaId',
- 'value' => $index ) ) );
- }
-
- /**
- * Check if the submitted form matches the captcha session data provided
- * by the plugin when the form was generated.
- *
- * Override this!
- *
- * @param WebRequest $request
- * @param array $info
- * @return bool
- */
- function keyMatch( $request, $info ) {
- return $request->getVal( 'wpCaptchaWord' ) == $info['answer'];
- }
-
- // ----------------------------------
-
- /**
- * @param EditPage $editPage
- * @param string $newtext
- * @param string $section
- * @return bool true if the captcha should run
- */
- function shouldCheck( &$editPage, $newtext, $section ) {
- global $wgUser;
- if( $wgUser->isAllowed( 'skipcaptcha' ) ) {
- wfDebug( "ConfirmEdit: user group allows skipping captcha\n" );
- return false;
- }
-
- global $wgEmailAuthentication, $ceAllowConfirmedEmail;
- if( $wgEmailAuthentication && $ceAllowConfirmedEmail &&
- $wgUser->isEmailConfirmed() ) {
- wfDebug( "ConfirmEdit: user has confirmed mail, skipping captcha\n" );
- return false;
- }
-
- global $wgCaptchaTriggers;
- if( !empty( $wgCaptchaTriggers['edit'] ) ) {
- // Check on all edits
- wfDebug( "ConfirmEdit: checking all edits...\n" );
- return true;
- }
-
- if( !empty( $wgCaptchaTriggers['addurl'] ) ) {
- // Only check edits that add URLs
- $oldtext = $this->loadText( $editPage, $section );
-
- $oldLinks = $this->findLinks( $oldtext );
- $newLinks = $this->findLinks( $newtext );
- $unknownLinks = array_filter( $newLinks, array( &$this, 'filterLink' ) );
-
- $addedLinks = array_diff( $unknownLinks, $oldLinks );
- $numLinks = count( $addedLinks );
-
- if( $numLinks > 0 ) {
- global $wgUser, $wgTitle;
- wfDebugLog( "captcha", sprintf( "ConfirmEdit: %dx url trigger by %s at [[%s]]: %s",
- $numLinks,
- $wgUser->getName(),
- $wgTitle->getPrefixedText(),
- implode( ", ", $addedLinks ) ) );
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Filter callback function for URL whitelisting
- * @return bool true if unknown, false if whitelisted
- * @access private
- */
- function filterLink( $url ) {
- global $wgCaptchaWhitelist;
- return !( $wgCaptchaWhitelist && preg_match( $wgCaptchaWhitelist, $url ) );
- }
-
- /**
- * The main callback run on edit attempts.
- * @param EditPage $editPage
- * @param string $newtext
- * @param string $section
- * @param bool true to continue saving, false to abort and show a captcha form
- */
- function confirmEdit( &$editPage, $newtext, $section ) {
- if( $this->shouldCheck( $editPage, $newtext, $section ) ) {
- $info = $this->retrieveCaptcha();
- if( $info ) {
- global $wgRequest;
- if( $this->keyMatch( $wgRequest, $info ) ) {
- wfDebug( "ConfirmEdit given proper key from form, passing.\n" );
- return true;
- } else {
- wfDebug( "ConfirmEdit missing form key, prompting.\n" );
- }
- } else {
- wfDebug( "ConfirmEdit: no session captcha key set, this is new visitor.\n" );
- }
- $editPage->showEditForm( array( &$this, 'formCallback' ) );
- return false;
- } else {
- wfDebug( "ConfirmEdit: no new links.\n" );
- return true;
- }
- }
-
- /**
- * Generate a captcha session ID and save the info in PHP's session storage.
- * (Requires the user to have cookies enabled to get through the captcha.)
- *
- * A random ID is used so legit users can make edits in multiple tabs or
- * windows without being unnecessarily hobbled by a serial order requirement.
- * Pass the returned id value into the edit form as wpCaptchaId.
- *
- * @param array $info data to store
- * @param string $index optional, to overwrite used session
- * @return string captcha ID key
- */
- function storeCaptcha( $info, $index=null ) {
- if( is_null( $index ) ) {
- $index = strval( mt_rand() );
- $info['index'] = $index;
- }
- $_SESSION['captcha' . $index] = $info;
- return $index;