Validar formularios en Zend Framework 2

A la hora de validar formularios en Zend Framework 2 tenemos dos opciones:
• Validación clásica a través de métodos llamados de forma manual.
• Generando reglas de validación asociadas al formulario.

Validación de datos sencilla

Esta forma de validar es muy similar a como lo hace Codeigniter, es muy sencilla, y puede ser muy útil cuando los formularios por cualquier cuestión han sido creados manualmente o nos interesa validar algún dato aislado.

El formulario (el mismo creado anteriormente)

<?php
namespace Modulo\Form;

use Zend\Form\Element;
use Zend\Form\Form;
use Zend\Form\Factory;

class FormularioPruebas extends Form
{
    public function __construct($name = null)
     {
        parent::__construct($name);
        
        $this->add(array(
            'name' => 'nombre',
            'options' => array(
                'label' => 'Nombre: ',
            ),
            'attributes' => array(
                'type' => 'text',
                'class' => 'input',
                'required'=>'required'
            )
        ));
        
        
        $factory = new Factory();

        $email = $factory->createElement(array(
            'type' => 'Zend\Form\Element\Email',
            'name' => 'email',
            'options' => array(
                'label' => 'Email: ',
            ),
            'attributes' => array(
                'required'=>'required',
                'class' => 'input_email',
                'id' => 'input_email'
            ),
          ));
        $this->add($email);
       
        $this->add(array(
            'name' => 'submit',
            'attributes' => array(     
                'type' => 'submit',
                'value' => 'Enviar',
                'title' => 'Enviar'
            ),
        ));
        
        
     }
}
?>

El controlador

<?php
namespace Modulo\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

//Incluir componentes de validación
use Zend\Validator;
use Zend\I18n\Validator as I18nValidator;

//Incluir modelos
use Modulo\Model\Entity\PruebasModel;

//Incluir formularios
use Modulo\Form\FormularioPruebas;

class PruebasController extends AbstractActionController{
    
    public function indexAction(){
        return new ViewModel();
    }
    
    public function formularioAction(){
	//Generamos el formulario y lo pasamos a la vista
        $form=new FormularioPruebas("form");
        return new ViewModel(array("titulo"=>"Formularios en ZF2","form"=>$form,'url'=>$this->getRequest()->getBaseUrl()));
    }
    
    public function recibirFormularioAction(){
	//Comprueba que existe $_POST["submit"]
        if($this->request->getPost("submit")){
		
		//Recoge los datos que le llegan via post
        $datos=$this->request->getPost();
            
			//Instanciamos el validador de emails
			$email=new Validator\EmailAddress();
			
			//Indicamos un mensaje para cuando falle
            $email->setMessage("Email '%value%' no valido");
			
			//Comprobamos que el dato es un email correcto
            $validar_email=$email->isValid($this->request->getPost("email"));
            
			//Instanciamos el validador alfabetico
            $letras=new I18nValidator\Alpha(); 
			
			//Indicamoss un mensaje para cuando falle
            $letras->setMessage("El nombre '%value%' no son solo letras");
			
			//Validamos el nombre
            $validar_nombre=$letras->isValid($this->request->getPost("nombre"));
           
            //Si ambas validaciones dan true
            if($validar_email && $validar_nombre){
                $valido="Formulario vaidado correctamente";
            }else{
			//Conseguimos los mensajes de error en el caso de que no sean correctos
                $valido=array(
                    $email->getMessages(),
                    $letras->getMessages(),
                        );
                
            }
			
			//Cargamos la vista pasándole los datos
            return new ViewModel(array("titulo"=>"Recibir datos via POST en ZF2","datos"=>$datos,"valido"=>$valido));
        }else{
		//Si no se a enviado el formulario e intentamos acceder a este método action nos redirige
           return $this->redirect()->toUrl(
            $this->getRequest()->getBaseUrl().'/modulo/formulario'
            );
        }
    }
     
}

La vista formulario.phtml

<h1><?php echo $this->titulo?></h1>
<?php
$form = $this->form;
$form->prepare();

$form->setAttributes(array(
    'action' => $this->url.'/modulo/recibirformulario',
    'method' => 'post'
));

$formLabel = $this->plugin('formLabel');

echo $this->form()->openTag($form);
?>

<div class="form_element">
<?php
    $name = $form->get('nombre');
    echo $formLabel->openTag().$name->getOption('label')." ";
    echo $this->formInput($name);
    echo $formLabel->closeTag();
?>
</div>


<div class="form_element">
<?php
    $email = $form->get('email');
    echo $formLabel->openTag().$email->getOption('label')." ";
    echo $this->formInput($email);
    echo $formLabel->closeTag();
?>
</div>

<?php echo $this->formElement($form->get('submit')) ?>

<?php echo $this->form()->closeTag(); ?>

La vista recibirformulario.phtml

<h1><?php echo $this->titulo?></h1>
<?php var_dump($datos); ?>
<?php var_dump($valido); ?>
<ul>
    <li>Nombre: <?=$datos->nombre?></li>
    <li>Email: <?=$datos->email?></li>
</ul>

Validar formularios en Zend Framework 2

Validaciones y filtros asociados al formulario

Esta forma de validar es la más correcta para aplicar a formularios.
Crearemos un fichero dentro del directorio Form de formularios llamado FormularioPruebaValidator.php por convención es recomendable utilizar el nombre del formulario acabado de Validator o Filters.

Src/Modulo/Form/FormularioPruebaValidator.php

<?php
namespace Modulo\Form;

//Incluimos todo lo necesario
use Zend\Form\Form;
use Zend\InputFilter\InputFilter;
use Zend\Validator;
use Zend\I18n\Validator as I18nValidator;

class FormularioPruebasValidator extends InputFilter{
  
    public function __construct(){
        //De esta forma añadimos restricciones a los campos del formulario
        $this->add(array(
            'name' => 'nombre',
            'required' => true,
            'filters' => array(
//Cuidado con StripTags y HtmlEntities puede ser que no nos validen texto con tildes o eñes
                array('name' => 'StripTags'),
                array('name' => 'StringTrim'),
            ),
            'validators' => array(
                array (
                    'name' => 'StringLength',
                    'options' => array(
                        'encoding' => 'UTF-8',
                        'min' => '5',
                        'max' => '15',
                        'messages' => array(
                        \Zend\Validator\StringLength::INVALID=>'Tu nombre esta mal',
                        \Zend\Validator\StringLength::TOO_SHORT=>'Tu nombre debe ser de más de 5 letras',
                        \Zend\Validator\StringLength::TOO_LONG=>'Tu nombre debe ser de menos de 15 letras',
                        ),
                    ),
                ),
                 array( 
                    'name' => 'Alpha',
                     'options' => array(
                        'messages' => array(
                            I18nValidator\Alpha::INVALID=>'Tu nombre solo puede estar formado por letras',
                            I18nValidator\Alpha::NOT_ALPHA=>'Tu nombre solo puede estar formado por letras',
                            I18nValidator\Alpha::STRING_EMPTY=>'Tu nombre no puede estar vacio',
                            //I18nValidator\Alpha::NOT_ALNUM=>'Tu nombre esta mal',
                        ),
                     ),
                 ),     
        )));
 
        $this->add(array(
                'name' => 'email',
                'required' => true,
                'filters' => array(
                    array('name' => 'StringTrim'),
                ),
                'validators' => array(
                    array(
                        'name'=>'EmailAddress',
                        'options'=> array(
    'allowWhiteSpace'=>true,
                            'messages' => array(
                            \Zend\Validator\EmailAddress::INVALID_HOSTNAME=>'Email incorrecto',
                            ),
                        ),
                    ),
                )));

        }
}

El formulario

<?php
namespace Modulo\Form;

use Zend\Form\Element;
use Zend\Form\Form;
use Zend\Form\Factory;

class FormularioPruebas extends Form
{
    public function __construct($name = null)
     {
        parent::__construct($name);
        
		//Definimos los filtros del formulario, instanciamos el objeto de validaciones
        $this->setInputFilter(new \Modulo\Form\FormularioPruebasValidator());
        
        $this->add(array(
            'name' => 'nombre',
            'options' => array(
                'label' => 'Nombre: ',
            ),
            'attributes' => array(
                'type' => 'text',
                'class' => 'input',
                'required'=>'required'
            )
        ));
        
        
        $factory = new Factory();

        $email = $factory->createElement(array(
            'type' => 'Zend\Form\Element\Email',
            'name' => 'email',
            'options' => array(
                'label' => 'Email: ',
            ),
            'attributes' => array(
                'required'=>'required',
                'class' => 'input_email',
                'id' => 'input_email'
            ),
          ));
        $this->add($email);
       
        $this->add(array(
            'name' => 'submit',
            'attributes' => array(     
                'type' => 'submit',
                'value' => 'Enviar',
                'title' => 'Enviar'
            ),
        ));
        
        
     }
}

?>

El controlador

<?php
namespace Modulo\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;

//Incluir componentes de validación
use Zend\Validator;
use Zend\I18n\Validator as I18nValidator;

//Incluir modelos
use Modulo\Model\Entity\PruebasModel;

//Incluir formularios
use Modulo\Form\FormularioPruebas;

class PruebasController extends AbstractActionController{
    
    public function indexAction(){
        return new ViewModel();
    }
    
    public function formularioAction(){
		/*
		* El propio método que muestra la vista del formulario, 
		* también procesara los datos
        */
		
		//Instanciamos el formulario
		$form=new FormularioPruebas("form");
		
		//Esta vista se cargará por defecto
        $vista=array("titulo"=>"Formularios en ZF2","form"=>$form,'url'=>$this->getRequest()->getBaseUrl());
        
		//Si el formulario a sido enviado
        if($this->getRequest()->isPost()) {
		
			//Repoblamos el formulario con los datos pasados por el usuario
            $form->setData($this->getRequest()->getPost());
            
			//Si el formulario es valido que haga algo
			if($form->isValid()){
                
            }else{
				//Si no, pasa los mensajes de error
                $err=$form->getMessages();
                $vista=array("titulo"=>"Formularios en ZF2","form"=>$form,'url'=>$this->getRequest()->getBaseUrl(),"error"=>$err);
            }
        }
        
		//Renderiza la vista
        return new ViewModel($vista);
    }
     
}

La vista

<h1><?php echo $this->titulo?></h1>
<?php
$form = $this->form;
$form->prepare();

//El formulario llama a la misma pagina
//El método setAtributes también puede ser llamado en la clase del formulario
$form->setAttributes(array(
    'action'=>"",
    'method' => 'post'
));

$formLabel = $this->plugin('formLabel');

echo $this->form()->openTag($form);
?>

<div class="form_element">
<?php
    $name = $form->get('nombre');
    echo $formLabel->openTag().$name->getOption('label')." ";
    echo $this->formInput($name);
    echo $this->formElementErrors($name); //Mostrar los errores del formulario
    echo $formLabel->closeTag();
?>
</div>


<div class="form_element">
<?php
    //var_dump($error);
    $email = $form->get('email');
    echo $formLabel->openTag().$email->getOption('label')." ";
    echo $this->formInput($email);
    //echo $this->formElementErrors($email);
    if(isset($error)){
	//Podemos manipular mas los mensajes de error
      echo $error["email"]['emailAddressInvalidHostname'];
    }
    echo $formLabel->closeTag();
?>
</div>

<?php echo $this->formElement($form->get('submit')) ?>

<?php echo $this->form()->closeTag(); ?>

Si enviamos el formulario y los datos no son correctos se nos mostrará así, por defecto los mensajes vienen en ingles. Dentro de los mensajes podemos utilizar la variable %value% que representa a la información que has rellenado en ese campo.
Validar formularios en Zend Framework 2 Zend Form

Podemos definir expresiones regulares de esta forma

array( 
	'name' => 'Regex',
	 'options' => array(
		'pattern'=>'/^Vi/',
		'messages' => array(
		Validator\Regex::INVALID=>'Tu nombre esta mal',
		Validator\Regex::ERROROUS=>'Tu nombre esta mal',
		Validator\Regex::NOT_MATCH=>'Tu nombre esta mal',
		),
	 ),
 ),     

Podemos conseguir mucha más información sobre formularios, validaciones y filtros en la documentación oficial de Zend Framework 2:
Zend Form Quick Start
Como crear los diferentes elementos de los formularios
Zend Validator
Zend Filter Set

Víctor Robles WEB

Autor: Victor

Desarrollador web - Formador online - Blogger

Compartir este post