width = $w; $this->height = $h; } function GenerateCaptchaImage($rand, $width, $height, $filter_blur = false) { global $site_font_path; global $site_font_validation; $image = imagecreate($width, $height); $bgColor = imagecolorallocate ($image, 255, 255, 255); $textColor = imagecolorallocate ($image, 0, 0, 0); // add random noise for ($i = 0; $i < 20; $i++) { $rx1 = rand(0, $width); $rx2 = rand(0, $width); $ry1 = rand(0, $height); $ry2 = rand(0, $height); $rcVal = rand(0, 255); $rc1 = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(100, 255)); imageline($image, $rx1, $ry1, $rx2, $ry2, $rc1); } // write the random number $dimensions = imagettfbbox($height*0.75, 0, KERNEL_PATH.'/fonts/monofont.ttf', $rand ); imagettftext($image, $height*0.75, 0, floor(($width - $dimensions[4])/2), floor(($height - $dimensions[5])/2), $textColor, KERNEL_PATH.'/fonts/monofont.ttf', $rand); // $font = imageloadfont(KERNEL_PATH.'/fonts/monofont.ttf'); // imagestring($image, $font, 3, 0, $rand, $textColor); if ($filter_blur) $this->blur($image, 3); // send several headers to make sure the image is not cached // date in the past header("Expires: Mon, 23 Jul 1993 05:00:00 GMT"); // always modified header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // HTTP/1.1 header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); // HTTP/1.0 header("Pragma: no-cache"); // send the content type header so the image is displayed properly header('Content-type: image/jpeg'); imagejpeg($image); imagedestroy($image); } function blur(&$gdimg, $radius = 5.0) { // Taken from Torstein Hønsi's phpUnsharpMask (see phpthumb.unsharp.php) $radius = round(max(0, min($radius, 50)) * 2); if (!$radius) { return false; } $w = ImageSX($gdimg); $h = ImageSY($gdimg); $imgBlur = ImageCreateTrueColor($w, $h); if ($imgBlur) { // Gaussian blur matrix: // 1 2 1 // 2 4 2 // 1 2 1 // Move copies of the image around one pixel at the time and merge them with weight // according to the matrix. The same matrix is simply repeated for higher radii. for ($i = 0; $i < $radius; $i++) { ImageCopy ($imgBlur, $gdimg, 0, 0, 1, 1, $w - 1, $h - 1); // up left ImageCopyMerge($imgBlur, $gdimg, 1, 1, 0, 0, $w, $h, 50.00000); // down right ImageCopyMerge($imgBlur, $gdimg, 0, 1, 1, 0, $w - 1, $h, 33.33333); // down left ImageCopyMerge($imgBlur, $gdimg, 1, 0, 0, 1, $w, $h - 1, 25.00000); // up right ImageCopyMerge($imgBlur, $gdimg, 0, 0, 1, 0, $w - 1, $h, 33.33333); // left ImageCopyMerge($imgBlur, $gdimg, 1, 0, 0, 0, $w, $h, 25.00000); // right ImageCopyMerge($imgBlur, $gdimg, 0, 0, 0, 1, $w, $h - 1, 20.00000); // up ImageCopyMerge($imgBlur, $gdimg, 0, 1, 0, 0, $w, $h, 16.666667); // down ImageCopyMerge($imgBlur, $gdimg, 0, 0, 0, 0, $w, $h, 50.000000); // center ImageCopy ($gdimg, $imgBlur, 0, 0, 0, 0, $w, $h); } return true; } return false; } /** * Generates captcha code for showing on form * * @param string $variable_name */ function prepareCode($variable_name) { if ($this->Application->isAdmin || $this->Application->RecallVar($variable_name)) { // when code found don't generate it 2nd time return $this->Application->RecallVar($variable_name); } $code = $this->GenerateCaptchaCode(); $this->Application->StoreVar($variable_name, $code); return $code; } /** * Validates captcha code on form * * @param kEvent $event * @param bool $check_request * @return bool */ function validateCode($event, $check_request = true) { if ($this->Application->isAdmin) { // no captcha codes in admin return true; } if ($check_request) { // perform validation only when field is found on form $field_values = current($this->Application->GetVar($event->getPrefixSpecial())); if (!array_key_exists('Captcha', $field_values)) { // when captcha code not submitted return true; } } /** @var kDBItem $object */ $object = $event->getObject(); $valid_code = $this->Application->RecallVar($event->getPrefixSpecial() . '_captcha_code'); if (!$object->GetDBField('Captcha') || ($object->GetDBField('Captcha') != $valid_code)) { // empty code OR codes doesn't match $object->SetError('Captcha', 'captcha_error', 'lu_captcha_error'); $this->Application->StoreVar($event->getPrefixSpecial() . '_captcha_code', $this->GenerateCaptchaCode()); return false; } return true; } }