diff options
Diffstat (limited to 'applications/core/lib/Zend/Captcha/Image.php')
| -rw-r--r-- | applications/core/lib/Zend/Captcha/Image.php | 594 | 
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/>'; +    } +} | 
