Create Captcha Image with Zend_Dojo

Users usually see the captcha and are asked to type the same in order to prove their truth when they are just going to take the registration.

 

Zend_Captcha in Zend Framework provides this kind of functionalities. Especially Zend_Captcha_Image which allow to show the words within an image has really made it easy.

 

See example below :

 

 

Now what I want to achieve is to change the image and its words on every time we click on the image without reloading the whole page. Just like what we do on the registration of BBS.

 

We have to prepare some things before start doing anything. First of all is to download your favourite font (.ttf) from any free of charge font-site. And here I choose a font called Faktos and put it under "public/fonts/faktos/" :

 

 

It’s the default font style of the words.

 

Second, we need the folder to store the images. For example in "public/img/captcha/" :

 

 

Ok let’s start coding. The script below is based on Zend_Dojo, which provide the powerful ajax support from Dojo toolkit. The first script is IndexController.php, the other one is index.phtml and that’s all we need.

 

[codesyntax lang=”php”]

// IndexController.php
class IndexController extends Zend_Controller_Action
{
    // create the form and its captcha image
    public function indexAction()
    {
        $form = new Zend_Form();
        $captcha = $this->createCaptcha();
        $form->addElement($captcha);
        $this->view->captchaImageUrl = $captcha->getCaptcha()->getImgUrl()
                                     . $captcha->getCaptcha()->getId()
                                     . $captcha->getCaptcha()->getSuffix();

        $this->view->formLogin = $form->render();
    }

    // Ajax : echo the new src of new image
    public function ajaxAction()
    {
        $captcha = $this->createCaptcha()->getCaptcha();
        $captcha->generate();
        echo $captcha->getImgUrl() . $captcha->getId() . $captcha->getSuffix();
        die;
    }

    // create the captcha element
    public function createCaptcha()
    {
        // decorator of captcha image, we add id and onclick()
        $decorators = array(
            array('HtmlTag', array('tag' => 'div',
                                   'id' => 'captchaId',
                                   'onclick' => 'changeImage()'))
        );

        $form = new Zend_Form();

        // Zend_Captcha_Image : images are saved in public/img/captcha/
        $captcha = $form->createElement('captcha', 'captcha', array(
            'captcha' => array(  
                'captcha' => 'Image',
                'wordLen' => 6,
                'fontsize' => 20,
                'width' => 200,
                'height' => 100,
                'dotNoiseLevel' => 2,
                'timeout' => 300,  
                'font' => 'fonts/faktos/Faktos.ttf',
                'imgDir' => './img/captcha/',
                'imgUrl' => '/img/captcha/',
            ),
            'decorators' => $decorators
        ));

        return $captcha;
    }
}

[/codesyntax]

 

We use CDN 1.3.1 ver. of Dojo and as a result no need for other operations, just copy and paste then you will see the result.

 

[codesyntax lang=”php”]

// index.phtml
<?php
// use latest version of Dojo through CDN, and make some configs
$this->dojo()->enable()
             ->setCdnVersion('1.3.1')
             ->setDjConfigOption('parseOnLoad', true)
             ->setDjConfigOption('isDebug', false)
             ->setDjConfigOption('locale', 'zh');

// echo the Dojo, we can also put it to the top of page 
echo $this->dojo();
?>

<script type="text/javascript">
    // change image
    function changeImage()
    {
        // do not change it if we click the input box
        if (document.activeElement.id == 'captcha-input') {
            return false;         
        }

        // Dojo - ajax get
        dojo.xhrGet( {
            // Url called
            url: "/index/ajax",

            // handle the response as text
            handleAs: "text",

            // timeout in microseconds
            timeout: 5000,

            // call load function when successful
            load: function(response, ioArgs) {
                // find the original image src and replace it by new one
                dojo.query("img", document.getElementById("captchaId")).forEach(
                    function(selectTag) {
                        if (selectTag.src.indexOf("<?php echo $this->captchaImageUrl; ?>")) {
                            selectTag.src = response;
                        }
                    }
                );
                return response;
            },

            // when error occurs
            error: function(response, ioArgs) {
                console.error("HTTP status code: ", ioArgs.xhr.status);
                return response;
            }
        });
    }
</script>

<?php
// echo the form
echo $this->formLogin;
?>

[/codesyntax]

 

It’s very simple and practical !

 

Posted in Zend Framework | Tagged , | Leave a comment