A free and open-source book on ZF3 for beginners

Translation into this language is not yet finished. You can help this project by translating the chapters and contributing your changes.

7.10. Agregar Filtros al Formulario y Reglas de Validación

La validación de formularios es el procedimiento de filtrar y revisar los datos enviados al servidor luego de hacer clic en el botón submit del formulario. Por ejemplo, queremos hacer las siguientes revisiones en el formulario de contacto:

22) Podrían haber usuarios maliciosos que agregan código HTML en el mensaje. Si abrimos ese código en el navegador podríamos ver contenido indeseado. Para evitar esto necesitamos reemplazar las etiquetas HTML del asunto y del cuerpo del mensaje.

Los requerimientos de arriba se llaman filtros y reglas de validación. Estas reglas pueden ser divididas dentro de dos categorías: filtros y validadores.

Los filtros transforman los datos ingresados por el usuario para reparar errores y asegurar que cumplen un determinado formato. Los filtros generalmente se aplican primero y los validadores se aplican de último.

Los validadores revisan si los datos son aceptables o no. Si todos los datos son correctos el formulario se considera valido y los datos pueden ser usados por la capa de la lógica de negocio. Si determinado campo es invalido, un validador levanta una bandera de error. En este caso, generalmente el formulario se muestra de nuevo al usuario al que se le pide que corrija cualquier error de entrada y que reenvíe el formulario al servidor.

¿Que sucede si no se agrega una regla de validación a un determinado campo del formulario?

Si no se agrega una regla de validación entonces los valores de los campos enviados por el usuario no serán revisados dejando un hueco en la seguridad del sitio web. Siempre es recomendable agregar una regla de validación a cada campo que el usuario llena del formulario y agregar tantas revisiones por campo como sea necesario para mantener el formulario seguro.

7.10.1. Filtros de Entrada

En ZF3 guardamos los filtros y la reglas de validación con la ayuda de la clase InputFilter. La clase InputFilter está definida en el componente Zend\InputFilter. Un filtro de entrada es un contenedor para las entradas (inputs). Generalmente agregamos un filtro de entrada por cada campo de nuestro modelo de formulario.

Una entrada puede consistir en filtros y/o validadores y alguna información adicional. Por ejemplo, una entrada puede contener la bandera que señala si el campo es obligatorio o si su valor puede faltar en la petición HTTP.

De una manera análoga a como agregamos campos al modelo del formulario existen dos formas de agregar entradas al contenedor de filtros: pasando una instancia de la clase entrada como argumento del método add() o pasando un arreglo de especificaciones 23. En la sección siguiente describiremos la última forma, ella es preferible porque necesitamos escribir menos código.

23) En el caso siguiente en el que usamos un arreglo de especificaciones la entrada se creará automáticamente con la ayuda de la clase Zend\InputFilter\Factory.

7.10.2. Agregar Entradas al Filtro de Entrada

Para agregar una entrada al filtro de entrada usamos el método add() que toma un solo argumento, un arreglo con las especificaciones de la entrada como se muestra a continuación:

[
  'name'     => '<name>',
  'type'     => '<type>',
  'required' => <required>,
  'filters'  => [
     // Add filters configuration here ...
  ],
  'validators' => [
     // Add validators configuration here ...
  ]
]

En el arreglo de arriba tenemos las siguientes llaves:

Figura 7.16. Herencia de la clase Input Figura 7.16. Herencia de la clase Input

7.10.2.1. Configuración del Filtro

La configuración de un filtro típico se muestra abajo:

[
  'name' => '<filter_name>',
  'priority' => <priority>,
  'options' => [
    // Filter options go here ...
  ]
],

La llave name (línea 2) es el nombre para el filtro. Este puede ser o el nombre completo de la clase filtro, es decir StringTrim::class, o un alias, StringTrim.

La llave opcional priority (línea 3) define la prioridad del filtro en la lista de filtros. La prioridad debe ser un número entero. El filtro con la prioridad más alta será aplicado primero. Por defecto se asigna la constante FilterChain::DEFAULT_PRIORITY (valor 1000).

El arreglo de options (línea 4) es especifico para cada filtro y puede contener parámetros para configurar el filtro.

7.10.2.2. Configuración del Validador

Una configuración típica para el validador se presenta abajo:

[
  'name' => '<validator_name>',
  'break_chain_on_failure' => <flag>,
  'options' => [
    // Validator options go here ...
  ]
],

