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

1 Comentario

  1. Use la forma de validar «Validaciones y filtros asociados al formulario» pero al hacer if($form->isValid()) me daba lanzaba siempre «FALSE» y era porque agregue un campo de Checkbox el cual el validador siempre lo requería así este no haya sido seleccionado ……..la solución fue poner en la clase «FormularioPruebasValidator» como no requerido, de esta forma

    $this->add(array(
    ‘name’ => ‘Checkbox’,
    ‘required’ => false,

    ));

    Responder

Poner un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *