[ Index ] |
MailPress 7.1 |
[ Index ] [ Classes ] [ Functions ] [ Variables ] [ Constants ] [ Statistics ] |
[Summary view] [Print] [Text view]
1 <?php 2 if ( !extension_loaded( 'gd' ) ) return; 3 4 /** 5 * From an original idea of : 6 * 7 * @author Jose Rodriguez <jose.rodriguez@exec.cl> 8 * @license GPLv3 9 * @link http://code.google.com/p/cool-php-captcha 10 * @package captcha 11 * @version 0.3 12 * 13 */ 14 15 class MP_Form_field_type_captcha_gd2_googlelike 16 { 17 public $width = 200; /** Width of the image */ 18 public $height = 70; /** Height of the image */ 19 public $minWordLength = 5; /** Min word length ( for non-dictionary random text generation ) */ 20 /** 21 * Max word length ( for non-dictionary random text generation ) 22 * 23 * Used for dictionary words indicating the word-length 24 * for font-size modification purposes 25 */ 26 public $maxWordLength = 8; 27 public $session_var = 'mp_googlelike'; /** Sessionname to store the original text */ 28 public $backgroundColor = array( 255, 255, 255 ); /** Background color in RGB-array */ 29 public $colors = array( array( 27,78,181 )/*blue*/, array( 22,163,35 )/*green*/, array( 214,36,7 ) /*red*/ ); /** Foreground colors in RGB-array */ 30 public $shadowColor = null; //array( 0, 0, 0 ); /** Shadow color in RGB-array or null */ 31 32 public $fonts = array( 33 'Antykwa' => array( 'spacing' => -3, 'minSize' => 27, 'maxSize' => 30, 'font' => 'AntykwaBold.ttf' ), // 34 'Candice' => array( 'spacing' =>-1.5,'minSize' => 28, 'maxSize' => 31, 'font' => 'Candice.ttf' ), // Font configuration 35 'DingDong' => array( 'spacing' => -2, 'minSize' => 24, 'maxSize' => 30, 'font' => 'Ding-DongDaddyO.ttf' ), // - font: TTF file 36 'Duality' => array( 'spacing' => -2, 'minSize' => 30, 'maxSize' => 38, 'font' => 'Duality.ttf' ), // - spacing: relative pixel space between character 37 'Heineken' => array( 'spacing' => -2, 'minSize' => 24, 'maxSize' => 34, 'font' => 'Heineken.ttf' ), // - minSize: min font size 38 'Jura' => array( 'spacing' => -2, 'minSize' => 28, 'maxSize' => 32, 'font' => 'Jura.ttf' ), // - maxSize: max font size 39 'StayPuft' => array( 'spacing' =>-1.5,'minSize' => 28, 'maxSize' => 32, 'font' => 'StayPuft.ttf' ), 40 'VeraSans' => array( 'spacing' => -1, 'minSize' => 20, 'maxSize' => 28, 'font' => 'VeraSansBold.ttf' ), 41 'VeraSeBd' => array( 'spacing' => -2, 'minSize' => 24, 'maxSize' => 30, 'font' => 'VeraSeBd.ttf' ), 42 ); 43 44 public $Yperiod = 12; /** Wave configuracion in X and Y axes */ 45 public $Yamplitude = 14; 46 public $Xperiod = 11; 47 public $Xamplitude = 5; 48 49 public $maxRotation = 8; /** letter rotation clockwise */ 50 51 /** 52 * Internal image size factor ( for better image quality ) 53 * 1: low, 2: medium, 3: high 54 */ 55 public $scale = 2; 56 57 /** 58 * Blur effect for better image quality ( but slower image processing ). 59 * Better image results with scale=3 60 */ 61 public $blur = false; 62 63 /** Debug? */ 64 public $debug = false; 65 66 /** Image format: jpeg or png */ 67 public $imageFormat = 'png'; 68 69 70 /** GD image */ 71 public $im; 72 73 function __construct() 74 { 75 session_start(); 76 77 $root = __DIR__ . '/words/'; 78 if ( is_dir( $root ) ) 79 { 80 $dir = @opendir( $root ); 81 if ( $dir ) while ( ( $file = readdir( $dir ) ) !== false ) if ( ( $file{0} != '.' ) && ( substr( $file, -4 ) == '.php' ) ) $xlangs[] = strtolower( substr( $file, 0, -4 ) ); 82 @closedir( $dir ); 83 } 84 85 $lang = $xlangs[array_rand( $xlangs )]; 86 87 $HTTP_ACCEPT_LANGUAGE = filter_input( INPUT_SERVER, 'HTTP_ACCEPT_LANGUAGE' ); 88 if ( !empty( $HTTP_ACCEPT_LANGUAGE ) ) 89 { 90 $lang_http = substr( $HTTP_ACCEPT_LANGUAGE, 0, 2 ); 91 if ( in_array( $lang_http, $xlangs ) ) $lang = $lang_http; 92 } 93 $this->wordsFile = $root . "$lang.php"; 94 95 $this->CreateImage(); 96 97 ob_end_clean(); 98 if ( $this->imageFormat == 'png' && function_exists( 'imagepng' ) ) 99 { 100 header( 'Content-type: image/png' ); 101 imagepng( $this->im ); 102 } else { 103 header( 'Content-type: image/jpeg' ); 104 imagejpeg( $this->im, null, 80 ); 105 } 106 imagedestroy ( $this->im ); 107 die(); 108 } 109 110 public function CreateImage() { 111 $ini = microtime( true ); 112 113 /** Initialization */ 114 $this->ImageAllocate(); 115 116 /** Text insertion */ 117 $text = $this->GetCaptchaText(); 118 119 $fontcfg = $this->fonts[array_rand( $this->fonts )]; 120 $this->WriteText( $text, $fontcfg ); 121 122 $_SESSION[$this->session_var] = $text; 123 124 /** Transformations */ 125 $this->WaveImage(); 126 if ( $this->blur && function_exists( 'imagefilter' ) ) imagefilter( $this->im, IMG_FILTER_GAUSSIAN_BLUR ); 127 $this->ReduceImage(); 128 129 if ( $this->debug ) imagestring( $this->im, 1, 1, $this->height-8, "$text {$fontcfg['font']} ".round( ( microtime( true )-$ini )*1000 )."ms", $this->GdFgColor ); 130 } 131 132 /** 133 * Creates the image resources 134 */ 135 protected function ImageAllocate() 136 { 137 // Cleanup 138 if ( !empty( $this->im ) ) imagedestroy( $this->im ); 139 140 $this->im = imagecreatetruecolor( $this->width*$this->scale, $this->height*$this->scale ); 141 142 // Background color 143 $this->GdBgColor = imagecolorallocate( $this->im, $this->backgroundColor[0], $this->backgroundColor[1], $this->backgroundColor[2] ); 144 imagefilledrectangle( $this->im, 0, 0, $this->width*$this->scale, $this->height*$this->scale, $this->GdBgColor ); 145 146 // Foreground color 147 $color = $this->colors[mt_rand( 0, sizeof( $this->colors )-1 )]; 148 $this->GdFgColor = imagecolorallocate( $this->im, $color[0], $color[1], $color[2] ); 149 150 // Shadow color 151 if ( !empty( $this->shadowColor ) && is_array( $this->shadowColor ) && sizeof( $this->shadowColor ) >= 3 ) $this->GdShadowColor = imagecolorallocate( $this->im, $this->shadowColor[0], $this->shadowColor[1], $this->shadowColor[2] ); 152 } 153 154 /** 155 * Text generation 156 * 157 * @return string Text 158 */ 159 protected function GetCaptchaText() 160 { 161 $text = $this->GetDictionaryCaptchaText(); 162 if ( !$text ) $text = $this->GetRandomCaptchaText(); 163 return $text; 164 } 165 166 /** 167 * Random dictionary word generation 168 * 169 * @param boolean $extended Add extended "fake" words 170 * @return string Word 171 */ 172 function GetDictionaryCaptchaText( $extended = false ) 173 { 174 if ( empty( $this->wordsFile ) ) return false; 175 176 $fp = fopen( $this->wordsFile, "r" ); 177 $length = strlen( fgets( $fp ) ); 178 if ( !$length ) return false; 179 180 $line = rand( 1, ( filesize( $this->wordsFile )/$length )-2 ); 181 if ( fseek( $fp, $length*$line ) == -1 ) return false; 182 183 $text = trim( fgets( $fp ) ); 184 fclose( $fp ); 185 186 /** Change ramdom volcals */ 187 if ( $extended ) 188 { 189 $text = preg_split( '//', $text, -1, PREG_SPLIT_NO_EMPTY ); 190 $vocals = array( 'a', 'e', 'i', 'o', 'u' ); 191 foreach ( $text as $i => $char ) if ( mt_rand( 0, 1 ) && in_array( $char, $vocals ) ) $text[$i] = $vocals[mt_rand( 0, 4 )]; 192 $text = implode( '', $text ); 193 } 194 return $text; 195 } 196 197 /** 198 * Random text generation 199 * 200 * @return string Text 201 */ 202 protected function GetRandomCaptchaText( $length = null ) 203 { 204 if ( empty( $length ) ) $length = rand( $this->minWordLength, $this->maxWordLength ); 205 $words = "abcdefghijlmnopqrstvwyz"; 206 $vocals = "aeiou"; 207 $text = ""; 208 $vocal = rand( 0, 1 ); 209 for ( $i = 0; $i < $length; $i++ ) 210 { 211 $text .= ( $vocal ) ? substr( $vocals, mt_rand( 0, 4 ), 1 ) : substr( $words, mt_rand( 0, 22 ), 1 ); 212 $vocal = !$vocal; 213 } 214 return $text; 215 } 216 217 /** 218 * Text insertion 219 */ 220 protected function WriteText( $text, $fontcfg = array() ) 221 { 222 // Select the font configuration 223 if ( empty( $fontcfg ) ) $fontcfg = $this->fonts[array_rand( $this->fonts )]; 224 225 // Full path of font file 226 $fontfile = __DIR__ . '/fonts/' . $fontcfg['font']; 227 /** 228 * Increase font-size for shortest words: 9% for each glyp missing */ 229 $lettersMissing = $this->maxWordLength-strlen( $text ); 230 $fontSizefactor = 1+( $lettersMissing*0.09 ); 231 232 // Text generation ( char by char ) 233 $x = 20*$this->scale; 234 $y = round( ( $this->height*27/40 )*$this->scale ); 235 $length = strlen( $text ); 236 for ( $i = 0; $i < $length; $i++ ) 237 { 238 $degree = rand( $this->maxRotation*-1, $this->maxRotation ); 239 $fontsize = rand( $fontcfg['minSize'], $fontcfg['maxSize'] )*$this->scale*$fontSizefactor; 240 $letter = substr( $text, $i, 1 ); 241 242 if ( $this->shadowColor ) $coords = imagettftext( $this->im, $fontsize, $degree, $x+$this->scale, $y+$this->scale, $this->GdShadowColor, $fontfile, $letter ); 243 $coords = imagettftext( $this->im, $fontsize, $degree, $x, $y, $this->GdFgColor, $fontfile, $letter ); 244 $x += ( $coords[2]-$x ) + ( $fontcfg['spacing']*$this->scale ); 245 } 246 } 247 248 /** 249 * Wave filter 250 */ 251 protected function WaveImage() 252 { 253 // X-axis wave generation 254 $xp = $this->scale*$this->Xperiod*rand( 1,3 ); 255 $k = rand( 0, 100 ); 256 for ( $i = 0; $i < ( $this->width*$this->scale ); $i++ ) imagecopy( $this->im, $this->im, $i-1, sin( $k+$i/$xp ) * ( $this->scale*$this->Xamplitude ), $i, 0, 1, $this->height*$this->scale ); 257 258 // Y-axis wave generation 259 $k = rand( 0, 100 ); 260 $yp = $this->scale*$this->Yperiod*rand( 1,2 ); 261 for ( $i = 0; $i < ( $this->height*$this->scale ); $i++ ) imagecopy( $this->im, $this->im, sin( $k+$i/$yp ) * ( $this->scale*$this->Yamplitude ), $i-1, 0, $i, $this->width*$this->scale, 1 ); 262 } 263 264 /** 265 * Reduce the image to the final size 266 */ 267 protected function ReduceImage() 268 { 269 $imResampled = imagecreatetruecolor( $this->width, $this->height ); 270 imagecopyresampled( $imResampled, $this->im, 0, 0, 0, 0, $this->width, $this->height, $this->width*$this->scale, $this->height*$this->scale ); 271 imagedestroy( $this->im ); 272 $this->im = $imResampled; 273 } 274 } 275 new MP_Form_field_type_captcha_gd2_googlelike();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Mar 11 18:33:33 2019 | Cross-referenced by PHPXref 0.7.1 |