Extensions too!
[toast/cookiecaptcha.git] / FancyCaptcha.php
index c3f2942f4c9722076299bc782f3bfe0fbfbc05f1..f4ce034653b10da44247f24335a0399aa34410d9 100644 (file)
@@ -29,6 +29,9 @@ if ( defined( 'MEDIAWIKI' ) ) {
 global $wgCaptchaDirectory;
 $wgCaptchaDirectory = "$wgUploadDirectory/captcha"; // bad default :D
 
+global $wgCaptchaDirectoryLevels;
+$wgCaptchaDirectoryLevels = 0; // To break into subdirectories
+
 global $wgCaptchaSecret;
 $wgCaptchaSecret = "CHANGE_THIS_SECRET!";
 
@@ -110,9 +113,48 @@ class FancyCaptcha extends SimpleCaptcha {
         * @return mixed tuple of (salt key, text hash) or false if no image to find
         */
        function pickImage() {
-               global $wgCaptchaDirectory;
-               $n = mt_rand( 0, $this->countFiles( $wgCaptchaDirectory ) );
-               $dir = opendir( $wgCaptchaDirectory );
+               global $wgCaptchaDirectory, $wgCaptchaDirectoryLevels;
+               return $this->pickImageDir(
+                       $wgCaptchaDirectory,
+                       $wgCaptchaDirectoryLevels );
+       }
+       
+       function pickImageDir( $directory, $levels ) {
+               if( $levels ) {
+                       $dirs = array();
+                       
+                       // Check which subdirs are actually present...
+                       $dir = opendir( $directory );
+                       while( false !== ($entry = readdir( $dir ) ) ) {
+                               if( ctype_xdigit( $entry ) && strlen( $entry ) == 1 ) {
+                                       $dirs[] = $entry;
+                               }
+                       }
+                       closedir( $dir );
+                       
+                       $place = mt_rand( 0, count( $dirs ) - 1 );
+                       // In case all dirs are not filled,
+                       // cycle through next digits...
+                       for( $j = 0; $j < count( $dirs ); $j++ ) {
+                               $char = $dirs[($place + $j) % count( $dirs )];
+                               $return = $this->pickImageDir( "$directory/$char", $levels - 1 );
+                               if( $return ) {
+                                       return $return;
+                               }
+                       }
+                       // Didn't find any images in this directory... empty?
+                       return false;
+               } else {
+                       return $this->pickImageFromDir( $directory );
+               }
+       }
+       
+       function pickImageFromDir( $directory ) {
+               if( !is_dir( $directory ) ) {
+                       return false;
+               }
+               $n = mt_rand( 0, $this->countFiles( $directory ) - 1 );
+               $dir = opendir( $directory );
 
                $count = 0;
 
@@ -121,7 +163,7 @@ class FancyCaptcha extends SimpleCaptcha {
                while( false !== $entry ) {
                        $entry = readdir( $dir );
                        if( preg_match( '/^image_([0-9a-f]+)_([0-9a-f]+)\\.png$/', $entry, $matches ) ) {
-                               $size = getimagesize( "$wgCaptchaDirectory/$entry" );
+                               $size = getimagesize( "$directory/$entry" );
                                $pick = array(
                                        'salt' => $matches[1],
                                        'hash' => $matches[2],
@@ -146,7 +188,7 @@ class FancyCaptcha extends SimpleCaptcha {
                $dir = opendir( $dirname );
                $count = 0;
                while( false !== ($entry = readdir( $dir ) ) ) {
-                       if( $dir != '.' && $dir != '..' ) {
+                       if( $entry != '.' && $entry != '..' ) {
                                $count++;
                        }
                }
@@ -156,7 +198,6 @@ class FancyCaptcha extends SimpleCaptcha {
 
        function showImage() {
                global $wgOut, $wgRequest;
-               global $wgCaptchaDirectory;
 
                $wgOut->disable();
 
@@ -172,17 +213,30 @@ class FancyCaptcha extends SimpleCaptcha {
 
                        $salt = $info['salt'];
                        $hash = $info['hash'];
-                       $file = $wgCaptchaDirectory . DIRECTORY_SEPARATOR . "image_{$salt}_{$hash}.png";
+                       $file = $this->imagePath( $salt, $hash );
 
                        if( file_exists( $file ) ) {
-                               header( 'Content-type: image/png' );
-                               readfile( $file );
+                               global $IP;
+                               require_once "$IP/includes/StreamFile.php";
+                               wfStreamFile( $file );
                                return true;
                        }
                }
                wfHttpError( 500, 'Internal Error', 'Requested bogus captcha image' );
                return false;
        }
+       
+       function imagePath( $salt, $hash ) {
+               global $wgCaptchaDirectory, $wgCaptchaDirectoryLevels;
+               $file = $wgCaptchaDirectory;
+               $file .= DIRECTORY_SEPARATOR;
+               for( $i = 0; $i < $wgCaptchaDirectoryLevels; $i++ ) {
+                       $file .= $hash{$i};
+                       $file .= DIRECTORY_SEPARATOR;
+               }
+               $file .= "image_{$salt}_{$hash}.png";
+               return $file;
+       }
 
        /**
         * Show a message asking the user to enter a captcha on edit
@@ -203,4 +257,4 @@ class FancyCaptcha extends SimpleCaptcha {
 
 } # End invocation guard
 
-?>
+