DbHelp.ru
Маленький Yii блог
Комментарии
Гость: фотографии половова акта Рґ...
Гость: Добрый день товарищи! Минеральные удобрения– вещест...
Гость: http://subcutaneous.co/c9e8.html http://subcutaneous.co/82gl.html http://subcutaneous.co/4e6.html ...
Гость: Эта идея устарела ------... [url=https://twitter.com/madsoklj/status/8827207...
Гость: Дипломы ведущих ВУЗов РФ недорого и срочно: Крат...



Сервер Ultima Online - Forest Wars (от создателя данного блога)

Подключаем yii капчу к сайту на другом движке

Рубрика: Работаем с капчей (captcha)

Оцените эту статью:

Рейтинг: 0.00 (0)
6 Апр. 2010
Опубликовать в Twitter Написать в Facebook Опубликовать в своем блоге livejournal.com

Сегодня мы разберем как подключать мою «математическую капчу» на обычный движок php магазина. Название движка я не знаю, да и это не важно, мы просто разберем как вырвать кусок yii и подключать к совершенно не зависимому сайту...

---

Я уже писал подобную статью, но из-за некоторых проблем - решил её написать еще раз.

Раньше форма связи на сайте выглядела следующим образом:

Yii Framework Blog img http://dbhelp.ruccc1

  1. капча с минимальным шумом
  2. размер шрифта постоянно одинаковый
  3. кол-ву символов постоянно одинаково

Заказчик попросил сделать что то другое, т.к. спам боты иногда эту капчу всё таки ломали. Недолго думая я решил присобачить «математическую капчу» которую я писал на Yii. Осталось найти классы которые отвечают за её вывод и выдрать их. (согласитесь, что будет лишним переносить весь фреймворка ради вывода капчи на другом движке, проще пару классов забрать с фреймворка)

Всем известно что именно класс CCaptchaAction отвечает за отображение капчи на экране. Именно в нем генерируется число в капче. Вот так класс выглядит в чистом, не тронутом виде:

<?php
/**
 * CCaptchaAction class file.
 *
 * @author Qiang Xue <[email protected]>
 * @link http://www.yiiframework.com/
 * @copyright Copyright &copy; 2008-2009 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * CCaptchaAction renders a CAPTCHA image.
 *
 * CCaptchaAction is used together with [email protected] CCaptcha} and [email protected] CCaptchaValidator}
 * to provide the [email protected] http://en.wikipedia.org/wiki/Captcha CAPTCHA} feature.
 *
 * You must configure properties of CCaptchaAction to customize the appearance of
 * the generated image.
 *
 * Note, CCaptchaAction requires PHP GD2 extension.
 *
 * Using CAPTCHA involves the following steps:
 * <ol>
 * <li>Override [email protected] CController::actions()} and register an action of class CCaptchaAction with ID 'captcha'.</li>
 * <li>In the form model, declare an attribute to store user-entered verification code, and declare the attribute
 * to be validated by the 'captcha' validator.</li>
 * <li>In the controller view, insert a [email protected] CCaptcha} widget in the form.</li>
 * </ol>
 *
 * @author Qiang Xue <[email protected]>
 * @version $Id: CCaptchaAction.php 726 2009-02-23 02:20:59Z qiang.xue $
 * @package system.web.widgets.captcha
 * @since 1.0
 */
class CCaptchaAction extends CAction
{
    /**
     * The name of the GET parameter indicating whether the CAPTCHA image should be regenerated.
     */
    const REFRESH_GET_VAR='refresh';
    /**
     * Prefix to the session variable name used by the action.
     */
    const SESSION_VAR_PREFIX='Yii.CCaptchaAction.';
    /**
     * @var integer how many times should the same CAPTCHA be displayed. Defaults to 3.
     */
    public $testLimit=3;
    /**
     * @var integer the width of the generated CAPTCHA image. Defaults to 120.
     */
    public $width=120;
    /**
     * @var integer the height of the generated CAPTCHA image. Defaults to 50.
     */
    public $height=50;
    /**
     * @var integer padding around the text. Defaults to 2.
     */
    public $padding=2;
    /**
     * @var integer the background color. For example, 0x55FF00.
     * Defaults to 0xFFFFFF, meaning white color.
     */
    public $backColor=0xFFFFFF;
    /**
     * @var integer the font color. For example, 0x55FF00. Defaults to 0x2040A0 (blue color).
     */
    public $foreColor=0x2040A0;
    /**
     * @var integer the minimum length for randomly generated word. Defaults to 6.
     */
    public $minLength=6;
    /**
     * @var integer the maximum length for randomly generated word. Defaults to 7.
     */
    public $maxLength=7;
    /**
     * @var string the TrueType font file. Defaults to Duality.ttf which is provided
     * with the Yii release.
     */
    public $fontFile;

    /**
     * Runs the action.
     * If the GET parameter [email protected] wsdlVar} exists, the action will serve WSDL content;
     * If not, the action will handle the remote method invocation.
     */
    public function run()
    {
        if(isset($_GET[self::REFRESH_GET_VAR]))  // AJAX request for regenerating code
        {
            $code=$this->getVerifyCode(true);
            // we add a random 'v' parameter so that FireFox can refresh the image
            // when src attribute of image tag is changed
            echo $this->getController()->createUrl($this->getId(),array('v'=>rand(0,10000)));
        }
        else
        {
            $session=Yii::app()->session;
            $session->open();
            $name=$this->getSessionKey().'count';
            if($session[$name]===null || $session[$name]>=$this->testLimit)
                $regenerate=true;
            else
            {
                $session[$name]=$session[$name]+1;
                $regenerate=false;
            }

            $this->renderImage($this->getVerifyCode($regenerate));
            Yii::app()->end();
        }
    }

    /**
     * Gets the verification code.
     * @param string whether the verification code should be regenerated.
     * @return string the verification code.
     */
    public function getVerifyCode($regenerate=false)
    {
        $session=Yii::app()->session;
        $session->open();
        $name=$this->getSessionKey();
        if($session[$name]===null || $regenerate)
        {
            $session[$name]=$this->generateVerifyCode();
            $session[$name.'count']=1;
        }
        return $session[$name];
    }

    /**
     * Validates the input to see if it matches the generated code.
     * @param string user input
     * @param boolean whether the comparison should be case-sensitive
     * @return whether the input is valid
     */
    public function validate($input,$caseSensitive)
    {
        $code=$this->getVerifyCode();
        return $caseSensitive?($input===$code):!strcasecmp($input,$code);
    }

    /**
     * Generates a new verification code.
     * @return string the generated verification code
     */
    protected function generateVerifyCode()
    {
        if($this->minLength<3)
            $this->minLength=3;
        if($this->maxLength>20)
            $this->maxLength=20;
        if($this->minLength>$this->maxLength)
            $this->maxLength=$this->minLength;
        $length=rand($this->minLength,$this->maxLength);

        $letters='bcdfghjklmnpqrstvwxyz';
        $vowels='aeiou';
        $code='';
        for($i=0;$i<$length;++$i)
        {
            if($i%2 && rand(0,10)>2 || !($i%2) && rand(0,10)>9)
                $code.=$vowels[rand(0,4)];
            else
                $code.=$letters[rand(0,20)];
        }

        return $code;
    }

    /**
     * Returns the session variable name used to store verification code.
     * @return string the session variable name
     */
    protected function getSessionKey()
    {
        return self::SESSION_VAR_PREFIX.Yii::app()->getId().'.'.$this->getController()->getUniqueId().'.'.$this->getId();
    }

    /**
     * Renders the CAPTCHA image based on the code.
     * @param string the verification code
     * @return string image content
     */
    protected function renderImage($code)
    {
        $image=imagecreatetruecolor($this->width,$this->height);
        $backColor=imagecolorallocate($image,
            (int)($this->backColor%0x1000000/0x10000),
            (int)($this->backColor%0x10000/0x100),
            $this->backColor%0x100);
        imagefilledrectangle($image,0,0,$this->width,$this->height,$backColor);
        imagecolordeallocate($image,$backColor);

        $foreColor=imagecolorallocate($image,
            (int)($this->foreColor%0x1000000/0x10000),
            (int)($this->foreColor%0x10000/0x100),
            $this->foreColor%0x100);

        if($this->fontFile===null)
            $this->fontFile=dirname(__FILE__).'/Duality.ttf';

        $offset=2;
        $length=strlen($code);
        $box=imagettfbbox(30,0,$this->fontFile,$code);
        $w=$box[4]-$box[0]-$offset*($length-1);
        $h=$box[1]-$box[5];
        $scale=min(($this->width-$this->padding*2)/$w,($this->height-$this->padding*2)/$h);
        $x=10;
        $y=round($this->height*27/40);
        for($i=0;$i<$length;++$i)
        {
            $fontSize=(int)(rand(26,32)*$scale*0.8);
            $angle=rand(-10,10);
            $letter=$code[$i];
            $box=imagettftext($image,$fontSize,$angle,$x,$y,$foreColor,$this->fontFile,$letter);
            $x=$box[2]-$offset;
        }

        imagecolordeallocate($image,$foreColor);

        header('Pragma: public');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Content-Transfer-Encoding: binary');
        header("Content-type: image/png");
        imagepng($image);
        imagedestroy($image);
    }
}

Как видите там есть много всего ненужного. Я не собераюсь переносить весь yii функционал на этот движок, просто хочу иметь возможность:

  1. Через minLength и maxLength изменять сложность выражения.
  2. Через backColor и foreColor изменять цвет фона и букв
  3. Через fontFile изменять шрифт для капчи

Я убрал наследование от CAction и несколько ненужных (на мой взгляд) методов. Получилось достаточно компактно

<?php
/**
 * CCaptchaAction class file.
 *
 * @author Qiang Xue <[email protected]>
 * @link http://www.yiiframework.com/
 * @copyright Copyright &copy; 2008-2009 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * CCaptchaAction renders a CAPTCHA image.
 *
 * CCaptchaAction is used together with [email protected] CCaptcha} and [email protected] CCaptchaValidator}
 * to provide the [email protected] http://en.wikipedia.org/wiki/Captcha CAPTCHA} feature.
 *
 * You must configure properties of CCaptchaAction to customize the appearance of
 * the generated image.
 *
 * Note, CCaptchaAction requires PHP GD2 extension.
 *
 * Using CAPTCHA involves the following steps:
 * <ol>
 * <li>Override [email protected] CController::actions()} and register an action of class CCaptchaAction with ID 'captcha'.</li>
 * <li>In the form model, declare an attribute to store user-entered verification code, and declare the attribute
 * to be validated by the 'captcha' validator.</li>
 * <li>In the controller view, insert a [email protected] CCaptcha} widget in the form.</li>
 * </ol>
 *
 * @author Qiang Xue <[email protected]>
 * @version $Id: CCaptchaAction.php 726 2009-02-23 02:20:59Z qiang.xue $
 * @package system.web.widgets.captcha
 * @since 1.0
 */
class CCaptchaAction
{
    /**
     * The name of the GET parameter indicating whether the CAPTCHA image should be regenerated.
     */
    const REFRESH_GET_VAR='refresh';
    /**
     * Prefix to the session variable name used by the action.
     */
    const SESSION_VAR_PREFIX='Yii.CCaptchaAction.';
    /**
     * @var integer how many times should the same CAPTCHA be displayed. Defaults to 3.
     */
    public $testLimit=1;
    /**
     * @var integer the width of the generated CAPTCHA image. Defaults to 120.
     */
    public $width=200;
    /**
     * @var integer the height of the generated CAPTCHA image. Defaults to 50.
     */
    public $height=75;
    /**
     * @var integer padding around the text. Defaults to 2.
     */
    public $padding=0;
    /**
     * @var integer the background color. For example, 0x55FF00.
     * Defaults to 0xFFFFFF, meaning white color.
     */
    public $backColor=0xFFFFFF;
    /**
     * @var integer the font color. For example, 0x55FF00. Defaults to 0x2040A0 (blue color).
     */
    public $foreColor=0x2040A0;
    /**
     * @var integer the minimum length for randomly generated word. Defaults to 6.
     */
    public $minLength=6;
    /**
     * @var integer the maximum length for randomly generated word. Defaults to 7.
     */
    public $maxLength=7;
    /**
     * @var string the TrueType font file. Defaults to Duality.ttf which is provided
     * with the Yii release.
     */
    public $fontFile;
    
    public $code;

    /**
     * Renders the CAPTCHA image based on the code.
     * @param string the verification code
     * @return string image content
     */
    function renderImage()
    {
    $this->code = $this->generateVerifyCode();
    $code = $this->showCode($this->code);    
    
        $image=imagecreatetruecolor($this->width,$this->height);
        $backColor=imagecolorallocate($image,
            (int)($this->backColor%0x1000000/0x10000),
            (int)($this->backColor%0x10000/0x100),
            $this->backColor%0x100);
        imagefilledrectangle($image,0,0,$this->width,$this->height,$backColor);
        imagecolordeallocate($image,$backColor);

        $foreColor=imagecolorallocate($image,
            (int)($this->foreColor%0x1000000/0x10000),
            (int)($this->foreColor%0x10000/0x100),
            $this->foreColor%0x100);

        if($this->fontFile===null)
            $this->fontFile=dirname(__FILE__).'/Duality.ttf';

        $offset=2;
        $length=strlen($code);
        $box=imagettfbbox(30,0,$this->fontFile,$code);
        $w=$box[4]-$box[0]-$offset*($length-1);
        $h=$box[1]-$box[5];
        $scale=min(($this->width-$this->padding*2)/$w,($this->height-$this->padding*2)/$h);
        $x=10;
        $y=round($this->height*27/40);
        for($i=0;$i<$length;++$i)
        {
            $fontSize=(int)(rand(26,32)*$scale*0.8);
            $angle=rand(-10,10);
            $letter=$code[$i];
            $box=imagettftext($image,$fontSize,$angle,$x,$y,$foreColor,$this->fontFile,$letter);
            $x=$box[2]-$offset;
        }

        imagecolordeallocate($image,$foreColor);

        header('Pragma: public');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Content-Transfer-Encoding: binary');
        header("Content-type: image/png");
        imagepng($image);
        imagedestroy($image);
    }
    
    function showCode($code) {
        $rand = rand(1, (int)$code-1);
        return (rand(0, 1)) ? (int)$code-$rand."+".(int)$rand : (int)$code+$rand."-".(int)$rand;
    }
    
    function generateVerifyCode()
    {
        return rand((int)$this->minLength, (int)$this->maxLength);
    }    
    
}

Этот класс я перенес на хост к движку магазина.

Как вы понимаете в самом магазине уже была капча, поэтому механизм валидации и тп — мне писать не пришлось. Старая капча запоминала код в сессию:

$_SESSION['captcha']

после чего уже сверяла введенный в поле код с тем что сохранен. Поэтому в конце своего класса я добавил что б капча сразу рендерилась на экран и сохраняла значение в сессию:

$abc = new CCaptchaAction();
$abc->renderImage();
session_start();
$_SESSION['captcha'] = $abc->code;

В сумме получился вот такой не большой CCaptchaAction:

<?php
/**
 * CCaptchaAction class file.
 *
 * @author Qiang Xue <[email protected]>
 * @link http://www.yiiframework.com/
 * @copyright Copyright &copy; 2008-2009 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

/**
 * CCaptchaAction renders a CAPTCHA image.
 *
 * CCaptchaAction is used together with [email protected] CCaptcha} and [email protected] CCaptchaValidator}
 * to provide the [email protected] http://en.wikipedia.org/wiki/Captcha CAPTCHA} feature.
 *
 * You must configure properties of CCaptchaAction to customize the appearance of
 * the generated image.
 *
 * Note, CCaptchaAction requires PHP GD2 extension.
 *
 * Using CAPTCHA involves the following steps:
 * <ol>
 * <li>Override [email protected] CController::actions()} and register an action of class CCaptchaAction with ID 'captcha'.</li>
 * <li>In the form model, declare an attribute to store user-entered verification code, and declare the attribute
 * to be validated by the 'captcha' validator.</li>
 * <li>In the controller view, insert a [email protected] CCaptcha} widget in the form.</li>
 * </ol>
 *
 * @author Qiang Xue <[email protected]>
 * @version $Id: CCaptchaAction.php 726 2009-02-23 02:20:59Z qiang.xue $
 * @package system.web.widgets.captcha
 * @since 1.0
 */
class CCaptchaAction
{
    /**
     * The name of the GET parameter indicating whether the CAPTCHA image should be regenerated.
     */
    const REFRESH_GET_VAR='refresh';
    /**
     * Prefix to the session variable name used by the action.
     */
    const SESSION_VAR_PREFIX='Yii.CCaptchaAction.';
    /**
     * @var integer how many times should the same CAPTCHA be displayed. Defaults to 3.
     */
    public $testLimit=1;
    /**
     * @var integer the width of the generated CAPTCHA image. Defaults to 120.
     */
    public $width=200;
    /**
     * @var integer the height of the generated CAPTCHA image. Defaults to 50.
     */
    public $height=75;
    /**
     * @var integer padding around the text. Defaults to 2.
     */
    public $padding=0;
    /**
     * @var integer the background color. For example, 0x55FF00.
     * Defaults to 0xFFFFFF, meaning white color.
     */
    public $backColor=0xFFFFFF;
    /**
     * @var integer the font color. For example, 0x55FF00. Defaults to 0x2040A0 (blue color).
     */
    public $foreColor=0x2040A0;
    /**
     * @var integer the minimum length for randomly generated word. Defaults to 6.
     */
    public $minLength=6;
    /**
     * @var integer the maximum length for randomly generated word. Defaults to 7.
     */
    public $maxLength=7;
    /**
     * @var string the TrueType font file. Defaults to Duality.ttf which is provided
     * with the Yii release.
     */
    public $fontFile;
    
    public $code;

    /**
     * Renders the CAPTCHA image based on the code.
     * @param string the verification code
     * @return string image content
     */
    function renderImage()
    {
    $this->code = $this->generateVerifyCode();
    $code = $this->showCode($this->code);    
    
        $image=imagecreatetruecolor($this->width,$this->height);
        $backColor=imagecolorallocate($image,
            (int)($this->backColor%0x1000000/0x10000),
            (int)($this->backColor%0x10000/0x100),
            $this->backColor%0x100);
        imagefilledrectangle($image,0,0,$this->width,$this->height,$backColor);
        imagecolordeallocate($image,$backColor);

        $foreColor=imagecolorallocate($image,
            (int)($this->foreColor%0x1000000/0x10000),
            (int)($this->foreColor%0x10000/0x100),
            $this->foreColor%0x100);

        if($this->fontFile===null)
            $this->fontFile=dirname(__FILE__).'/Duality.ttf';

        $offset=2;
        $length=strlen($code);
        $box=imagettfbbox(30,0,$this->fontFile,$code);
        $w=$box[4]-$box[0]-$offset*($length-1);
        $h=$box[1]-$box[5];
        $scale=min(($this->width-$this->padding*2)/$w,($this->height-$this->padding*2)/$h);
        $x=10;
        $y=round($this->height*27/40);
        for($i=0;$i<$length;++$i)
        {
            $fontSize=(int)(rand(26,32)*$scale*0.8);
            $angle=rand(-10,10);
            $letter=$code[$i];
            $box=imagettftext($image,$fontSize,$angle,$x,$y,$foreColor,$this->fontFile,$letter);
            $x=$box[2]-$offset;
        }

        imagecolordeallocate($image,$foreColor);

        header('Pragma: public');
        header('Expires: 0');
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Content-Transfer-Encoding: binary');
        header("Content-type: image/png");
        imagepng($image);
        imagedestroy($image);
    }
    
    function showCode($code) {
        $rand = rand(1, (int)$code-1);
        return (rand(0, 1)) ? (int)$code-$rand."+".(int)$rand : (int)$code+$rand."-".(int)$rand;
    }
    
    function generateVerifyCode()
    {
        return rand((int)$this->minLength, (int)$this->maxLength);
    }    
    
}

$abc = new CCaptchaAction();
$abc->renderImage();

session_start();
$_SESSION['captcha'] = $abc->code;

Выглядит это всё вот так:

Yii Framework Blog img http://dbhelp.ruccc2



Если хотите опубликовать этот материал у себя - пожалуйста, разместите ссылку на страницу откуда вы его взяли.
Другие yii статьи:

  1. Последние пару дней я проводил небольшие технические работы на блоге, но всё не было времени запостить тему про всё что ... "Обновление на DbHelp.ru"

  2. Сегодня обнаружил что Sam Dark как и обещал перевел интерисующюю практически всех часть документации про RBAC. next Благодаря таким людям  - ... "Перевод : Аутентификация и авторизация (RBAC)"

  3. Я обычно часто просматриваю гугл сообщества в поисках чего-то нового (статьи, вопросы) и сам являюсь активным участником групп по ... "Сообщество Google"

[adm] zolter

Было сказано: Вторник, 06 Апрель 2010

Как и обещал, написал снова статью которая удалилась в день пожара

[guest] snnwolf

Было сказано: Среда, 07 Апрель 2010

Спасибо! Очень полезная штучка... :)

