Zend Framework/Zend Captcha/Ejemplo básico

Introducción

editar

En este veremos como utilizar Captcha con las herramientas que nos ofrece Zend Framework. Utilizaremos la clase Zend_Captcha_Image. Para esto necesitamos:

  • Tener GD instalado en la copia de php.
  • Crear la carpeta que va a contener las imágenes de captcha. En nuestro ejemplo: /application/resources/images/captcha/.
  • Crear el método generateCaptcha().Este método recibe dos parámetros, el path al archivo de la fuente (en nuestro ejemplo es /application/resources/fonts/arial.ttf), y el path a la carpeta de imágenes de captcha.

Se instancia Zend_Captcha_Image, se setean algunos parámetros de información básica, se crea la imagen, y devuelve el id de esta.

    private function generateCaptcha($psFontPath, $psImgPath)
    {
      $captcha = new Zend_Captcha_Image();
      $captcha->setTimeout('300')
    	      ->setWordLen('6')
    	      ->setHeight('60')
    	      ->setFont($psFontPath)
    	      ->setImgDir($psImgPath);
      $captcha->g
    		$captchaInput = $captcha['input'];
    		$captchaSession = new Zend_Session_Namespace('Zend_Form_Captcha_' . $captchaId);
    		$captchaIterator = $captchaSession->getIterator();
    		$captchaWord = $captchaIterator['word'];
    		if( $captchaInput != $captchaWord ){
    			return false;
    		} else {
    			return true;
    		}
    } 
  • Crear la página con el formulario, en nuestro ejemplo index.phtml
<h1>Valida Captcha</h1>
<div>
   	<div>
   		<b>
   		<? if ( count($this->mensajes) > 0)
   				 {
   					foreach ($this->mensajes as $msg) {
   						echo $msg.'<br>';
   					}
   				 }
   		?>
   		</b>
   	</div>
   	<div>		
		<form action="<?=$this->baseUrl()?>/index/validar-captcha" method="post">
    		<label for="captcha">Ingrese el codigo:
    			<input type="hidden" value="<?=$this->captchaId ?>" name="id_captcha"/>
    			<img src="/zft-captcha/application/resources/images/captcha/<?=$this->captchaId ?>.png" alt=""/>
    			<input type="text" name="input_captcha" />
    		</label>
    		<input type="submit" value="Enviar"/>
		</form>
	</div>
</div>

Estructura de archivos

editar

La estructura de los archivos será al siguiente

Archivo:Zft captcha basico.png

/html/index.php

editar

Breve descripción del archivo

Plantilla:Zf /html/index.php

<?php
/**
 * Zend Framework Tutorial
 * 
 * Este tutorial tiene un enfoque pragmatico, lo cual indica una amplia cantidad
 * de ejemplos. Este material forma parte del Wikibook en español para ZF.
 * 
 * @author Mario Garcia
 * @copyright  Copyright (c) 2006-2008 Oh!Studio Media Solutions (http://www.ohstudio.com.ar)
 * @license    http://www.php.net/license/3_0.txt
 */

/*poner comentario*/


define('ROOT_DIR', dirname(dirname(__FILE__)));

// Setup path to the Zend Framework files
set_include_path('.'
	. PATH_SEPARATOR . ROOT_DIR.'/lib/'
	. PATH_SEPARATOR . get_include_path()
);

require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();

// Inicializar el MVC
Zend_Layout::startMvc(array('layoutPath' => ROOT_DIR.'/application/views/layouts'));

// Run!
$frontController = Zend_Controller_Front::getInstance();
$frontController->addControllerDirectory(ROOT_DIR.'/application/controllers');
$frontController->throwExceptions(true);
try {
    $frontController->dispatch();
} catch(Exception $e) {
    echo nl2br($e->__toString());
}


/html/.htaccess

editar

Breve descripción del archivo

Este archivo me permite determinar que todo archivo que no sea una imagen, ni js, ni css sea redireccionado hacia index.php.

RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php


/html/css/grid.css

editar

Breve descripción del archivo

Este archivo forma parte del layout #/application/views/layouts/layout.phtml.

Aquí le aplicamos el estilo para la distribución de las secciones.

/* Site Grid by BoxedCSS.com */

#bcss-header {

	width:100%;

	background:#FFFFE5; /* you can delete this, it's just a visual aid */

	clear:both;

	}

