| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 15103 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.validate.writing_validators">
- <title>Escribiendo Validadores</title>
- <para>
- <classname>Zend_Validate</classname> provee un conjunto de validadores que suelen necesitarse,
- pero inevitablemente, los desarrolladores quiere escribir sus propios
- validadores personalizados para sus necesidades particulares.
- La tarea de escribir un validador personalizado se describe en esta sección.
- </para>
- <para>
- <classname>Zend_Validate_Interface</classname> define tres métodos, isValid(),
- getMessages(), y getErrors(), que pueden ser implementadas por clases de usuario
- a fin de crear objetos de validación personalizados.
- Un objeto que implementa una interfaz <classname>Zend_Validate_Interface</classname>
- puede añadirse a una cadena de validación con <classname>Zend_Validate::addValidator()</classname>.
- Tales objetos también pueden ser usados con
- <link linkend="zend.filter.input"><classname>Zend_Filter_Input</classname></link>.
- </para>
- <para>
- De la descripción anterior de <classname>Zend_Validate_Interface</classname>, podrá inferir
- que las clases de validación que proporciona Zend Framework devuelven un
- valor booleano para cuando un valor se valida satisfactoriamente o no.
- También proporcionan información sobre <emphasis role="bold">por qué</emphasis>
- un valor falló en la validación.
- La disponibilidad de las razones para los fracasos de validación puede ser
- valiosa para una aplicación por diversos motivos, tales como proporcionar
- estadísticas para análisis de usabilidad.
- </para>
- <para>
- La funcionalidad de los mensajes de validación básica de fallos están
- implementados en <classname>Zend_Validate_Abstract</classname>.
- A fin de incluir esta funcionalidad al crear una clase de validación,
- simplemente extienda <classname>Zend_Validate_Abstract</classname>.
- En la extensión de la clase deberá aplicar la lógica del método
- <methodname>isValid()</methodname> y definir las variables y plantillas de mensajes
- que correspondan a los tipos de fallos de validación que puedan suceder.
- Si falla un valor en su test de validación, entonces <methodname>isValid()</methodname>
- deberá devolver <methodname>false</methodname>.
- Si el valor pasa su test de validación, entonces <methodname>isValid()</methodname>
- deberá devolver <methodname>true</methodname>.
- </para>
- <para>
- En general, el método <methodname>isValid()</methodname> no debería arrojar
- excepciones, salvo que sea imposible determinar si el valor de entrada
- es válido o no.
- Algunos ejemplos de casos razonables para lanzar una excepción podría ser
- si un archivo no puede abrirse, que un servidor LDAP no pudiera ser
- contactado, o una conexión a una base de datos no estuviera disponible.
- Estos son casos en los que puede ser necesario determinar el éxito o
- fracaso de la validación.
- </para>
- <example id="zend.validate.writing_validators.example.simple">
- <title>Crear una Clase de Validación sencilla</title>
- <para>
- El siguiente ejemplo demuestra cómo podría escribirse un sencillo
- validador personalizado.
- En este caso las reglas de validación son simplemente que el valor
- de entrada debe ser de punto flotante.
- <programlisting language="php"><![CDATA[
- class MyValid_Float extends Zend_Validate_Abstract
- {
- const FLOAT = 'float';
- protected $_messageTemplates = array(
- self::FLOAT => "'%value%' no es un valor de punto flotante"
- );
- public function isValid($value)
- {
- $this->_setValue($value);
- if (!is_float($value)) {
- $this->_error();
- return false;
- }
- return true;
- }
- }
- ]]></programlisting>
- La clase define una plantilla para su único mensaje de fallo de
- validación, que incluye el mágico parámetro <methodname>%value%</methodname>.
- La llamada a <methodname>_setValue()</methodname> prepara al objeto para insertar
- automáticamente en el mensaje de fallo al valor probado, si éste
- falla en la validación.
- La llamada a <methodname>_error()</methodname> sigue las pistas para establecer
- una razón por el fracaso de la validación.
- Dado que esta clase sólo define un mensaje de fallo, no es necesario
- darle a <methodname>_error()</methodname> el nombre de la plantilla del mensaje
- de fallo.
- </para>
- </example>
- <example id="zend.validate.writing_validators.example.conditions.dependent">
- <title>Escribiendo una Clase de Validación habiendo Condiciones Dependientes </title>
- <para>
- El siguiente ejemplo muestra un conjunto de reglas de validación
- más complejo, donde es necesario que el valor de entrada ser numérico
- y dentro del límite de un rango de valores mínimos y máximos.
- Un valor de entrada podría fallar en la validación exactamente por una
- de las siguientes razones:
- <itemizedlist>
- <listitem>
- <para>El valor de entrada no es numérico.</para>
- </listitem>
- <listitem>
- <para>El valor de entrada es menor que el valor mínimo permitido.</para>
- </listitem>
- <listitem>
- <para>El valor de entrada es mayor que el valor máximo permitido.</para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- Estas razones en el fallo de validación, son traducidas a las definiciones en la clase:
- <programlisting language="php"><![CDATA[
- class MyValid_NumericBetween extends Zend_Validate_Abstract
- {
- const MSG_NUMERIC = 'msgNumeric';
- const MSG_MINIMUM = 'msgMinimum';
- const MSG_MAXIMUM = 'msgMaximum';
- public $minimum = 0;
- public $maximum = 100;
- protected $_messageVariables = array(
- 'min' => 'minimum',
- 'max' => 'maximum'
- );
- protected $_messageTemplates = array(
- self::MSG_NUMERIC => "'%value%' no es numérico",
- self::MSG_MINIMUM => "'%value%' debe ser al menos '%min%'",
- self::MSG_MAXIMUM => "'%value%' debe ser no mayor a '%max%'"
- );
- public function isValid($value)
- {
- $this->_setValue($value);
- if (!is_numeric($value)) {
- $this->_error(self::MSG_NUMERIC);
- return false;
- }
- if ($value < $this->minimum) {
- $this->_error(self::MSG_MINIMUM);
- return false;
- }
- if ($value > $this->maximum) {
- $this->_error(self::MSG_MAXIMUM);
- return false;
- }
- return true;
- }
- }
- ]]></programlisting>
- Las propiedades públicas <methodname>$minimum</methodname> y <methodname>$maximum</methodname>
- se han establecido para proporcionar los límites mínimo y máximo,
- respectivamente, de un valor a validar.
- La clase también define dos variables de mensajes que corresponden a
- las propiedades públicas y permiten usar <methodname>min</methodname> y <methodname>max</methodname>
- en plantillas de mensajes como parámetros mágicos, al igual que con
- <methodname>value</methodname>.
- </para>
- <para>
- Tenga en cuenta que si cualquiera de las comprobaciones de validación
- falla en <methodname>isValid()</methodname>, ya está preparado un mensaje apropiado,
- y el método inmediatamente devuelve <methodname>false</methodname>.
- Estas reglas de validación son por lo tanto secuencialmente dependientes.
- Es decir, si uno de los tests falla, no hay necesidad de poner a
- prueba las posteriores reglas de validación.
- Sin embargo, esta necesidad no será el caso.
- El siguiente ejemplo ilustra cómo escribir una clase con reglas de
- validación independientes, donde el objeto validación puede devolver
- múltiples razones por las cuales fracasó un intento de validación en
- particular.
- </para>
- </example>
- <example id="zend.validate.writing_validators.example.conditions.independent">
- <title>Validación con Condiciones Independientes, Múltiples Razones del Fracaso</title>
- <para>
- Considere escribir una clase de validación y control de
- contraseñas - cuando es necesario que un usuario elija una
- contraseña que cumple determinados criterios para ayudar a tener
- cuentas de usuario seguras. Supongamos que la seguridad de la contraseña
- aplica criterios que fuerzan a lo siguiente:
- <itemizedlist>
- <listitem>
- <para>debe tener al menos una longitud de 8 caracteres,</para>
- </listitem>
- <listitem>
- <para>contener al menos una letra en mayúscula,</para>
- </listitem>
- <listitem>
- <para>contener al menos una letra en minúscula,</para>
- </listitem>
- <listitem>
- <para>contener al menos un dígito.</para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- La siguiente clase implementa estos criterios de validación:
- <programlisting language="php"><![CDATA[
- class MyValid_PasswordStrength extends Zend_Validate_Abstract
- {
- const LENGTH = 'length';
- const UPPER = 'upper';
- const LOWER = 'lower';
- const DIGIT = 'digit';
- protected $_messageTemplates = array(
- self::LENGTH => "'%value%' debe tener al menos una longitud de 8 caracteres",
- self::UPPER => "'%value%' debe contener al menos una letra en mayúscula",
- self::LOWER => "'%value%' debe contener al menos una letra en minúscula",
- self::DIGIT => "'%value%' debe contener al menos un dígito"
- );
- public function isValid($value)
- {
- $this->_setValue($value);
- $isValid = true;
- if (strlen($value) < 8) {
- $this->_error(self::LENGTH);
- $isValid = false;
- }
- if (!preg_match('/[A-Z]/', $value)) {
- $this->_error(self::UPPER);
- $isValid = false;
- }
- if (!preg_match('/[a-z]/', $value)) {
- $this->_error(self::LOWER);
- $isValid = false;
- }
- if (!preg_match('/\d/', $value)) {
- $this->_error(self::DIGIT);
- $isValid = false;
- }
- return $isValid;
- }
- }
- ]]></programlisting>
- Las cuatro pruebas de criterio en <methodname>isValid()</methodname> no devuelven
- inmediatamente <methodname>false</methodname>.
- Esto permite a la clase de validación a proporcionar <emphasis role="bold">todas</emphasis>
- las razones por las que la contraseña de entrada no cumplió los requisitos
- de validación.
- Si, por ejemplo, un usuario ingresara el string "<methodname>#$%</methodname>"
- como contraseña, <methodname>isValid()</methodname> causaría que los cuatro
- mensajes de fracaso de validación sean devueltos por un llamado posterior
- a <methodname>getMessages()</methodname>.
- </para>
- </example>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|