[guest] levik

Было сказано: Пятница, 23 Июль 2010

похоже, в этом блоге именно такая капча стоит :)

[guest] Гость

Было сказано: Четверг, 12 Январь 2012

<script>alert('');</script>

[guest] Гость

Было сказано: Четверг, 12 Январь 2012

&lt;script&gt;alert('');&lt;\/script&gt;

[guest] zolter

Было сказано: Четверг, 12 Январь 2012

ой ой, какие читеры нашлись :D

[guest] Гость

Было сказано: Среда, 31 Июль 2013

uyiu

[guest] Гость

Было сказано: Вторник, 31 Январь 2017

<a href="http://102hp.ru/bolshie-siski/krasivaya-devushka-na-massazhe-poluchaet-udovolstvie-ot-lask"&gt;Красивая девушка на массаже получает удовольствие от ласк</a>

http://1b1b.ru/%D0%BC%D0%B5%D0%B6%D1%80%D0%B0%D1%81%D1%81%D0%BE%D0%B2%D0%BE%D0%B5/sandra-romain-%D1%80%D0%BE%D1%81%D1%82-%D0%B2%D0%B5%D1%81 - sandra romain рост вес

[guest] Гость

Было сказано: Понедельник, 27 Февраль 2017

<a href="http://utebayuutebayu.trade/buying-in-amazon-with-paypal"&gt;buying in amazon with paypal</a>
<a href="http://yisunodoyisunodo.racing/where-to-buy-self-raising-flour-in-malaysia-movie"&gt;where to buy self raising flour in malaysia movie</a>
<a href="http://vogamevogame.party/monroe-mega-dangler-buy-a-car"&gt;monroe mega dangler buy a car</a>
<a href="http://vogamevogame.party/buy-nike-mercurial-superfly-cheap"&gt;buy nike mercurial superfly cheap</a>
<a href="http://mukezupomukezupo.accountant/de-buyer-non-stick-review"&gt;de buyer non stick review</a>

Оставить комментарий


Код:
Имя: