| 1 |
<?php |
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
class sfCryptoCaptcha |
|---|
| 15 |
{ |
|---|
| 16 |
|
|---|
| 17 |
private $config = array(); |
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
private $image; |
|---|
| 21 |
|
|---|
| 22 |
private $temp_image; |
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
private $captcha = array(); |
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
private $sf_user; |
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
public function __construct($test_queries_flood=true) |
|---|
| 32 |
{ |
|---|
| 33 |
$this->getConfiguration(); |
|---|
| 34 |
|
|---|
| 35 |
|
|---|
| 36 |
$user = sfContext::getInstance()->getUser(); |
|---|
| 37 |
|
|---|
| 38 |
$test_value = 'done'; |
|---|
| 39 |
$user->setAttribute('test',$test_value); |
|---|
| 40 |
|
|---|
| 41 |
if($user->getAttribute('test') == $test_value) |
|---|
| 42 |
{ |
|---|
| 43 |
|
|---|
| 44 |
$user->getAttributeHolder()->remove('test'); |
|---|
| 45 |
$this->sf_user = $user; |
|---|
| 46 |
|
|---|
| 47 |
if($test_queries_flood == true) |
|---|
| 48 |
{ |
|---|
| 49 |
|
|---|
| 50 |
if($this->testQueries() && $this->testLastRequest()) |
|---|
| 51 |
{ |
|---|
| 52 |
|
|---|
| 53 |
$this->config['constructor_test'] = true; |
|---|
| 54 |
return true; |
|---|
| 55 |
} |
|---|
| 56 |
else |
|---|
| 57 |
{ |
|---|
| 58 |
$this->config['constructor_test'] = false; |
|---|
| 59 |
if(!$this->testQueries()) { |
|---|
| 60 |
$this->config['constructor_error_reason'] = 'Error - too many queries'; |
|---|
| 61 |
$this->config['constructor_error_message'] = 'too_many'; |
|---|
| 62 |
} |
|---|
| 63 |
elseif(!$this->testLastRequest()) |
|---|
| 64 |
{ |
|---|
| 65 |
$this->config['constructor_error_reason'] = 'Error - refreshing too fast'; |
|---|
| 66 |
$this->config['constructor_error_message'] = 'refresh'; |
|---|
| 67 |
} |
|---|
| 68 |
else |
|---|
| 69 |
{ |
|---|
| 70 |
$this->config['constructor_error_reason'] = 'Error - unknown reason'; |
|---|
| 71 |
$this->config['constructor_error_message'] = 'unknown'; |
|---|
| 72 |
} |
|---|
| 73 |
return false; |
|---|
| 74 |
} |
|---|
| 75 |
} |
|---|
| 76 |
else |
|---|
| 77 |
{ |
|---|
| 78 |
|
|---|
| 79 |
$this->config['constructor_test']= true; |
|---|
| 80 |
return true; |
|---|
| 81 |
} |
|---|
| 82 |
} |
|---|
| 83 |
} |
|---|
| 84 |
|
|---|
| 85 |
|
|---|
| 86 |
* Tests the number of queries done |
|---|
| 87 |
* |
|---|
| 88 |
* Tests the number of queries done by the user |
|---|
| 89 |
* to block flood attempts |
|---|
| 90 |
* |
|---|
| 91 |
* @return bool Ok if the number of queries is under the limit per session |
|---|
| 92 |
*/ |
|---|
| 93 |
private function testQueries() |
|---|
| 94 |
{ |
|---|
| 95 |
if($this->sf_user->getAttribute('queries', null, 'captcha') == '' || $this->sf_user->getAttribute('queries', null, 'captcha') == 0) |
|---|
| 96 |
{ |
|---|
| 97 |
$this->sf_user->setAttribute('queries',1, 'captcha'); |
|---|
| 98 |
return true; |
|---|
| 99 |
} |
|---|
| 100 |
elseif($this->sf_user->getAttribute('queries', null, 'captcha') >= $this->config['max_refresh']) |
|---|
| 101 |
{ |
|---|
| 102 |
return false; |
|---|
| 103 |
} |
|---|
| 104 |
else |
|---|
| 105 |
{ |
|---|
| 106 |
$this->sf_user->setAttribute('queries',$this->sf_user->getAttribute('queries', null, 'captcha')+1, 'captcha'); |
|---|
| 107 |
return true; |
|---|
| 108 |
} |
|---|
| 109 |
} |
|---|
| 110 |
|
|---|
| 111 |
|
|---|
| 112 |
* Tests the last request time |
|---|
| 113 |
* |
|---|
| 114 |
* Tests the last request time done by the user to block |
|---|
| 115 |
* too fast refreshes |
|---|
| 116 |
* |
|---|
| 117 |
* @return bool Ok if the last request was not too soon from now |
|---|
| 118 |
*/ |
|---|
| 119 |
private function testLastRequest() |
|---|
| 120 |
{ |
|---|
| 121 |
if($this->sf_user->getAttribute('last_request', null, 'captcha') == '' || $this->sf_user->getAttribute('last_request', null, 'captcha') == 0) |
|---|
| 122 |
{ |
|---|
| 123 |
$this->sf_user->setAttribute('last_request',time(), 'captcha'); |
|---|
| 124 |
return true; |
|---|
| 125 |
} |
|---|
| 126 |
else |
|---|
| 127 |
{ |
|---|
| 128 |
$delay = time() - $this->sf_user->getAttribute('last_request', null, 'captcha'); |
|---|
| 129 |
if($this->config['flood_timer'] != 0 && $this->config['flood_timer'] > $delay) |
|---|
| 130 |
{ |
|---|
| 131 |
|
|---|
| 132 |
return false; |
|---|
| 133 |
} |
|---|
| 134 |
else |
|---|
| 135 |
{ |
|---|
| 136 |
$this->sf_user->setAttribute('last_request',time(), 'captcha'); |
|---|
| 137 |
return true; |
|---|
| 138 |
} |
|---|
| 139 |
} |
|---|
| 140 |
} |
|---|
| 141 |
|
|---|
| 142 |
|
|---|
| 143 |
* Generates the captcha image |
|---|
| 144 |
* |
|---|
| 145 |
* This function generates the captcha variables and |
|---|
| 146 |
* creates the image. |
|---|
| 147 |
* |
|---|
| 148 |
* @return resource Returns the image to the browser of the user |
|---|
| 149 |
*/ |
|---|
| 150 |
public function getCaptchaImage() |
|---|
| 151 |
{ |
|---|
| 152 |
if($this->config['constructor_test']===false) { |
|---|
| 153 |
|
|---|
| 154 |
if(!$this->sendErrorImage($this->config['constructor_error_message'])) |
|---|
| 155 |
{ |
|---|
| 156 |
if (sfConfig::get('sf_logging_enabled')) |
|---|
| 157 |
{ |
|---|
| 158 |
$message = '{sfCaptcha}'; |
|---|
| 159 |
$message .= ' - Critical Image Error - '; |
|---|
| 160 |
$message .= 'The ERROR message(['.$this->config['constructor_error_reason'].']) image could not be sent to the user.'; |
|---|
| 161 |
$message .= ' Possible problem with file access/path.'; |
|---|
| 162 |
sfContext::getInstance()->getLogger()->crit($message); |
|---|
| 163 |
} |
|---|
| 164 |
} |
|---|
| 165 |
elseif(!$this->generateErrorImage($this->config['constructor_error_reason'])) |
|---|
| 166 |
{ |
|---|
| 167 |
if (sfConfig::get('sf_logging_enabled')) |
|---|
| 168 |
{ |
|---|
| 169 |
$message = '{sfCaptcha}'; |
|---|
| 170 |
$message .= ' - Critical Image Error - '; |
|---|
| 171 |
$message .= 'The ERROR message(['.$this->config['constructor_error_reason'].']) image encoutered an error when sending to user.'; |
|---|
| 172 |
$message .= ' Possible problem with GD2 library.'; |
|---|
| 173 |
sfContext::getInstance()->getLogger()->crit($message); |
|---|
| 174 |
} |
|---|
| 175 |
} |
|---|
| 176 |
|
|---|
| 177 |
imagedestroy($this->image); |
|---|
| 178 |
|
|---|
| 179 |
$config = array(); |
|---|
| 180 |
$captcha = array(); |
|---|
| 181 |
$image = ''; |
|---|
| 182 |
$temp_image = ''; |
|---|
| 183 |
return true; |
|---|
| 184 |
} |
|---|
| 185 |
|
|---|
| 186 |
$this->generateCaptcha(); |
|---|
| 187 |
|
|---|
| 188 |
|
|---|
| 189 |
$this->adjustCaptcha(); |
|---|
| 190 |
|
|---|
| 191 |
|
|---|
| 192 |
imagedestroy ($this->temp_image); |
|---|
| 193 |
|
|---|
| 194 |
|
|---|
| 195 |
$this->selectBackground(); |
|---|
| 196 |
|
|---|
| 197 |
|
|---|
| 198 |
$this->createCaptchaImageAndBackground(); |
|---|
| 199 |
|
|---|
| 200 |
|
|---|
| 201 |
$this->setNoiseParameters(); |
|---|
| 202 |
if($this->config['noise_on_top']) |
|---|
| 203 |
{ |
|---|
| 204 |
$this->addLettersToImage(); |
|---|
| 205 |
$this->addNoiseToImage(); |
|---|
| 206 |
} |
|---|
| 207 |
else |
|---|
| 208 |
{ |
|---|
| 209 |
$this->addNoiseToImage(); |
|---|
| 210 |
$this->addLettersToImage(); |
|---|
| 211 |
} |
|---|
| 212 |
$this->clearBrush(); |
|---|
| 213 |
|
|---|
| 214 |
$this->addBorder(); |
|---|
| 215 |
$this->addEffect(); |
|---|
| 216 |
|
|---|
| 217 |
//set user attributes (word into session etc.) |
|---|
| 218 |
$this->setUserAttributes(); |
|---|
| 219 |
|
|---|
| 220 |
if(!$this->sendImageToBrowser()) |
|---|
| 221 |
{ |
|---|
| 222 |
if (sfConfig::get('sf_logging_enabled')) |
|---|
| 223 |
{ |
|---|
| 224 |
$message = '{seCaptcha}'; |
|---|
| 225 |
$message .= ' - Critical Image Error - '; |
|---|
| 226 |
$message .= 'The NORMAL image encoutered an error when sending to user.'; |
|---|
| 227 |
$message .= ' Possbile problem with GD2 library.'; |
|---|
| 228 |
sfContext::getInstance()->getLogger()->crit($message); |
|---|
| 229 |
} |
|---|
| 230 |
} |
|---|
| 231 |
|
|---|
| 232 |
|
|---|
| 233 |
|
|---|
| 234 |
imagedestroy($this->image); |
|---|
| 235 |
|
|---|
| 236 |
$config = array(); |
|---|
| 237 |
$captcha = array(); |
|---|
| 238 |
$image = ''; |
|---|
| 239 |
$temp_image = ''; |
|---|
| 240 |
|
|---|
| 241 |
return true; |
|---|
| 242 |
} |
|---|
| 243 |
|
|---|
| 244 |
|
|---|
| 245 |
* Tests the user's captcha |
|---|
| 246 |
* |
|---|
| 247 |
* Tests if the captcha given by the user is correct. |
|---|
| 248 |
* |
|---|
| 249 |
* @return bool Ok if the captcha is correct |
|---|
| 250 |
*/ |
|---|
| 251 |
public function testCaptcha($input) |
|---|
| 252 |
{ |
|---|
| 253 |
if(!$this->config['case_sensitive']) |
|---|
| 254 |
{ |
|---|
| 255 |
$input = strtoupper($input); |
|---|
| 256 |
} |
|---|
| 257 |
|
|---|
| 258 |
|
|---|
| 259 |
if(empty($this->config['hash_algo'])) |
|---|
| 260 |
{ |
|---|
| 261 |
$input_hash = hash('sha1',$input); |
|---|
| 262 |
} |
|---|
| 263 |
else |
|---|
| 264 |
{ |
|---|
| 265 |
$input_hash = hash($this->config['hash_algo'],$input); |
|---|
| 266 |
} |
|---|
| 267 |
|
|---|
| 268 |
|
|---|
| 269 |
$saved_captcha = $this->sf_user->getAttribute('captcha_code', null, 'captcha'); |
|---|
| 270 |
if($input_hash == $saved_captcha) |
|---|
| 271 |
{ |
|---|
| 272 |
|
|---|
| 273 |
$this->clearUserCaptchaAttributes(); |
|---|
| 274 |
return true; |
|---|
| 275 |
} |
|---|
| 276 |
else |
|---|
| 277 |
{ |
|---|
| 278 |
|
|---|
| 279 |
return false; |
|---|
| 280 |
} |
|---|
| 281 |
} |
|---|
| 282 |
|
|---|
| 283 |
|
|---|
| 284 |
* Clears all the user captcha attributes (last_request, queries, ...) |
|---|
| 285 |
* |
|---|
| 286 |
* @return bool Always true |
|---|
| 287 |
*/ |
|---|
| 288 |
public function clearUserCaptchaAttributes() |
|---|
| 289 |
{ |
|---|
| 290 |
$this->sf_user->getAttributeHolder()->removeNamespace('captcha'); |
|---|
| 291 |
return true; |
|---|
| 292 |
} |
|---|
| 293 |
|
|---|
| 294 |
|
|---|
| 295 |
* Generates the captcha |
|---|
| 296 |
* |
|---|
| 297 |
* It generates the captcha atributes and other stuff |
|---|
| 298 |
* and saves it in the class $captcha attribute |
|---|
| 299 |
* |
|---|
| 300 |
* @return bool Ok if the captcha has been correctly generated. |
|---|
| 301 |
*/ |
|---|
| 302 |
private function generateCaptcha() |
|---|
| 303 |
{ |
|---|
| 304 |
$this->captcha['word'] = ''; |
|---|
| 305 |
$this->captcha['chars'] = rand($this->config['min_chars'],$this->config['max_chars']); |
|---|
| 306 |
|
|---|
| 307 |
$x_coord = 10; |
|---|
| 308 |
//generate the captcha |
|---|
| 309 |
for($i=1; $i<= $this->captcha['chars']; $i++) |
|---|
| 310 |
{ |
|---|
| 311 |
|
|---|
| 312 |
$this->captcha['letters'][$i]['font'] = $this->getRandomFont(); |
|---|
| 313 |
$this->captcha['letters'][$i]['font_path'] = $this->config['char_fonts_dir'].$this->captcha['letters'][$i]['font']; |
|---|
| 314 |
|
|---|
| 315 |
|
|---|
| 316 |
$this->captcha['letters'][$i]['ink_type'] = $this->getInkType(); |
|---|
| 317 |
$this->captcha['letters'][$i]['ink_colors'] = $this->getInkColors(); |
|---|
| 318 |
|
|---|
| 319 |
|
|---|
| 320 |
$this->captcha['letters'][$i]['rotation'] = $this->getRandomLetterRotation(); |
|---|
| 321 |
|
|---|
| 322 |
|
|---|
| 323 |
$this->captcha['letters'][$i]['char'] = $this->getRandomCharacter(); |
|---|
| 324 |
|
|---|
| 325 |
|
|---|
| 326 |
$this->captcha['letters'][$i]['size'] = $this->getRandomCharacterSize(); |
|---|
| 327 |
|
|---|
| 328 |
|
|---|
| 329 |
$this->captcha['letters'][$i]['y_coord'] = $this->getRandomVerticalOffset(); |
|---|
| 330 |
|
|---|
| 331 |
|
|---|
| 332 |
$this->captcha['word'] .= $this->captcha['letters'][$i]['char']; |
|---|
| 333 |
|
|---|
| 334 |
|
|---|
| 335 |
$this->captcha['letters'][$i]['x_coord'] = $x_coord; |
|---|
| 336 |
$x_coord += $this->config['char_px_spacing']; |
|---|
| 337 |
} |
|---|
| 338 |
|
|---|
| 339 |
return true; |
|---|
| 340 |
} |
|---|
| 341 |
|
|---|
| 342 |
|
|---|
| 343 |
* Adjusts the captcha to the image |
|---|
| 344 |
* |
|---|
| 345 |
* It adapts the characters to the image so none is out of bounds |
|---|
| 346 |
* and saved the x offset coordinate |
|---|
| 347 |
* |
|---|
| 348 |
* @return bool Ok if the captcha has been correctly aligned. |
|---|
| 349 |
*/ |
|---|
| 350 |
private function adjustCaptcha() |
|---|
| 351 |
{ |
|---|
| 352 |
|
|---|
| 353 |
$this->generateRawTempImage(); |
|---|
| 354 |
|
|---|
| 355 |
|
|---|
| 356 |
$this->addCaptchaOnTempImage(); |
|---|
| 357 |
|
|---|
| 358 |
|
|---|
| 359 |
$x_coord_adjust = $this->getAdjustmentOffset(); |
|---|
| 360 |
if(!empty($x_coord_adjust)) |
|---|
| 361 |
{ |
|---|
| 362 |
$this->captcha['x_coord_adjust'] = $x_coord_adjust; |
|---|
| 363 |
|
|---|
| 364 |
|
|---|
| 365 |
$this->updateCaptchaXCoord(); |
|---|
| 366 |
|
|---|
| 367 |
return true; |
|---|
| 368 |
} |
|---|
| 369 |
else |
|---|
| 370 |
{ |
|---|
| 371 |
return false; |
|---|
| 372 |
} |
|---|
| 373 |
} |
|---|
| 374 |
|
|---|
| 375 |
|
|---|
| 376 |
|
|---|
| 377 |
* Randomly selects a font in the available fonts |
|---|
| 378 |
* |
|---|
| 379 |
* @return string The randomly selected font |
|---|
| 380 |
*/ |
|---|
| 381 |
private function getRandomFont() |
|---|
| 382 |
{ |
|---|
| 383 |
return $this->config['char_fonts'][array_rand($this->config['char_fonts'],1)]; |
|---|
| 384 |
} |
|---|
| 385 |
|
|---|
| 386 |
|
|---|
| 387 |
* Randomly generates an angle |
|---|
| 388 |
* |
|---|
| 389 |
* @return string The randomly generated angle |
|---|
| 390 |
*/ |
|---|
| 391 |
private function getRandomLetterRotation() |
|---|
| 392 |
{ |
|---|
| 393 |
if(rand(0,1)) |
|---|
| 394 |
{ |
|---|
| 395 |
return rand(0, $this->config['char_max_rot_angle']); |
|---|
| 396 |
} |
|---|
| 397 |
else |
|---|
| 398 |
{ |
|---|
| 399 |
return rand(360-$this->config['char_max_rot_angle'],360); |
|---|
| 400 |
} |
|---|
| 401 |
} |
|---|
| 402 |
|
|---|
| 403 |
|
|---|
| 404 |
* Randomly selects a character |
|---|
| 405 |
* |
|---|
| 406 |
* The function randomly selects characters to make the captcha |
|---|
| 407 |
* word. If the easy captcha is activated, it alternates |
|---|
| 408 |
* between vowels and consonants. |
|---|
| 409 |
* |
|---|
| 410 |
* @return string The randomly selected letter |
|---|
| 411 |
*/ |
|---|
| 412 |
private function getRandomCharacter() |
|---|
| 413 |
{ |
|---|
| 414 |
|
|---|
| 415 |
if($this->config['easy_captcha']) |
|---|
| 416 |
{ |
|---|
| 417 |
|
|---|
| 418 |
if($this->config['easy_captcha_bool'] == 1) |
|---|
| 419 |
{ |
|---|
| 420 |
|
|---|
| 421 |
$this->config['easy_captcha_bool'] = 0; |
|---|
| 422 |
return $this->config['easy_captcha_consonants']{rand(0,strlen($this->config['easy_captcha_consonants'])-1)}; |
|---|
| 423 |
} |
|---|
| 424 |
else |
|---|
| 425 |
{ |
|---|
| 426 |
|
|---|
| 427 |
$this->config['easy_captcha_bool'] = 1; |
|---|
| 428 |
return $this->config['easy_captcha_vowels']{rand(0,strlen($this->config['easy_captcha_vowels'])-1)}; |
|---|
| 429 |
} |
|---|
| 430 |
} |
|---|
| 431 |
else |
|---|
| 432 |
{ |
|---|
| 433 |
|
|---|
| 434 |
return $this->config['chars_used']{rand(0,strlen($this->config['chars_used'])-1)}; |
|---|
| 435 |
} |
|---|
| 436 |
} |
|---|
| 437 |
|
|---|
| 438 |
|
|---|
| 439 |
* Randomly selects a character size |
|---|
| 440 |
* |
|---|
| 441 |
* @return string The randomly selected size |
|---|
| 442 |
*/ |
|---|
| 443 |
private function getRandomCharacterSize() |
|---|
| 444 |
{ |
|---|
| 445 |
return rand($this->config['char_min_size'],$this->config['char_max_size']); |
|---|
| 446 |
} |
|---|
| 447 |
|
|---|
| 448 |
|
|---|
| 449 |
* Randomly generates a vertical offset |
|---|
| 450 |
* |
|---|
| 451 |
* @return string The randomly generated offset |
|---|
| 452 |
*/ |
|---|
| 453 |
private function getRandomVerticalOffset() |
|---|
| 454 |
{ |
|---|
| 455 |
if($this->config['char_vertical_offset']) |
|---|
| 456 |
{ |
|---|
| 457 |
$vertical_offset = $this->config['height']/2; |
|---|
| 458 |
$vertical_offset += rand(0,round($this->config['height']/5)); |
|---|
| 459 |
} |
|---|
| 460 |
else |
|---|
| 461 |
{ |
|---|
| 462 |
$vertical_offset = round($this->config['height']/1.5); |
|---|
| 463 |
} |
|---|
| 464 |
return $vertical_offset; |
|---|
| 465 |
} |
|---|
| 466 |
|
|---|
| 467 |
|
|---|
| 468 |
* Generates an image with a white background in the $temp_image class attribute |
|---|
| 469 |
* |
|---|
| 470 |
* @return bool True if the generation is successfull. |
|---|
| 471 |
*/ |
|---|
| 472 |
private function generateRawTempImage() |
|---|
| 473 |
{ |
|---|
| 474 |
$this->temp_image = imagecreatetruecolor($this->config['width'],$this->config['height']); |
|---|
| 475 |
$white = imagecolorallocate($this->temp_image,255,255,255); |
|---|
| 476 |
|
|---|
| 477 |
if(!imagefill($this->temp_image,0,0,$white)) |
|---|
| 478 |
{ |
|---|
| 479 |
return false; |
|---|
| 480 |
} |
|---|
| 481 |
else |
|---|
| 482 |
{ |
|---|
| 483 |
return true; |
|---|
| 484 |
} |
|---|
| 485 |
} |
|---|
| 486 |
|
|---|
| 487 |
|
|---|
| 488 |
* Adds the captcha letters on the temporary image |
|---|
| 489 |
* |
|---|
| 490 |
* @return bool True if the adding is successfull |
|---|
| 491 |
*/ |
|---|
| 492 |
private function addCaptchaOnTempImage() |
|---|
| 493 |
{ |
|---|
| 494 |
|
|---|
| 495 |
for($i=1; $i<= $this->captcha['chars']; $i++) |
|---|
| 496 |
{ |
|---|
| 497 |
$black_ink = imagecolorallocate($this->temp_image,0,0,0); |
|---|
| 498 |
|
|---|
| 499 |
if(!imagettftext($this->temp_image, |
|---|
| 500 |
$this->captcha['letters'][$i]['size'], |
|---|
| 501 |
$this->captcha['letters'][$i]['rotation'], |
|---|
| 502 |
$this->captcha['letters'][$i]['x_coord'], |
|---|
| 503 |
$this->captcha['letters'][$i]['y_coord'], |
|---|
| 504 |
$black_ink, |
|---|
| 505 |
$this->captcha['letters'][$i]['font_path'], |
|---|
| 506 |
$this->captcha['letters'][$i]['char'])) |
|---|
| 507 |
{ |
|---|
| 508 |
return false; |
|---|
| 509 |
} |
|---|
| 510 |
} |
|---|
| 511 |
return true; |
|---|
| 512 |
} |
|---|
| 513 |
|
|---|
| 514 |
|
|---|
| 515 |
* Computes the x coordinate offset |
|---|
| 516 |
* |
|---|
| 517 |
* @return int The x coordiante offset |
|---|
| 518 |
*/ |
|---|
| 519 |
private function getAdjustmentOffset() |
|---|
| 520 |
{ |
|---|
| 521 |
$white = imagecolorallocate($this->temp_image,255,255,255); |
|---|
| 522 |
|
|---|
| 523 |
|
|---|
| 524 |
$xbegin = 0; |
|---|
| 525 |
$x = 0; |
|---|
| 526 |
while ($x < $this->config['width'] && !$xbegin ) |
|---|
| 527 |
{ |
|---|
| 528 |
$y = 0; |
|---|
| 529 |
while ($y < $this->config['height'] && !$xbegin ) |
|---|
| 530 |
{ |
|---|
| 531 |
if(imagecolorat($this->temp_image, $x, $y) != $white ) |
|---|
| 532 |
{ |
|---|
| 533 |
$xbegin = $x; |
|---|
| 534 |
} |
|---|
| 535 |
$y++; |
|---|
| 536 |
} |
|---|
| 537 |
$x++; |
|---|
| 538 |
} |
|---|
| 539 |
$xend = 0; |
|---|
| 540 |
|
|---|
| 541 |
|
|---|
| 542 |
$x = $this->config['width'] - 1; |
|---|
| 543 |
while($x > 0 && !$xend) |
|---|
| 544 |
{ |
|---|
| 545 |
$y = 0; |
|---|
| 546 |
while ($y < $this->config['height'] && !$xend) |
|---|
| 547 |
{ |
|---|
| 548 |
if(imagecolorat($this->temp_image, $x, $y) != $white) |
|---|
| 549 |
{ |
|---|
| 550 |
$xend = $x; |
|---|
| 551 |
} |
|---|
| 552 |
$y++; |
|---|
| 553 |
} |
|---|
| 554 |
$x--; |
|---|
| 555 |
} |
|---|
| 556 |
|
|---|
| 557 |
|
|---|
| 558 |
$xadjustment = round(($this->config['width']/2)-($xend-$xbegin)/2); |
|---|
| 559 |
|
|---|
| 560 |
return $xadjustment; |
|---|
| 561 |
} |
|---|
| 562 |
|
|---|
| 563 |
|
|---|
| 564 |
* Selects the final captcha background. Random image if file in configuration |
|---|
| 565 |
* |
|---|
| 566 |
* In all cases, it defines also the background color. |
|---|
| 567 |
* |
|---|
| 568 |
* @return bool True if image correctly selected and set |
|---|
| 569 |
*/ |
|---|
| 570 |
private function selectBackground() |
|---|
| 571 |
{ |
|---|
| 572 |
if($this->config['bg_img'] && is_dir($this->config['bg_img'])) |
|---|
| 573 |
{ |
|---|
| 574 |
$pointer = opendir($this->config['bg_img']); |
|---|
| 575 |
while(false !== ($filename = readdir($pointer))) |
|---|
| 576 |
{ |
|---|
| 577 |
if(eregi('.[gif|jpg|jpeg|png]$', $filename)) |
|---|
| 578 |
{ |
|---|
| 579 |
$files[] = $filename; |
|---|
| 580 |
} |
|---|
| 581 |
} |
|---|
| 582 |
closedir($pointer); |
|---|
| 583 |
$this->captcha['bg_img'] = $this->config['bg_img'].'/'.$files[array_rand($files, 1)]; |
|---|
| 584 |
} |
|---|
| 585 |
elseif($this->config['bg_img'] && file_exists($this->config['bg_img'])) |
|---|
| 586 |
{ |
|---|
| 587 |
|
|---|
| 588 |
$this->captcha['bg_img'] = $this->config['bg_img']; |
|---|
| 589 |
} |
|---|
| 590 |
else |
|---|
| 591 |
{ |
|---|
| 592 |
$this->captcha['bg_img'] = ''; |
|---|
| 593 |
} |
|---|
| 594 |
$this->captcha['bg_colors'] = array('red'=>$this->config['bg_red'], 'green'=>$this->config['bg_green'], 'blue'=>$this->config['bg_blue']); |
|---|
| 595 |
|
|---|
| 596 |
if(!empty($this->captcha['bg_colors'])) |
|---|
| 597 |
{ |
|---|
| 598 |
return true; |
|---|
| 599 |
} |
|---|
| 600 |
else |
|---|
| 601 |
{ |
|---|
| 602 |
return false; |
|---|
| 603 |
} |
|---|
| 604 |
} |
|---|
| 605 |
|
|---|
| 606 |
|
|---|
| 607 |
* Selects the ink type (transparent or normal) |
|---|
| 608 |
* |
|---|
| 609 |
* @return bool The ink type (true=alpha, false=opaque) |
|---|
| 610 |
*/ |
|---|
| 611 |
private function getInkType() |
|---|
| 612 |
{ |
|---|
| 613 |
|
|---|
| 614 |
if(function_exists('imagecolorallocatealpha') && $this->config['char_transparent'] != 0) |
|---|
| 615 |
{ |
|---|
| 616 |
return true; |
|---|
| 617 |
} |
|---|
| 618 |
else |
|---|
| 619 |
{ |
|---|
| 620 |
return false; |
|---|
| 621 |
} |
|---|
| 622 |
} |
|---|
| 623 |
|
|---|
| 624 |
|
|---|
| 625 |
* Selects the ink colors |
|---|
| 626 |
* |
|---|
| 627 |
* @return array The ink colors |
|---|
| 628 |
*/ |
|---|
| 629 |
private function getInkColors() |
|---|
| 630 |
{ |
|---|
| 631 |
|
|---|
| 632 |
if($this->config['char_random_color']) |
|---|
| 633 |
{ |
|---|
| 634 |
$ok = false; |
|---|
| 635 |
do { |
|---|
| 636 |
$rand_red = rand(0,255); |
|---|
| 637 |
$rand_green = rand(0,255); |
|---|
| 638 |
$rand_blue = rand(0,255); |
|---|
| 639 |
$random_color_sum = $rand_red + $rand_green + $rand_blue; |
|---|
| 640 |
switch ($this->config['char_random_color_lvl']) |
|---|
| 641 |
{ |
|---|
| 642 |
case 1 : if ($random_color_sum<200) $ok=true; break; |
|---|
| 643 |
case 2 : if ($random_color_sum<400) $ok=true; break; |
|---|
| 644 |
case 3 : if ($random_color_sum>500) $ok=true; break; |
|---|
| 645 |
case 4 : if ($random_color_sum>650) $ok=true; break; |
|---|
| 646 |
default : $ok=true; |
|---|
| 647 |
} |
|---|
| 648 |
}while($ok == false); |
|---|
| 649 |
|
|---|
| 650 |
$ink['red']=$rand_red; |
|---|
| 651 |
$ink['green']=$rand_green; |
|---|
| 652 |
$ink['blue']=$rand_blue; |
|---|
| 653 |
} |
|---|
| 654 |
else |
|---|
| 655 |
{ |
|---|
| 656 |
$ink['red']=$this->config['char_red']; |
|---|
| 657 |
$ink['green']=$this->config['char_green']; |
|---|
| 658 |
$ink['blue']=$this->config['char_blue']; |
|---|
| 659 |
} |
|---|
| 660 |
|
|---|
| 661 |
return $ink; |
|---|
| 662 |
} |
|---|
| 663 |
|
|---|
| 664 |
|
|---|
| 665 |
* Defines the captcha noise parameters |
|---|
| 666 |
* |
|---|
| 667 |
* @return bool Always true |
|---|
| 668 |
*/ |
|---|
| 669 |
private function setNoiseParameters() |
|---|
| 670 |
{ |
|---|
| 671 |
switch($this->config['noise_color']) |
|---|
| 672 |
{ |
|---|
| 673 |
case 1 : $rand_letter = rand(1,$this->captcha['chars']); |
|---|
| 674 |
$this->captcha['noise_color'] = $this->captcha['letters'][$rand_letter]['ink_colors']; break; |
|---|
| 675 |
case 2 : $this->captcha['noise_color'] = $this->captcha['bg_colors']; break; |
|---|
| 676 |
case 3 : |
|---|
| 677 |
default : $this->captcha['noise_color'] = array('red'=>rand(0,255),'green'=>rand(0,255),'blue'=>rand(0,255)); break; |
|---|
| 678 |
} |
|---|
| 679 |
|
|---|
| 680 |
$this->captcha['noise_px'] = rand($this->config['noise_min_px'],$this->config['noise_max_px']); |
|---|
| 681 |
$this->captcha['noise_lines'] = rand($this->config['noise_min_lines'],$this->config['noise_max_lines']); |
|---|
| 682 |
$this->captcha['noise_circles'] = rand($this->config['noise_min_circles'],$this->config['noise_max_circles']); |
|---|
| 683 |
|
|---|
| 684 |
return true; |
|---|
| 685 |
} |
|---|
| 686 |
|
|---|
| 687 |
|
|---|
| 688 |
* Generates the final captcha image with the background |
|---|
| 689 |
* |
|---|
| 690 |
* @return bool Always true |
|---|
| 691 |
*/ |
|---|
| 692 |
private function createCaptchaImageAndBackground() |
|---|
| 693 |
{ |
|---|
| 694 |
$this->image = imagecreatetruecolor($this->config['width'],$this->config['height']); |
|---|
| 695 |
|
|---|
| 696 |
if(!empty($this->config['bg_img'])) |
|---|
| 697 |
{ |
|---|
| 698 |
$this->addImageBackgroundImage(); |
|---|
| 699 |
} |
|---|
| 700 |
else |
|---|
| 701 |
{ |
|---|
| 702 |
$this->addImageBackgroundColor(); |
|---|
| 703 |
} |
|---|
| 704 |
|
|---|
| 705 |
return true; |
|---|
| 706 |
} |
|---|
| 707 |
|
|---|
| 708 |
|
|---|
| 709 |
* Adds the background image to the $image attribute |
|---|
| 710 |
* |
|---|
| 711 |
* @return bool Always true |
|---|
| 712 |
*/ |
|---|
| 713 |
private function addImageBackgroundImage() |
|---|
| 714 |
{ |
|---|
| 715 |
list($bg_width, $bg_height, $bg_type, $bg_attributes) = getimagesize($this->captcha['bg_img']); |
|---|
| 716 |
if($bg_type == '1') |
|---|
| 717 |
{ |
|---|
| 718 |
$img_read = imagecreatefromgif($this->captcha['bg_img']); |
|---|
| 719 |
} |
|---|
| 720 |
elseif($bg_type == '2') |
|---|
| 721 |
{ |
|---|
| 722 |
$img_read = imagecreatefromjpeg($this->captcha['bg_img']); |
|---|
| 723 |
} |
|---|
| 724 |
elseif($bg_type == '3') |
|---|
| 725 |
{ |
|---|
| 726 |
$img_read = imagecreatefrompng($this->captcha['bg_img']); |
|---|
| 727 |
} |
|---|
| 728 |
else |
|---|
| 729 |
{ |
|---|
| 730 |
return false; |
|---|
| 731 |
} |
|---|
| 732 |
imagecopyresized($this->image, $img_read, 0, 0, 0, 0, $this->config['width'], $this->config['height'], $bg_width, $bg_height ); |
|---|
| 733 |
imagedestroy($img_read); |
|---|
| 734 |
|
|---|
| 735 |
return true; |
|---|
| 736 |
} |
|---|
| 737 |
|
|---|
| 738 |
|
|---|
| 739 |
* Adds the background color to the $image attribute |
|---|
| 740 |
* |
|---|
| 741 |
* @return bool Always true |
|---|
| 742 |
*/ |
|---|
| 743 |
private function addImageBackgroundColor() |
|---|
| 744 |
{ |
|---|
| 745 |
$bg = imagecolorallocate($this->image, $this->captcha['bg_colors']['red'], $this->captcha['bg_colors']['green'], $this->captcha['bg_colors']['blue']); |
|---|
| 746 |
imagefill($this->image, 0, 0, $bg); |
|---|
| 747 |
|
|---|
| 748 |
if($this->config['bg_transparent'] && strtoupper($this->config['format'])== 'PNG') |
|---|
| 749 |
{ |
|---|
| 750 |
imagecolortransparent($this->image, $bg); |
|---|
| 751 |
} |
|---|
| 752 |
|
|---|
| 753 |
return true; |
|---|
| 754 |
} |
|---|
| 755 |
|
|---|
| 756 |
|
|---|
| 757 |
* Adds the noise to the $image attribute |
|---|
| 758 |
* |
|---|
| 759 |
* @return bool Always true |
|---|
| 760 |
*/ |
|---|
| 761 |
private function addNoiseToImage() |
|---|
| 762 |
{ |
|---|
| 763 |
|
|---|
| 764 |
for($i = 1; $i < $this->captcha['noise_px']; $i++) |
|---|
| 765 |
{ |
|---|
| 766 |
imagesetpixel($this->image, rand(0, $this->config['width']-1), rand(0, $this->config['height']-1), $this->getNoiseBrush() ); |
|---|
| 767 |
} |
|---|
| 768 |
|
|---|
| 769 |
for($j = 1; $j < $this->captcha['noise_lines']; $j++) |
|---|
| 770 |
{ |
|---|
| 771 |
imageline($this->image, rand(0, $this->config['width']-1), rand(0, $this->config['height']-1), rand(0, $this->config['width']-1), rand(0, $this->config['height']-1), $this->getNoiseBrush()); |
|---|
| 772 |
} |
|---|
| 773 |
|
|---|
| 774 |
for($k = 1; $k < $this->captcha['noise_circles']; $k++) |
|---|
| 775 |
{ |
|---|
| 776 |
$radius = rand(5,$this->config['width']/3); |
|---|
| 777 |
imagearc($this->image, rand(0, $this->config['width']-1), rand(0, $this->config['height']-1), $radius, $radius, 0, 360, $this->getNoiseBrush()); |
|---|
| 778 |
} |
|---|
| 779 |
|
|---|
| 780 |
return true; |
|---|
| 781 |
} |
|---|
| 782 |
|
|---|
| 783 |
|
|---|
| 784 |
* Updates the captcha letters x_coord value |
|---|
| 785 |
* |
|---|
| 786 |
* @return bool Always true |
|---|
| 787 |
*/ |
|---|
| 788 |
private function updateCaptchaXCoord() |
|---|
| 789 |
{ |
|---|
| 790 |
|
|---|
| 791 |
$x_coord = $this->captcha['x_coord_adjust']; |
|---|
| 792 |
|
|---|
| 793 |
for($i=1; $i<= $this->captcha['chars']; $i++) |
|---|
| 794 |
{ |
|---|
| 795 |
|
|---|
| 796 |
$this->captcha['letters'][$i]['x_coord'] = $x_coord; |
|---|
| 797 |
$x_coord += $this->config['char_px_spacing']; |
|---|
| 798 |
} |
|---|
| 799 |
|
|---|
| 800 |
return true; |
|---|
| 801 |
} |
|---|
| 802 |
|
|---|
| 803 |
|
|---|
| 804 |
* Adds the actual captcha letters to the $image attribute |
|---|
| 805 |
* |
|---|
| 806 |
* @return bool Always true |
|---|
| 807 |
*/ |
|---|
| 808 |
private function addLettersToImage() |
|---|
| 809 |
{ |
|---|
| 810 |
|
|---|
| 811 |
for($i=1; $i<= $this->captcha['chars']; $i++) |
|---|
| 812 |
{ |
|---|
| 813 |
|
|---|
| 814 |
if($this->captcha['letters'][$i]['ink_type']) |
|---|
| 815 |
{ |
|---|
| 816 |
|
|---|
| 817 |
$ink = imagecolorallocatealpha($this->image, $this->captcha['letters'][$i]['ink_colors']['red'], |
|---|
| 818 |
$this->captcha['letters'][$i]['ink_colors']['green'], |
|---|
| 819 |
$this->captcha['letters'][$i]['ink_colors']['blue'], |
|---|
| 820 |
$this->config['char_transparent']); |
|---|
| 821 |
} |
|---|
| 822 |
else |
|---|
| 823 |
{ |
|---|
| 824 |
|
|---|
| 825 |
$ink = imagecolorallocatealpha($this->image, $this->captcha['letters'][$i]['ink_colors']['red'], |
|---|
| 826 |
$this->captcha['letters'][$i]['ink_colors']['green'], |
|---|
| 827 |
$this->captcha['letters'][$i]['ink_colors']['blue']); |
|---|
| 828 |
} |
|---|
| 829 |
|
|---|
| 830 |
|
|---|
| 831 |
imagettftext($this->image, |
|---|
| 832 |
$this->captcha['letters'][$i]['size'], |
|---|
| 833 |
$this->captcha['letters'][$i]['rotation'], |
|---|
| 834 |
$this->captcha['letters'][$i]['x_coord'], |
|---|
| 835 |
$this->captcha['letters'][$i]['y_coord'], |
|---|
| 836 |
$ink, |
|---|
| 837 |
$this->captcha['letters'][$i]['font_path'], |
|---|
| 838 |
$this->captcha['letters'][$i]['char']); |
|---|
| 839 |
|
|---|
| 840 |
} |
|---|
| 841 |
|
|---|
| 842 |
return true; |
|---|
| 843 |
} |
|---|
| 844 |
|
|---|
| 845 |
|
|---|
| 846 |
* Defines the brush used on the $image attribute |
|---|
| 847 |
* |
|---|
| 848 |
* @return bool Always true |
|---|
| 849 |
*/ |
|---|
| 850 |
private function setBrush() |
|---|
| 851 |
{ |
|---|
| 852 |
$noise_color = imagecolorallocate ($this->image, $this->captcha['noise_color']['red'], $this->captcha['noise_color']['green'], $this->captcha['noise_color']['blue']); |
|---|
| 853 |
if($this->config['brush_size'] && $this->config['brush_size']>1 && function_exists('imagesetbrush')) |
|---|
| 854 |
{ |
|---|
| 855 |
$brush = imagecreatetruecolor($this->config['brush_size'], $this->config['brush_size']); |
|---|
| 856 |
imagefill($brush, 0, 0, $noise_color); |
|---|
| 857 |
imagesetbrush($this->image, $brush); |
|---|
| 858 |
$this->captcha['noise_brush'] = IMG_COLOR_BRUSHED; |
|---|
| 859 |
$this->captcha['brush'] = $brush; |
|---|
| 860 |
} |
|---|
| 861 |
else |
|---|
| 862 |
{ |
|---|
| 863 |
$this->captcha['noise_brush'] = $noise_color; |
|---|
| 864 |
} |
|---|
| 865 |
|
|---|
| 866 |
return true; |
|---|
| 867 |
} |
|---|
| 868 |
|
|---|
| 869 |
|
|---|
| 870 |
* Deletes the brush image so it can be reused! |
|---|
| 871 |
* |
|---|
| 872 |
* @return bool Always returns true |
|---|
| 873 |
*/ |
|---|
| 874 |
private function clearBrush() |
|---|
| 875 |
{ |
|---|
| 876 |
if(isset($this->captcha['brush']) && !empty($this->captcha['brush'])) |
|---|
| 877 |
{ |
|---|
| 878 |
imagedestroy($this->captcha['brush']); |
|---|
| 879 |
return true; |
|---|
| 880 |
} |
|---|
| 881 |
else |
|---|
| 882 |
{ |
|---|
| 883 |
return false; |
|---|
| 884 |
} |
|---|
| 885 |
} |
|---|
| 886 |
|
|---|
| 887 |
|
|---|
| 888 |
* Refreshes the captcha noise parameters if the random option is selected |
|---|
| 889 |
* |
|---|
| 890 |
* @return bool If changed, returns true |
|---|
| 891 |
*/ |
|---|
| 892 |
private function refreshNoiseColor() |
|---|
| 893 |
{ |
|---|
| 894 |
if($this->config['noise_color'] != 1 && $this->config['noise_color'] != 2) |
|---|
| 895 |
{ |
|---|
| 896 |
$this->captcha['noise_color'] = array('red'=>rand(0,255),'green'=>rand(0,255),'blue'=>rand(0,255)); |
|---|
| 897 |
return true; |
|---|
| 898 |
} |
|---|
| 899 |
return false; |
|---|
| 900 |
} |
|---|
| 901 |
|
|---|
| 902 |
|
|---|
| 903 |
* Refreshes the noise and makes it into a brush for direct use |
|---|
| 904 |
* |
|---|
| 905 |
* @return bool Always true |
|---|
| 906 |
*/ |
|---|
| 907 |
private function getNoiseBrush() |
|---|
| 908 |
{ |
|---|
| 909 |
|
|---|
| 910 |
if($this->refreshNoiseColor()) |
|---|
| 911 |
{ |
|---|
| 912 |
|
|---|
| 913 |
$this->setBrush(); |
|---|
| 914 |
} |
|---|
| 915 |
else |
|---|
| 916 |
{ |
|---|
| 917 |
if(empty($this->captcha['noise_brush']) || !isset($this->captcha['noise_brush'])) |
|---|
| 918 |
{ |
|---|
| 919 |
$this->setBrush(); |
|---|
| 920 |
} |
|---|
| 921 |
else |
|---|
| 922 |
{ |
|---|
| 923 |
|
|---|
| 924 |
} |
|---|
| 925 |
} |
|---|
| 926 |
return $this->captcha['noise_brush']; |
|---|
| 927 |
} |
|---|
| 928 |
|
|---|
| 929 |
|
|---|
| 930 |
* Adds a border around the image |
|---|
| 931 |
* |
|---|
| 932 |
* @return bool Always true |
|---|
| 933 |
*/ |
|---|
| 934 |
private function addBorder() |
|---|
| 935 |
{ |
|---|
| 936 |
if($this->config['bg_border']) |
|---|
| 937 |
{ |
|---|
| 938 |
$border_color = imagecolorallocate($this->image, ($this->config['bg_red']*3+$this->config['char_red'])/4, |
|---|
| 939 |
($this->config['bg_green']*3+$this->config['char_green'])/4, |
|---|
| 940 |
($this->config['bg_blue']*3+$this->config['char_blue'])/4); |
|---|
| 941 |
imagerectangle($this->image, 0, 0, $this->config['width']-1, $this->config['height']-1, $border_color); |
|---|
| 942 |
} |
|---|
| 943 |
return true; |
|---|
| 944 |
} |
|---|
| 945 |
|
|---|
| 946 |
|
|---|
| 947 |
* Aplies effects to the image |
|---|
| 948 |
* |
|---|
| 949 |
* @return bool Always true |
|---|
| 950 |
*/ |
|---|
| 951 |
private function addEffect() |
|---|
| 952 |
{ |
|---|
| 953 |
if(function_exists('imagefilter')) |
|---|
| 954 |
{ |
|---|
| 955 |
if($this->config['effect_greyscale']) |
|---|
| 956 |
{ |
|---|
| 957 |
imagefilter($this->image, IMG_FILTER_GRAYSCALE); |
|---|
| 958 |
} |
|---|
| 959 |
if($this->config['effect_blur']) |
|---|
| 960 |
{ |
|---|
| 961 |
imagefilter($this->image, IMG_FILTER_GAUSSIAN_BLUR); |
|---|
| 962 |
} |
|---|
| 963 |
} |
|---|
| 964 |
return true; |
|---|
| 965 |
} |
|---|
| 966 |
|
|---|
| 967 |
|
|---|
| 968 |
* Saves the captcha word into the user session |
|---|
| 969 |
* |
|---|
| 970 |
* @return bool Always true |
|---|
| 971 |
*/ |
|---|
| 972 |
private function setUserAttributes() |
|---|
| 973 |
{ |
|---|
| 974 |
if(!$this->config['case_sensitive']) |
|---|
| 975 |
{ |
|---|
| 976 |
$this->captcha['word'] = strtoupper($this->captcha['word']); |
|---|
| 977 |
} |
|---|
| 978 |
|
|---|
| 979 |
|
|---|
| 980 |
if(empty($this->config['hash_algo'])) |
|---|
| 981 |
{ |
|---|
| 982 |
$this->sf_user->setAttribute('captcha_code', hash('sha1',$this->captcha['word']), 'captcha'); |
|---|
| 983 |
} |
|---|
| 984 |
else |
|---|
| 985 |
{ |
|---|
| 986 |
$this->sf_user->setAttribute('captcha_code', hash($this->config['hash_algo'],$this->captcha['word']), 'captcha'); |
|---|
| 987 |
} |
|---|
| 988 |
|
|---|
| 989 |
return true; |
|---|
| 990 |
} |
|---|
| 991 |
|
|---|
| 992 |
|
|---|
| 993 |
* Sends the final image to the browser! |
|---|
| 994 |
* |
|---|
| 995 |
* @return bool Returns false if the format specified does not exist. |
|---|
| 996 |
*/ |
|---|
| 997 |
private function sendImageToBrowser() |
|---|
| 998 |
{ |
|---|
| 999 |
|
|---|
| 1000 |
if(strtoupper($this->config['format']) == 'JPG' || strtoupper($this->config['format']) == 'JPEG') |
|---|
| 1001 |
{ |
|---|
| 1002 |
if(imagetypes() & IMG_JPG) |
|---|
| 1003 |
{ |
|---|
| 1004 |
header("Content-type: image/jpeg"); |
|---|
| 1005 |
imagejpeg($this->image, '', 80); |
|---|
| 1006 |
} |
|---|
| 1007 |
else |
|---|
| 1008 |
{ |
|---|
| 1009 |
return false; |
|---|
| 1010 |
} |
|---|
| 1011 |
} |
|---|
| 1012 |
|
|---|
| 1013 |
if(strtoupper($this->config['format']) == 'GIF') |
|---|
| 1014 |
{ |
|---|
| 1015 |
if(imagetypes() & IMG_GIF) |
|---|
| 1016 |
{ |
|---|
| 1017 |
header("Content-type: image/gif"); |
|---|
| 1018 |
imagegif($this->image); |
|---|
| 1019 |
} |
|---|
| 1020 |
else |
|---|
| 1021 |
{ |
|---|
| 1022 |
return false; |
|---|
| 1023 |
} |
|---|
| 1024 |
} |
|---|
| 1025 |
|
|---|
| 1026 |
if(strtoupper($this->config['format']) == 'PNG') |
|---|
| 1027 |
{ |
|---|
| 1028 |
if(imagetypes() & IMG_PNG) |
|---|
| 1029 |
{ |
|---|
| 1030 |
header("Content-type: image/png"); |
|---|
| 1031 |
imagepng($this->image); |
|---|
| 1032 |
} |
|---|
| 1033 |
else |
|---|
| 1034 |
{ |
|---|
| 1035 |
return false; |
|---|
| 1036 |
} |
|---|
| 1037 |
} |
|---|
| 1038 |
|
|---|
| 1039 |
return true; |
|---|
| 1040 |
} |
|---|
| 1041 |
|
|---|
| 1042 |
private function generateErrorImage($error_text) |
|---|
| 1043 |
{ |
|---|
| 1044 |
$this->captcha['bg_img'] = false; |
|---|
| 1045 |
$this->config['bg_red']=255; |
|---|
| 1046 |
$this->config['bg_green']=255; |
|---|
| 1047 |
$this->config['bg_blue']=255; |
|---|
| 1048 |
$this->selectBackground(); |
|---|
| 1049 |
|
|---|
| 1050 |
|
|---|
| 1051 |
$this->createCaptchaImageAndBackground(); |
|---|
| 1052 |
|
|---|
| 1053 |
|
|---|
| 1054 |
$this->captcha['word'] = $error_text; |
|---|
| 1055 |
$this->captcha['chars'] = strlen($this->captcha['word']); |
|---|
| 1056 |
|
|---|
| 1057 |
$x_coord = 5; |
|---|
| 1058 |
$new_line = false; |
|---|
| 1059 |
|
|---|
| 1060 |
for($i=1; $i<= $this->captcha['chars']; $i++) |
|---|
| 1061 |
{ |
|---|
| 1062 |
|
|---|
| 1063 |
$this->captcha['letters'][$i]['font'] = $this->config['error_font']; |
|---|
| 1064 |
$this->captcha['letters'][$i]['font_path'] = $this->config['char_fonts_dir'].$this->captcha['letters'][$i]['font']; |
|---|
| 1065 |
|
|---|
| 1066 |
|
|---|
| 1067 |
$this->captcha['letters'][$i]['ink_type'] = $this->getInkType(); |
|---|
| 1068 |
$this->captcha['letters'][$i]['ink_colors'] = array('red'=>255,'green'=>0, 'blue'=>0); |
|---|
| 1069 |
|
|---|
| 1070 |
|
|---|
| 1071 |
$this->captcha['letters'][$i]['rotation'] = 0; |
|---|
| 1072 |
|
|---|
| 1073 |
|
|---|
| 1074 |
$this->captcha['letters'][$i]['char'] = $this->captcha['word']{$i-1}; |
|---|
| 1075 |
|
|---|
| 1076 |
|
|---|
| 1077 |
$this->captcha['letters'][$i]['size'] = '8'; |
|---|
| 1078 |
|
|---|
| 1079 |
|
|---|
| 1080 |
$this->config['char_px_spacing'] = 7; |
|---|
| 1081 |
|
|---|
| 1082 |
if($i >= round($this->captcha['chars'])/2) |
|---|
| 1083 |
{ |
|---|
| 1084 |
if($this->captcha['letters'][$i]['char'] == ' ' && !$new_line) |
|---|
| 1085 |
{ |
|---|
| 1086 |
|
|---|
| 1087 |
$x_coord = 10; |
|---|
| 1088 |
$new_line = true; |
|---|
| 1089 |
} |
|---|
| 1090 |
if($new_line == true) |
|---|
| 1091 |
{ |
|---|
| 1092 |
|
|---|
| 1093 |
$this->captcha['letters'][$i]['y_coord'] = $this->config['height']/1.3; |
|---|
| 1094 |
} |
|---|
| 1095 |
else |
|---|
| 1096 |
{ |
|---|
| 1097 |
|
|---|
| 1098 |
$this->captcha['letters'][$i]['y_coord'] = $this->config['height']/2.5; |
|---|
| 1099 |
} |
|---|
| 1100 |
} |
|---|
| 1101 |
else |
|---|
| 1102 |
{ |
|---|
| 1103 |
if(($i >= (round($this->captcha['chars'])/2 - 1) || $i >= (round($this->captcha['chars'])/2 - 2)) && $this->captcha['letters'][$i]['char'] == ' ' && !$new_line) |
|---|
| 1104 |
{ |
|---|
| 1105 |
|
|---|
| 1106 |
$x_coord = 5; |
|---|
| 1107 |
$new_line = true; |
|---|
| 1108 |
} |
|---|
| 1109 |
if($new_line == true) |
|---|
| 1110 |
{ |
|---|
| 1111 |
|
|---|
| 1112 |
$this->captcha['letters'][$i]['y_coord'] = $this->config['height']/1.3; |
|---|
| 1113 |
} |
|---|
| 1114 |
else |
|---|
| 1115 |
{ |
|---|
| 1116 |
|
|---|
| 1117 |
$this->captcha['letters'][$i]['y_coord'] = $this->config['height']/2.5; |
|---|
| 1118 |
} |
|---|
| 1119 |
} |
|---|
| 1120 |
|
|---|
| 1121 |
|
|---|
| 1122 |
$this->captcha['letters'][$i]['x_coord'] = $x_coord; |
|---|
| 1123 |
$x_coord += $this->config['char_px_spacing']; |
|---|
| 1124 |
} |
|---|
| 1125 |
$this->addLettersToImage(); |
|---|
| 1126 |
|
|---|
| 1127 |
$this->addBorder(); |
|---|
| 1128 |
|
|---|
| 1129 |
|
|---|
| 1130 |
return $this->sendImageToBrowser(); |
|---|
| 1131 |
} |
|---|
| 1132 |
|
|---|
| 1133 |
private function sendErrorImage($error_message) |
|---|
| 1134 |
{ |
|---|
| 1135 |
|
|---|
| 1136 |
// 2) send it to the browser |
|---|
| 1137 |
|
|---|
| 1138 |
//get culture |
|---|
| 1139 |
$culture = $this->sf_user->getCulture(); |
|---|
| 1140 |
|
|---|
| 1141 |
|
|---|
| 1142 |
if($this->config['use_i18n'] == true) |
|---|
| 1143 |
{ |
|---|
| 1144 |
$image_path = $this->config['error_images_dir'].DIRECTORY_SEPARATOR.$culture.DIRECTORY_SEPARATOR.$error_message.'.'.$this->config['format']; |
|---|
| 1145 |
} |
|---|
| 1146 |
else |
|---|
| 1147 |
{ |
|---|
| 1148 |
$image_path = $this->config['error_images_dir'].DIRECTORY_SEPARATOR.$error_message.'.'.$this->config['format']; |
|---|
| 1149 |
} |
|---|
| 1150 |
|
|---|
| 1151 |
if(strtoupper($this->config['format']) == 'JPG' || strtoupper($this->config['format']) == 'JPEG') |
|---|
| 1152 |
{ |
|---|
| 1153 |
header("Content-type: image/jpeg"); |
|---|
| 1154 |
readfile($image_path); |
|---|
| 1155 |
exit; |
|---|
| 1156 |
} |
|---|
| 1157 |
|
|---|
| 1158 |
if(strtoupper($this->config['format']) == 'GIF') |
|---|
| 1159 |
{ |
|---|
| 1160 |
header("Content-type: image/gif"); |
|---|
| 1161 |
readfile($image_path); |
|---|
| 1162 |
exit; |
|---|
| 1163 |
} |
|---|
| 1164 |
|
|---|
| 1165 |
if(strtoupper($this->config['format']) == 'PNG') |
|---|
| 1166 |
{ |
|---|
| 1167 |
header("Content-type: image/png"); |
|---|
| 1168 |
readfile($image_path); |
|---|
| 1169 |
exit; |
|---|
| 1170 |
} |
|---|
| 1171 |
|
|---|
| 1172 |
return true; |
|---|
| 1173 |
} |
|---|
| 1174 |
|
|---|
| 1175 |
|
|---|
| 1176 |
|
|---|
| 1177 |
* Captcha configuration getter from the app.yml |
|---|
| 1178 |
* |
|---|
| 1179 |
* This function gets the configuration values |
|---|
| 1180 |
* from the configuration file. |
|---|
| 1181 |
* |
|---|
| 1182 |
* @return bool Always true |
|---|
| 1183 |
*/ |
|---|
| 1184 |
private function getConfiguration() |
|---|
| 1185 |
{ |
|---|
| 1186 |
$root_dir = sfConfig::get('sf_root_dir'); |
|---|
| 1187 |
$web_dir = sfConfig::get('sf_web_dir'); |
|---|
| 1188 |
|
|---|
| 1189 |
$this->config['width'] = sfConfig::get('app_sf_crypto_captcha_width', 130); |
|---|
| 1190 |
$this->config['height'] = sfConfig::get('app_sf_crypto_captcha_height', 40); |
|---|
| 1191 |
|
|---|
| 1192 |
//Setting background |
|---|
| 1193 |
$this->config['bg_red'] = sfConfig::get('app_sf_crypto_captcha_bg_red', 238); |
|---|
| 1194 |
$this->config['bg_green'] = sfConfig::get('app_sf_crypto_captcha_bg_green', 255); |
|---|
| 1195 |
$this->config['bg_blue'] = sfConfig::get('app_sf_crypto_captcha_bg_blue', 255); |
|---|
| 1196 |
$this->config['bg_transparent'] = sfConfig::get('app_sf_crypto_captcha_bg_transparent', false); |
|---|
| 1197 |
$this->config['bg_img'] = sfConfig::get('app_sf_crypto_captcha_bg_img', false); |
|---|
| 1198 |
if($this->config['bg_img'] != false) { $this->config['bg_img'] = $root_dir.$this->config['bg_img']; } |
|---|
| 1199 |
|
|---|
| 1200 |
$this->config['bg_border'] = sfConfig::get('app_sf_crypto_captcha_bg_border', true); |
|---|
| 1201 |
|
|---|
| 1202 |
//Setting characters |
|---|
| 1203 |
$this->config['char_red'] = sfConfig::get('app_sf_crypto_captcha_char_red', 0); |
|---|
| 1204 |
$this->config['char_green'] = sfConfig::get('app_sf_crypto_captcha_char_green', 0); |
|---|
| 1205 |
$this->config['char_blue'] = sfConfig::get('app_sf_crypto_captcha_char_blue', 0); |
|---|
| 1206 |
$this->config['char_random_color'] = sfConfig::get('app_sf_crypto_captcha_char_random_color', true); |
|---|
| 1207 |
$this->config['char_random_color_lvl'] = sfConfig::get('app_sf_crypto_captcha_char_random_color_lvl', 1); |
|---|
| 1208 |
$this->config['char_transparent'] = sfConfig::get('app_sf_crypto_captcha_char_transparent', 10); |
|---|
| 1209 |
$this->config['char_px_spacing'] = sfConfig::get('app_sf_crypto_captcha_char_px_spacing', 20); |
|---|
| 1210 |
$this->config['char_min_size'] = sfConfig::get('app_sf_crypto_captcha_char_min_size', 16); |
|---|
| 1211 |
$this->config['char_max_size'] = sfConfig::get('app_sf_crypto_captcha_char_max_size', 20); |
|---|
| 1212 |
$this->config['char_max_rot_angle'] = sfConfig::get('app_sf_crypto_captcha_char_max_rot_angle', 30); |
|---|
| 1213 |
$this->config['char_vertical_offset'] = sfConfig::get('app_sf_crypto_captcha_char_vertical_offset', true); |
|---|
| 1214 |
|
|---|
| 1215 |
//Setting fonts |
|---|
| 1216 |
$this->config['char_fonts'] = sfConfig::get('app_sf_crypto_captcha_char_fonts', array('luggerbu.ttf')); |
|---|
| 1217 |
$this->config['char_fonts_dir'] = sfConfig::get('app_sf_crypto_captcha_char_fonts_dir', '/plugins/sfCryptoCaptchaPlugin/media/fonts/'); |
|---|
| 1218 |
$this->config['char_fonts_dir'] = $root_dir.$this->config['char_fonts_dir']; |
|---|
| 1219 |
$this->config['error_font'] = sfConfig::get('app_sf_crypto_captcha_error_font', 'arial.ttf'); |
|---|
| 1220 |
|
|---|
| 1221 |
|
|---|
| 1222 |
|
|---|
| 1223 |
$this->config['chars_used'] = sfConfig::get('app_sf_crypto_captcha_chars_used', 'ABCDEFGHKLMNPRTWXYZ234569'); |
|---|
| 1224 |
|
|---|
| 1225 |
//Setting easy captchas |
|---|
| 1226 |
$this->config['easy_captcha'] = sfConfig::get('app_sf_crypto_captcha_easy_captcha', true); |
|---|
| 1227 |
$this->config['easy_captcha_vowels'] = sfConfig::get('app_sf_crypto_captcha_easy_captcha_vowels', 'AEIOUY'); |
|---|
| 1228 |
$this->config['easy_captcha_consonants'] = sfConfig::get('app_sf_crypto_captcha_easy_captcha_consonants', 'BCDFGHKLMNPRTVWXZ'); |
|---|
| 1229 |
$this->config['easy_captcha_bool'] = rand(0,1); |
|---|
| 1230 |
|
|---|
| 1231 |
//Setting parameters |
|---|
| 1232 |
$this->config['case_sensitive'] = sfConfig::get('app_sf_crypto_captcha_case_sensitive', false); |
|---|
| 1233 |
$this->config['min_chars'] = sfConfig::get('app_sf_crypto_captcha_min_chars', 4); |
|---|
| 1234 |
$this->config['max_chars'] = sfConfig::get('app_sf_crypto_captcha_max_chars', 6); |
|---|
| 1235 |
$this->config['brush_size'] = sfConfig::get('app_sf_crypto_captcha_brush_size', 1); |
|---|
| 1236 |
$this->config['format'] = sfConfig::get('app_sf_crypto_captcha_format', 'png'); |
|---|
| 1237 |
$this->config['hash_algo'] = sfConfig::get('app_sf_crypto_captcha_hash_algo', 'sha1'); |
|---|
| 1238 |
$this->config['flood_timer'] = sfConfig::get('app_sf_crypto_captcha_flood_timer', 0); |
|---|
| 1239 |
//$this->config['flood_error'] = sfConfig::get('app_sf_crypto_captcha_flood_error', 3); // what happens if flood (1=no image, 2=error image, 3=pause) |
|---|
| 1240 |
$this->config['max_refresh'] = sfConfig::get('app_sf_crypto_captcha_max_refresh',1000); |
|---|
| 1241 |
|
|---|
| 1242 |
//Setting effects |
|---|
| 1243 |
$this->config['effect_blur'] = sfConfig::get('app_sf_crypto_captcha_effect_blur', false); |
|---|
| 1244 |
$this->config['effect_greyscale'] = sfConfig::get('app_sf_crypto_captcha_effect_greyscale', false); |
|---|
| 1245 |
|
|---|
| 1246 |
//Setting noise |
|---|
| 1247 |
$this->config['noise_min_px'] = sfConfig::get('app_sf_crypto_captcha_noise_min_px', 200); |
|---|
| 1248 |
$this->config['noise_max_px'] = sfConfig::get('app_sf_crypto_captcha_noise_max_px', 400); |
|---|
| 1249 |
$this->config['noise_min_lines'] = sfConfig::get('app_sf_crypto_captcha_noise_min_lines', 2); |
|---|
| 1250 |
$this->config['noise_max_lines'] = sfConfig::get('app_sf_crypto_captcha_noise_max_lines', 3); |
|---|
| 1251 |
$this->config['noise_min_circles'] = sfConfig::get('app_sf_crypto_captcha_noise_min_circles', 2); |
|---|
| 1252 |
$this->config['noise_max_circles'] = sfConfig::get('app_sf_crypto_captcha_noise_max_circles', 3); |
|---|
| 1253 |
$this->config['noise_color'] = sfConfig::get('app_sf_crypto_captcha_noise_color', 3); |
|---|
| 1254 |
$this->config['noise_on_top'] = sfConfig::get('app_sf_crypto_captcha_noise_on_top', false); |
|---|
| 1255 |
|
|---|
| 1256 |
//error config |
|---|
| 1257 |
$this->config['use_i18n'] = sfConfig::get('sf_i18n', false); |
|---|
| 1258 |
$this->config['error_images_dir'] = sfConfig::get('app_sf_crypto_captcha_error_images_dir', '/plugins/sfCryptoCaptchaPlugin/media/error/'); |
|---|
| 1259 |
$this->config['error_images_dir'] = $root_dir.$this->config['error_images_dir']; |
|---|
| 1260 |
|
|---|
| 1261 |
return true; |
|---|
| 1262 |
} |
|---|
| 1263 |
|
|---|
| 1264 |
} |
|---|
| 1265 |
|
|---|
| 1266 |
|
|---|