summaryrefslogtreecommitdiff
path: root/applications/core/lib/Zend/Captcha/Image.php
diff options
Diffstat (limited to 'applications/core/lib/Zend/Captcha/Image.php')
-rw-r--r--applications/core/lib/Zend/Captcha/Image.php594
1 files changed, 594 insertions, 0 deletions
diff --git a/applications/core/lib/Zend/Captcha/Image.php b/applications/core/lib/Zend/Captcha/Image.php
new file mode 100644
index 0000000..98cbd0b
--- /dev/null
+++ b/applications/core/lib/Zend/Captcha/Image.php
@@ -0,0 +1,594 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to [email protected] so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Captcha
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id: Image.php 14290 2009-03-13 12:40:14Z alexander $
+ */
+
+/** Zend_Captcha_Word */
+require_once 'Zend/Captcha/Word.php';
+
+/**
+ * Image-based captcha element
+ *
+ * Generates image displaying random word
+ *
+ * @category Zend
+ * @package Zend_Captcha
+ * @subpackage Adapter
+ * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Captcha_Image extends Zend_Captcha_Word
+{
+ /**
+ * Directory for generated images
+ *
+ * @var string
+ */
+ protected $_imgDir = "./images/captcha/";
+
+ /**
+ * URL for accessing images
+ *
+ * @var string
+ */
+ protected $_imgUrl = "/images/captcha/";
+
+ /**
+ * Image's alt tag content
+ *
+ * @var string
+ */
+ protected $_imgAlt = "";
+
+ /**
+ * Image suffix (including dot)
+ *
+ * @var string
+ */
+ protected $_suffix = ".png";
+
+ /**
+ * Image width
+ *
+ * @var int
+ */
+ protected $_width = 200;
+
+ /**
+ * Image height
+ *
+ * @var int
+ */
+ protected $_height = 50;
+
+ /**
+ * Font size
+ *
+ * @var int
+ */
+ protected $_fsize = 24;
+
+ /**
+ * Image font file
+ *
+ * @var string
+ */
+ protected $_font;
+
+ /**
+ * Image to use as starting point
+ * Default is blank image. If ptovided, should be PNG image.
+ *
+ * @var string
+ */
+ protected $_startImage;
+ /**
+ * How frequently to execute garbage collection
+ *
+ * @var int
+ */
+ protected $_gcFreq = 10;
+
+ /**
+ * How long to keep generated images
+ *
+ * @var int
+ */
+ protected $_expiration = 600;
+
+ /**
+ * Number of noise dots on image
+ * Used twice - before and after transform
+ *
+ * @var int
+ */
+ protected $_dotNoiseLevel = 100;
+ /**
+ * Number of noise lines on image
+ * Used twice - before and after transform
+ *
+ * @var int
+ */
+ protected $_lineNoiseLevel = 5;
+ /**
+ * @return string
+ */
+ public function getImgAlt ()
+ {
+ return $this->_imgAlt;
+ }
+ /**
+ * @return string
+ */
+ public function getStartImage ()
+ {
+ return $this->_startImage;
+ }
+ /**
+ * @return int
+ */
+ public function getDotNoiseLevel ()
+ {
+ return $this->_dotNoiseLevel;
+ }
+ /**
+ * @return int
+ */
+ public function getLineNoiseLevel ()
+ {
+ return $this->_lineNoiseLevel;
+ }
+ /**
+ * Get captcha expiration
+ *
+ * @return int
+ */
+ public function getExpiration()
+ {
+ return $this->_expiration;
+ }
+
+ /**
+ * Get garbage collection frequency
+ *
+ * @return int
+ */
+ public function getGcFreq()
+ {
+ return $this->_gcFreq;
+ }
+ /**
+ * Get font to use when generating captcha
+ *
+ * @return string
+ */
+ public function getFont()
+ {
+ return $this->_font;
+ }
+
+ /**
+ * Get font size
+ *
+ * @return int
+ */
+ public function getFontSize()
+ {
+ return $this->_fsize;
+ }
+
+ /**
+ * Get captcha image height
+ *
+ * @return int
+ */
+ public function getHeight()
+ {
+ return $this->_height;
+ }
+
+ /**
+ * Get captcha image directory
+ *
+ * @return string
+ */
+ public function getImgDir()
+ {
+ return $this->_imgDir;
+ }
+ /**
+ * Get captcha image base URL
+ *
+ * @return string
+ */
+ public function getImgUrl()
+ {
+ return $this->_imgUrl;
+ }
+ /**
+ * Get captcha image file suffix
+ *
+ * @return string
+ */
+ public function getSuffix()
+ {
+ return $this->_suffix;
+ }
+ /**
+ * Get captcha image width
+ *
+ * @return int
+ */
+ public function getWidth()
+ {
+ return $this->_width;
+ }
+ /**
+ * @param string $startImage
+ */
+ public function setStartImage ($startImage)
+ {
+ $this->_startImage = $startImage;
+ return $this;
+ }
+ /**
+ * @param int $dotNoiseLevel
+ */
+ public function setDotNoiseLevel ($dotNoiseLevel)
+ {
+ $this->_dotNoiseLevel = $dotNoiseLevel;
+ return $this;
+ }
+ /**
+ * @param int $lineNoiseLevel
+ */
+ public function setLineNoiseLevel ($lineNoiseLevel)
+ {
+ $this->_lineNoiseLevel = $lineNoiseLevel;
+ return $this;
+ }
+
+ /**
+ * Set captcha expiration
+ *
+ * @param int $expiration
+ * @return Zend_Captcha_Image
+ */
+ public function setExpiration($expiration)
+ {
+ $this->_expiration = $expiration;
+ return $this;
+ }
+
+ /**
+ * Set garbage collection frequency
+ *
+ * @param int $gcFreq
+ * @return Zend_Captcha_Image
+ */
+ public function setGcFreq($gcFreq)
+ {
+ $this->_gcFreq = $gcFreq;
+ return $this;
+ }
+
+ /**
+ * Set captcha font
+ *
+ * @param string $font
+ * @return Zend_Captcha_Image
+ */
+ public function setFont($font)
+ {
+ $this->_font = $font;
+ return $this;
+ }
+
+ /**
+ * Set captcha font size
+ *
+ * @param int $fsize
+ * @return Zend_Captcha_Image
+ */
+ public function setFontSize($fsize)
+ {
+ $this->_fsize = $fsize;
+ return $this;
+ }
+
+ /**
+ * Set captcha image height
+ *
+ * @param int $height
+ * @return Zend_Captcha_Image
+ */
+ public function setHeight($height)
+ {
+ $this->_height = $height;
+ return $this;
+ }
+
+ /**
+ * Set captcha image storage directory
+ *
+ * @param string $imgDir
+ * @return Zend_Captcha_Image
+ */
+ public function setImgDir($imgDir)
+ {
+ $this->_imgDir = rtrim($imgDir, "/\\") . '/';
+ return $this;
+ }
+
+ /**
+ * Set captcha image base URL
+ *
+ * @param string $imgUrl
+ * @return Zend_Captcha_Image
+ */
+ public function setImgUrl($imgUrl)
+ {
+ $this->_imgUrl = rtrim($imgUrl, "/\\") . '/';
+ return $this;
+ }
+ /**
+ * @param string $imgAlt
+ */
+ public function setImgAlt ($imgAlt)
+ {
+ $this->_imgAlt = $imgAlt;
+ return $this;
+ }
+
+ /**
+ * Set captch image filename suffix
+ *
+ * @param string $suffix
+ * @return Zend_Captcha_Image
+ */
+ public function setSuffix($suffix)
+ {
+ $this->_suffix = $suffix;
+ return $this;
+ }
+
+ /**
+ * Set captcha image width
+ *
+ * @param int $width
+ * @return Zend_Captcha_Image
+ */
+ public function setWidth($width)
+ {
+ $this->_width = $width;
+ return $this;
+ }
+
+ /**
+ * Generate random frequency
+ *
+ * @return float
+ */
+ protected function _randomFreq()
+ {
+ return mt_rand(700000, 1000000) / 15000000;
+ }
+
+ /**
+ * Generate random phase
+ *
+ * @return float
+ */
+ protected function _randomPhase()
+ {
+ // random phase from 0 to pi
+ return mt_rand(0, 3141592) / 1000000;
+ }
+
+ /**
+ * Generate random character size
+ *
+ * @return int
+ */
+ protected function _randomSize()
+ {
+ return mt_rand(300, 700) / 100;
+ }
+
+ /**
+ * Generate captcha
+ *
+ * @return string captcha ID
+ */
+ public function generate()
+ {
+ $id = parent::generate();
+ $this->_generateImage($id, $this->getWord());
+
+ if (mt_rand(1, $this->getGcFreq()) == 1) {
+ $this->_gc();
+ }
+ return $id;
+ }
+
+ /**
+ * Generate image captcha
+ *
+ * Override this function if you want different image generator
+ * Wave transform from http://www.captcha.ru/captchas/multiwave/
+ *
+ * @param string $id Captcha ID
+ * @param string $word Captcha word
+ */
+ protected function _generateImage($id, $word)
+ {
+ if (!extension_loaded("gd")) {
+ require_once 'Zend/Captcha/Exception.php';
+ throw new Zend_Captcha_Exception("Image CAPTCHA requires GD extension");
+ }
+
+ if (!function_exists("imagepng")) {
+ require_once 'Zend/Captcha/Exception.php';
+ throw new Zend_Captcha_Exception("Image CAPTCHA requires PNG support");
+ }
+
+ if (!function_exists("imageftbbox")) {
+ require_once 'Zend/Captcha/Exception.php';
+ throw new Zend_Captcha_Exception("Image CAPTCHA requires FT fonts support");
+ }
+
+ $font = $this->getFont();
+
+ if (empty($font)) {
+ require_once 'Zend/Captcha/Exception.php';
+ throw new Zend_Captcha_Exception("Image CAPTCHA requires font");
+ }
+
+ $w = $this->getWidth();
+ $h = $this->getHeight();
+ $fsize = $this->getFontSize();
+
+ $img_file = $this->getImgDir() . $id . $this->getSuffix();
+ if(empty($this->_startImage)) {
+ $img = imagecreatetruecolor($w, $h);
+ } else {
+ $img = imagecreatefrompng($this->_startImage);
+ if(!$img) {
+ require_once 'Zend/Captcha/Exception.php';
+ throw new Zend_Captcha_Exception("Can not load start image");
+ }
+ $w = imagesx($img);
+ $h = imagesy($img);
+ }
+ $text_color = imagecolorallocate($img, 0, 0, 0);
+ $bg_color = imagecolorallocate($img, 255, 255, 255);
+ imagefilledrectangle($img, 0, 0, $w-1, $h-1, $bg_color);
+ $textbox = imageftbbox($fsize, 0, $font, $word);
+ $x = ($w - ($textbox[2] - $textbox[0])) / 2;
+ $y = ($h - ($textbox[7] - $textbox[1])) / 2;
+ imagefttext($img, $fsize, 0, $x, $y, $text_color, $font, $word);
+
+ // generate noise
+ for ($i=0; $i<$this->_dotNoiseLevel; $i++) {
+ imagefilledellipse($img, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color);
+ }
+ for($i=0; $i<$this->_lineNoiseLevel; $i++) {
+ imageline($img, mt_rand(0,$w), mt_rand(0,$h), mt_rand(0,$w), mt_rand(0,$h), $text_color);
+ }
+
+ // transformed image
+ $img2 = imagecreatetruecolor($w, $h);
+ $bg_color = imagecolorallocate($img2, 255, 255, 255);
+ imagefilledrectangle($img2, 0, 0, $w-1, $h-1, $bg_color);
+ // apply wave transforms
+ $freq1 = $this->_randomFreq();
+ $freq2 = $this->_randomFreq();
+ $freq3 = $this->_randomFreq();
+ $freq4 = $this->_randomFreq();
+
+ $ph1 = $this->_randomPhase();
+ $ph2 = $this->_randomPhase();
+ $ph3 = $this->_randomPhase();
+ $ph4 = $this->_randomPhase();
+
+ $szx = $this->_randomSize();
+ $szy = $this->_randomSize();
+
+ for ($x = 0; $x < $w; $x++) {
+ for ($y = 0; $y < $h; $y++) {
+ $sx = $x + (sin($x*$freq1 + $ph1) + sin($y*$freq3 + $ph3)) * $szx;
+ $sy = $y + (sin($x*$freq2 + $ph2) + sin($y*$freq4 + $ph4)) * $szy;
+
+ if ($sx < 0 || $sy < 0 || $sx >= $w - 1 || $sy >= $h - 1) {
+ continue;
+ } else {
+ $color = (imagecolorat($img, $sx, $sy) >> 16) & 0xFF;
+ $color_x = (imagecolorat($img, $sx + 1, $sy) >> 16) & 0xFF;
+ $color_y = (imagecolorat($img, $sx, $sy + 1) >> 16) & 0xFF;
+ $color_xy = (imagecolorat($img, $sx + 1, $sy + 1) >> 16) & 0xFF;
+ }
+ if ($color == 255 && $color_x == 255 && $color_y == 255 && $color_xy == 255) {
+ // ignore background
+ continue;
+ } elseif ($color == 0 && $color_x == 0 && $color_y == 0 && $color_xy == 0) {
+ // transfer inside of the image as-is
+ $newcolor = 0;
+ } else {
+ // do antialiasing for border items
+ $frac_x = $sx-floor($sx);
+ $frac_y = $sy-floor($sy);
+ $frac_x1 = 1-$frac_x;
+ $frac_y1 = 1-$frac_y;
+
+ $newcolor = $color * $frac_x1 * $frac_y1
+ + $color_x * $frac_x * $frac_y1
+ + $color_y * $frac_x1 * $frac_y
+ + $color_xy * $frac_x * $frac_y;
+ }
+ imagesetpixel($img2, $x, $y, imagecolorallocate($img2, $newcolor, $newcolor, $newcolor));
+ }
+ }
+
+ // generate noise
+ for ($i=0; $i<$this->_dotNoiseLevel; $i++) {
+ imagefilledellipse($img2, mt_rand(0,$w), mt_rand(0,$h), 2, 2, $text_color);
+ }
+ for ($i=0; $i<$this->_lineNoiseLevel; $i++) {
+ imageline($img2, mt_rand(0,$w), mt_rand(0,$h), mt_rand(0,$w), mt_rand(0,$h), $text_color);
+ }
+
+ imagepng($img2, $img_file);
+ imagedestroy($img);
+ imagedestroy($img2);
+ }
+
+ /**
+ * Remove old files from image directory
+ *
+ */
+ protected function _gc()
+ {
+ $expire = time() - $this->getExpiration();
+ $imgdir = $this->getImgDir();
+ if(!$imgdir || strlen($imgdir) < 2) {
+ // safety guard
+ return;
+ }
+ foreach (new DirectoryIterator($imgdir) as $file) {
+ if (!$file->isDot() && !$file->isDir()) {
+ if ($file->getMTime() < $expire) {
+ unlink($file->getPathname());
+ }
+ }
+ }
+ }
+
+ /**
+ * Display the captcha
+ *
+ * @param Zend_View_Interface $view
+ * @param mixed $element
+ * @return string
+ */
+ public function render(Zend_View_Interface $view, $element = null)
+ {
+ return '<img alt="'.$this->getImgAlt().'" src="' . $this->getImgUrl() . $this->getId() . $this->getSuffix() . '"/><br/>';
+ }
+}