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>
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.
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