Post on 28-May-2015
description
Validación
Realizada por:Christian Aquino |@cj_aquinoDiego Ramirez |@thedarsideofitGonzalo Alonso |@GonzaloAlonsoDDiego Barros |@Inmzombie
Para: Hydras C&S |@hydras_csBasada en Libro Symfony 2 en español Nacho Pacheco y The Book
Validando
La validación es una tarea muy común en aplicaciones web.● Los datos introducidos en formularios se tienen que
validar.● Los datos también se deben validar antes de escribirlos
en una base de datos o pasarlos a un servicio web.
Symfony2 viene con un componente Validator que facilita y transparenta esta tarea. Este componente está basado en la especificación de validación Bean JSR303.
Fundamentos de la validación// src/Acme/BlogBundle/Entity/Author.phpuse Symfony\Component\Validator\Constraints as Assert;
class Author{ /** * Restricciones */ public $name;}
/** * @Assert\NotBlank() */
Usando el servicio validadorpublic function indexAction(){ $author = new Author(); // ... hace algo con el objeto $author $validator = $this->get('validator'); $errors = $validator->validate($author); if (count($errors) > 0) { return new Response(print_r($errors, true)); } else { return new Response('The author is valid! Yes!'); }}
Usando el servicio validadorSi la propiedad $name está vacía, verás el siguiente
mensaje de error:
Acme\BlogBundle\Author.name: This value should not be blank
Si insertas un valor en la propiedad $name aparecerá el
satisfactorio mensaje de éxito:
The author is valid! Yes!
Colección de errores a plantillaif (count($errors) > 0) { return $this->render('AcmeBlogBundle:Author:validate.html.twig', array( 'errors' => $errors, ));} else { // ...}
<ul>{% for error in errors %} <li>{{ error.message }}</li>{% endfor %}</ul>
Validación y formulariospublic function updateAction(Request $request){ $author = new Author(); $form = $this->createForm(new AuthorType(), $author); if ($request->isMethod('POST')) { $form->bind($request);
if ($form->isValid()) { // validación superada, haz algo con el objeto $author
return $this->redirect($this->generateUrl(...)); } }}
Configurando anotaciones# app/config/config.ymlframework: validation: { enable_annotations: true }
<!-- app/config/config.xml --><framework:config> <framework:validation enable-annotations="true" /></framework:config>
// app/config/config.php$container->loadFromExtension('framework', array('validation' => array( 'enable_annotations' => true,)));
Restricciones
A fin de validar un objeto, basta con asignar una o más
restricciones a tu clase y luego pasarla al servicio
validador.
Una restricción simplemente es un objeto PHP que hace
una declaración asertiva.
En la vida real: «El pastel no se debe quemar». En
Symfony2, son similares: son aserciones de que una
condición es verdadera.
Dado un valor, una restricción te dirá si o no el valor se
adhiere a las reglas de tu restricción.
Restricciones básicas
● NotBlank● Blank● NotNull● Null● True● False● Type
Restricciones de cadena
● Email● MinLength● MaxLength● Length● Url● Regex● Ip
Restricciones de número● Max● Min● Range
Restricciones de fecha● Date● DateTime● Time
Restricciones de colección● Choice● Collection● Count● UniqueEntity● Language● Locale● Country
Restricciones de archivo● File● Image
Restricciones de financieras● CardScheme● Luhn
Otras restricciones● Callback● All● UserPassword● Valid
Configurando restricciones// src/Acme/BlogBundle/Entity/Author.phpuse Symfony\Component\Validator\Constraints as Assert;
class Autor{ /** * @Assert\Choice( * choices = { "male", "female" }, * message = "Choose a valid gender." * ) */ public $gender;}
/** * @Assert\Choice({"male", "female"}) */
PropiedadesLa validación de propiedades de clase es la técnica de validación más básica.
// Acme/BlogBundle/Entity/Author.phpuse Symfony\Component\Validator\Constraints as Assert;
class Autor{ /** * @Assert\NotBlank() * @Assert\Length(min = "3") */ private $firstName;}
CaptadoresLas restricciones también se pueden aplicar al valor devuelto por un método, público que comience con get o is
// src/Acme/BlogBundle/Entity/Author.phpuse Symfony\Component\Validator\Constraints as Assert;
class Author{ /** * @Assert\True(message = "The password cannot match your first name") */ public function isPasswordLegal() {
// return true or falsereturn ($this->firstName != $this->password);
}}
Clases - Callback
// src/Acme/BlogBundle/Entity/Author.phpnamespace Acme\BlogBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
/** * @Assert\Callback(methods={"isAuthorValid"}) */class Author{}
// ...use Symfony\Component\Validator\ExecutionContext;
class Author{ // ... private $firstName;
public function isAuthorValid(ExecutionContext $context) { // de alguna manera hay un arreglo de "nombres ficticios" $fakeNames = array();
// comprueba si el nombre en realidad es un nombre ficticio if (in_array($this->getFirstName(), $fakeNames)) { $context->addViolationAtSubPath('firstname', 'This name sounds totally fake!', array(), null); } }}
Validando grupos// src/Acme/BlogBundle/Entity/User.phpnamespace Acme\BlogBundle\Entity;
use Symfony\Component\Security\Core\User\UserInterface;use Symfony\Component\Validator\Constraints as Assert;
class User implements UserInterface{ /** * @Assert\Email(groups={"registration"}) */ private $email;
Validando grupos
/** * @Assert\NotBlank(groups={"registration"}) * @Assert\Length(min=7, groups={"registration"}) */ private $password;
/** * @Assert\Length(min = "2") */ private $city;}
Form - validando grupos
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
public function setDefaultOptions(OptionsResolverInterface $resolver){ $resolver->setDefaults(array( 'validation_groups' => array('registration') ));}
Validando valores y arregloscomo verificar que una cadena es una dirección de correo electrónico válida
use Symfony\Component\Validator\Constraints\Email;// ...
public function addEmailAction($email){ $emailConstraint = new Email(); // puedes fijar todas las "opciones" de restricción de esta manera $emailConstraint->message = 'Invalid email address';
// usa el validador para validar el valor $errorList = $this->get('validator')->validateValue( $email, $emailConstraint );
Validando valores y arregloscomo verificar que una cadena es una dirección de correo electrónico válida
if (count($errorList) == 0) { // esta ES una dirección de correo válida, haz algo } else { // esta *no* es una dirección de correo electrónico válida $errorMessage = $errorList[0]->getMessage(); // ... haz algo con el error } // ...}
El método validateValue devuelve un objeto Symfony\Component\Validator\ConstraintViolationList, que actúa como un arreglo de errores. Cada error de la colección es un objeto Symfony\Component\Validator\ConstraintViolation, que contiene el mensaje de error en su método getMessage.
Crear restricciones personalizadas
Puedes crear una restricción personalizada extendiendo la clase base “constraint”,
Symfony\Component\Validator\Constraint. A modo de ejemplo vas a crear un sencillo validador que compruebe si
una cadena únicamente contiene caracteres alfanuméricos.
Creando la clase de la restricción// src/Acme/DemoBundle/Validator/Constraints/ContainsAlphanumeric.phpnamespace Acme\DemoBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
/** * @Annotation */class ContainsAlphanumeric extends Constraint{ public $message = 'The string "%string%" contains an illegal character: it can only contain letters or numbers.';}
Creando el validador directamente// src/Acme/DemoBundle/Validator/Constraints/ContainsAlphanumericValidator.phpnamespace Acme\DemoBundle\Validator\Constraints;use Symfony\Component\Validator\Constraint;use Symfony\Component\Validator\ConstraintValidator;
class ContainsAlphanumericValidator extends ConstraintValidator{ public function validate($value, Constraint $constraint) { if (!preg_match('/^[a-zA-Za0-9]+$/', $value, $matches)) { $this->context->addViolation($constraint->message, array('%string%' => $value)); } }}
// src/Acme/DemoBundle/Entity/AcmeEntity.phpuse Symfony\Component\Validator\Constraints as Assert;use Acme\DemoBundle\Validator\Constraints as AcmeAssert;
class AcmeEntity{ /** * @Assert\NotBlank * @AcmeAssert\ContainsAlphanumeric */ protected $name;}
Usando el nuevo validador