#bcss-sidebar-1 {

	width:27%;

	float:left;

	background:#FFE5FF; /* you can delete this, it's just a visual aid */

	}

#bcss-sidebar-2 {

	width:13%;

	float:left;

	background:#F7FBEA; /* you can delete this, it's just a visual aid */

	}

#bcss-content {

	width:60%;

	min-height: 400px;

	float:left;

	background:#E5F2FF; /* you can delete this, it's just a visual aid */

	}

#bcss-footer {

	width:100%;

	clear:both;

	background:#FFF2E5; /* you can delete this, it's just a visual aid */

	}



/application/controllers/IndexController.php

editar

Breve descripción del archivo

Este es el controlador por defecto que se invoca en el caso de no especificar que controlador utilizar. Aqui podemos ver las acciones que el mismo puede realizar.

<?php
/**
 * Zend Framework Tutorial
 * 
 * Este tutorial tiene un enfoque pragmatico, lo cual indica una amplia cantidad
 * de ejemplos. Este material forma parte del Wikibook en español para ZF.
 * 
 * @author Mario Garcia
 * @copyright  Copyright (c) 2006-2008 Oh!Studio Media Solutions (http://www.ohstudio.com.ar)
 * @license    http://www.php.net/license/3_0.txt
 */


class IndexController extends Zend_Controller_Action
{
	

	function init()
    {
    	

        $response = $this->getResponse();
        $response->insert('sidebarLeft', $this->view->render('sidebarLeft.phtml'));
        $response->insert('sidebarRight', $this->view->render('sidebarRight.phtml'));
        $response->insert('header', $this->view->render('header.phtml'));
        $response->insert('footer', $this->view->render('footer.phtml')); 
        $this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');
    }
    
    

    public function indexAction()
    {
        $lsFontPath = ROOT_DIR. '/application/resources/fonts/arial.ttf';
    	$lsImgPath = ROOT_DIR. '/application/resources/images/captcha';

    	$this->view->captchaId = $this->generateCaptcha($lsFontPath, $lsImgPath);
    	$this->view->envio = $this->_request->getParam('envio');
    	$this->view->mensajes = $this->_flashMessenger->getMessages();        
    }
    
    public function validarCaptchaAction()
    {
    	$lsIdCaptcha = $this->_request->getParam('id_captcha');
        $lsInputCaptcha = $this->_request->getParam('input_captcha');

		$laCaptcha = array('id' => $lsIdCaptcha, 'input' => $lsInputCaptcha);
		if(!$this->validateCaptcha($laCaptcha))
		{
		    $this->_helper->_flashMessenger->addMessage('El código ingresado no coincide con el de la imagen.');
		}
		else
		{
   		    $this->_helper->_flashMessenger->addMessage('El código ingresado es correcto!!!');
		}

		$this->_redirector = $this->_helper->getHelper('Redirector');
		$this->_redirector->gotoUrl('/index/index');		
        
    }
    
    /*     
     * Método para utilización de captcha. Genera session, crea la imagen y devuelve el id.
     *
     * @param string $psFontPath Path del archivo de la fuente
     * @param string $psImgPath Path del archivo de la carpeta de imagenes captcha
     * @return string
     */
    private function generateCaptcha($psFontPath, $psImgPath)
    {
    
      $captcha = new Zend_Captcha_Image();
    
      $captcha->setTimeout('300')
    	      ->setWordLen('6')
    	      ->setHeight('60')
    	      ->setFont($psFontPath)
    	      ->setImgDir($psImgPath);
    
      $captcha->generate();    //genera session y crea imagen
    
      return $captcha->getId();   //devuelve el ID
    
    }
    
    /**
     * Valida el captcha
     *
     * @param array $captcha
     * @return boolean
     */
    private function validateCaptcha($captcha)
    {
    		$captchaId = $captcha['id'];
    		$captchaInput = $captcha['input'];
    		$captchaSession = new Zend_Session_Namespace('Zend_Form_Captcha_' . $captchaId);
    		$captchaIterator = $captchaSession->getIterator();
    		$captchaWord = $captchaIterator['word'];
    		if( $captchaInput != $captchaWord ){
    			return false;
    		} else {
    			return true;
    		}
    }    

}    


/application/views/scripts/sidebarRight.phtml

editar

Breve descripción del archivo

Este archivo forma parte del layout #/application/views/layouts/layout.phtml.

Esta sección incluye el contenido de la parte lateral derecha del layout.

<h1>Sidebar Right</h1>


/application/views/scripts/footer.phtml

editar

Breve descripción del archivo

Este archivo forma parte del layout #/application/views/layouts/layout.phtml.

Esta sección incluye el contenido del pie del layout.

<h1>Footer</h1>


/application/views/scripts/header.phtml

editar

Breve descripción del archivo

Este archivo forma parte del layout #/application/views/layouts/layout.phtml.

Esta sección incluye el contenido del encabezado del layout.

<h1>Header</h1>


/application/views/scripts/sidebarLeft.phtml

editar

Breve descripción del archivo

Este archivo forma parte del layout #/application/views/layouts/layout.phtml.

Esta sección incluye el contenido de la parte lateral izquierda del layout.

<ul>
<li><a href="<?php echo $this->baseUrl();?>/index/index">home</a></li>
<li><a href="http://www.google.com">google</a></li>
</ul>


/application/views/scripts/index/index.phtml

editar

Breve descripción del archivo

Este archivo forma parte del layout #/application/views/layouts/layout.phtml.

Esta sección incluye el contenido de la accion que se esta ejecutando.

<h1>Valida Captcha</h1>
<div>
   	<div>
   		<b>
   		<? if ( count($this->mensajes) > 0)
   				 {
   					foreach ($this->mensajes as $msg) {
   						echo $msg.'<br>';
   					}
   				 }
   		?>
   		</b>
   	</div>
   	<div>		
		<form action="<?=$this->baseUrl()?>/index/validar-captcha" method="post">
    		<label for="captcha">Ingrese el codigo:
    			<input type="hidden" value="<?=$this->captchaId ?>" name="id_captcha"/>
    			<img src="/zft-captcha/application/resources/images/captcha/<?=$this->captchaId ?>.png" alt=""/>
    			<input type="text" name="input_captcha" />
    		</label>
    		<input type="submit" value="Enviar"/>
		</form>
	</div>
</div>


/application/views/layouts/layout.phtml

editar

Breve descripción del archivo

Esta pagina nos permite definir la estructura del sitio, es decir su distribucion topografica, como ser si dispone de un encabezado, pie de pagina, barra lateral izquierada, barra lateral derecha y donde residira el contenido de la accion que se esta ejecutando actualmente.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
					"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<title>ZFTutorial :: Enfoque pragmatico</title>
    <link rel="stylesheet" type="text/css" href="<?php echo $this->baseUrl();?>/css/grid.css" />
</head>
<body>
	<div id="bcss-header">
    <!-- bcss-header -->
	<?php echo $this->layout()->header ?>
    <!-- /bcss-header -->
	</div>
	
	<div id="bcss-sidebar-1">
    <!-- bcss-sidebar-1 -->
	<?php echo $this->layout()->sidebarLeft ?>
    <!-- /bcss-sidebar-1 -->
 	</div>
 	
	<div id="bcss-content">
    <!-- bcss-content -->
	<?php echo $this->layout()->content ?>
    <!-- /bcss-content -->	
	</div>
	
	<div id="bcss-sidebar-2">
    <!-- bcss-sidebar-2 -->
	<?php echo $this->layout()->sidebarRight ?>
    <!-- /bcss-sidebar-2 -->	
 	</div>
 	
	<div id="bcss-footer">
    <!-- bcss-footer -->
	<?php echo $this->layout()->footer ?>
    <!-- /bcss-footer -->	
	</div>
</body>
</html>


/application/views/helpers/BaseUrl.php

editar

Breve descripción del archivo

Este helper me permite determinar en forma absoluta la url base de la aplicación.

<?php
/**
 * Zend Framework Tutorial
 * 
 * Este tutorial tiene un enfoque pragmatico, lo cual indica una amplia cantidad
 * de ejemplos. Este material forma parte del Wikibook en español para ZF.
 * 
 * @author Mario Garcia
 * @copyright  Copyright (c) 2006-2008 Oh!Studio Media Solutions (http://www.ohstudio.com.ar)
 * @license    http://www.php.net/license/3_0.txt
 */


class Zend_View_Helper_BaseUrl
{
	
    function baseUrl()
    {
        $fc = Zend_Controller_Front::getInstance();
        $request = $fc->getRequest();
        return $request->getBaseUrl();
    }
}