La llave name (línea 2) es el nombre para el validador. Este puede ser el nombre completo de la clase validador (EmailAddress::class) o un alias (EmailAddress).

La llave opcional break_chain_on_failure (línea 3) define el comportamiento en el caso de que el validador falle. Si es igual a true los siguientes validadores en la lista no serán ejecutados de lo contrario cada validador en la lista será ejecutado sin depender del resultado de los otros validadores.

El arreglo de options (línea 4) es especifico para una determinada clase validador y puede contener parámetros para configurar el validador.

7.10.2.3. Añadir el Filtro de Entrada al Modelo de Formulario

Una vez que hemos creado y llenado el contenedor para el filtro de entrada debemos añadirlo al modelo del formulario. La clase base Form provee el método setInputFilter() que esta pensado con este propósito (ver tabla 7.10).

Tabla 7.10. Métodos que provee la clase base Form
Nombre del Método Descripción
setInputFilter($inputFilter) Añade el contenedor de filtro de entrada al formulario.
getInputFilter() Recupera el filtro de entrada añadido a un formulario.

7.10.3. Crear un Filtro de Entrada para el Formulario de Contacto

Ahora que tenemos un idea general sobre como definir y llenar el contenedor del filtro de entrada con filtros y validadores para cada campo vamos a completar nuestra clase de modelo de formulario ContactForm. Abajo agregamos el método privado addInputFilter() que define las reglas de filtrado/validación, las guarda en el contenedor de filtro de entrada y asocia el filtro de entrada al modelo de formulario.

<?php
// ...
use Zend\InputFilter\InputFilter;

class ContactForm extends Form
{
  public function __construct()
  {
    // ... call this method to add filtering/validation rules
    $this->addInputFilter();
  }

  // ...

  // This method creates input filter (used for form filtering/validation).
  private function addInputFilter()
  {
    $inputFilter = new InputFilter();
    $this->setInputFilter($inputFilter);

    $inputFilter->add([
        'name'     => 'email',
        'required' => true,
        'filters'  => [
           ['name' => 'StringTrim'],
        ],
        'validators' => [
           [
            'name' => 'EmailAddress',
            'options' => [
              'allow' => \Zend\Validator\Hostname::ALLOW_DNS,
              'useMxCheck' => false,
            ],
          ],
        ],
      ]
    );

    $inputFilter->add([
        'name'     => 'subject',
        'required' => true,
        'filters'  => [
           ['name' => 'StringTrim'],
           ['name' => 'StripTags'],
           ['name' => 'StripNewlines'],
        ],
        'validators' => [
           [
            'name' => 'StringLength',
              'options' => [
                'min' => 1,
                'max' => 128
              ],
           ],
        ],
      ]
    );

    $inputFilter->add([
        'name'     => 'body',
        'required' => true,
        'filters'  => [
          ['name' => 'StripTags'],
        ],
        'validators' => [
          [
            'name' => 'StringLength',
            'options' => [
              'min' => 1,
              'max' => 4096
            ],
          ],
        ],
      ]
    );
  }
}

Como podemos ver en el código de arriba primero declaramos el alias para la clase Zend\InputFilter\InputFilter (línea 3).

En el constructor del modelo de formulario (línea 10) llamamos al método addInputFilter() que está definido entre las líneas 16-76.

El objetivo del método addInputFilter() es crear el contenedor InputFilter (línea 18), asociarlo al modelo de formulario (línea 19) y agregar reglas de filtrado/validación (líneas 21-75). Para asociar el filtro de entrada al modelo de formulario usamos el método setInputFilter() provisto por la clase Form. Para insertar reglas de filtrado/validación dentro del contenedor de filtro de entrada usamos el método add() que provee la clase InputFilter y que toma el arreglo de especificaciones de la entrada que se quiere crear.

Agregamos tres entradas una por cada campo de nuestro formulario excepto el botón submit:

En la figura 7.17 podemos encontrar el esquema gráfico del filtro de entrada que hemos creado.

Figura 7.17. El filtro de entrada para el ContactForm Figura 7.17. El filtro de entrada para el ContactForm

Arriba describimos brevemente como crear un filtro de entrada para el modelo de formulario. Para información detallada sobre lo que mencionamos arriba, filtros y validadores, y sobre otras cosas podemos revisar Transformar los Datos de Entrada con Filtros y Revisar los Datos de Entrada con Validadores en donde encontraremos además ejemplos de uso.


Top