Post validators en symfony

symfony.jpg
Solucionex
01
Dic 10

En el ultimo proyecto que estoy realizando con Symfony, en muchos de sus formularios antes de permitir guardar es necesario verificar que se cumplan ciertas reglas de negocio. Esto es muy sencillo hacerlo utilizando los post validators. Un post validator, es un validador especial de Symfony que es ejecutado después de todos los otros validadores.

Dentro del post validator podemos acceder a todos los campos del formulario, con la garantía de que los datos que nos están llegando ya han sido validados por el validador individual que tiene cada campo del formulario. Gracias a esto, podemos realizar las validaciones que necesitemos como comparar campos del formulario o realizar verificaciones con la capa de negocio.

El post validator, en el caso de que el formulario no supere la validación que queremos realizar, nos permite lanzar un mensaje de error personalizado y situarlo en los errores globales del formulario o asociado al campo junto al que deseamos que se muestre el error. A mi personalmente esta funcionalidad me parece una autentica virguería.

A continuación os dejo un pequeño ejemplo para que veáis como se utiliza.

class CompraForm extends sfForm { public function configure() { $this->setWidgets(array( 'producto_id' => new sfWidgetFormDoctrineChoice(array('model' => $this->getRelatedModelName('Producto')), 'cantidad' => new sfWidgetFormInputText(), )); $this->setValidators(array( 'producto_id' => new sfValidatorDoctrineChoice(array('model' => $this->getRelatedModelName('Producto'), 'required' => true)), 'cantidad' => new sfValidatorInteger(array('required' => true)), )); $this->widgetSchema->setNameFormat('compra[%s]'); // Añado un post validator $this->validatorSchema->setPostValidator( new sfValidatorCallback(array('callback' => array($this, 'checkStock'))) ); } public function checkStock($validator, $values) { // Mediante la cama de negocio comprobamos si hay stock del articulo $producto = Doctrine::getTable('Producto')->find($values['producto_id']); if($producto->geStock() < $values['cantidad']){ throw new sfValidatorError($validator, 'No hay Stock suficiente'); } return $values; } }

De esta forma si se cumple la condición, se mostrará el mensaje de error en la zona de Errores globales.

Si necesitamos mostrar el error junto al campo que lo provoca, podemos hacerlo utilizando el siguiente código:

public function checkStock($validator, $values) { // Mediante la cama de negocio comprobamos si hay stock del articulo $producto = Doctrine::getTable('Producto')->find($values['producto_id']); if($producto->geStock() < $values['cantidad']){ $error = new sfValidatorError($validator, 'No hay Stock suficiente'); throw new sfValidatorErrorSchema($validator, array('cantidad' => $error)); } return $values; }

Otra característica que podemos utilizar en los post validators, es la de modificar los valores de los campos enviados desde el formulario. Si en alguna ocasión necesitamos alterar el valor de algún campo del formulario podemos hacerlo modificando el valor de la variable $values.

Por ultimo, avisaros que hay que tener cuidado de hacer siempre un return de $values, si no hacemos esto el formulario no funcionará.

Espero que esto os sirva de utilidad, a mi me ha resuelto muchos problemas.