Zend_Validate-WritingValidators.xml 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 19577 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.validate.writing_validators">
  5. <title>Escribiendo Validadores</title>
  6. <para>
  7. <classname>Zend_Validate</classname>
  8. provee un conjunto de validadores que suelen necesitarse,
  9. pero inevitablemente, los
  10. desarrolladores quiere escribir sus propios
  11. validadores personalizados para sus necesidades
  12. particulares.
  13. La tarea de escribir un validador personalizado se describe en esta sección.
  14. </para>
  15. <para>
  16. <classname>Zend_Validate_Interface</classname>
  17. define tres métodos, isValid(),
  18. getMessages(), y getErrors(), que pueden ser implementadas
  19. por clases de usuario
  20. a fin de crear objetos de validación personalizados.
  21. Un objeto que
  22. implementa una interfaz
  23. <classname>Zend_Validate_Interface</classname>
  24. puede añadirse a una cadena de validación con
  25. <methodname>Zend_Validate::addValidator()</methodname>
  26. .
  27. Tales objetos también pueden ser usados con
  28. <link linkend="zend.filter.input">
  29. <classname>Zend_Filter_Input</classname>
  30. </link>
  31. .
  32. </para>
  33. <para>
  34. De la descripción anterior de
  35. <classname>Zend_Validate_Interface</classname>
  36. , podrá inferir
  37. que las clases de validación que proporciona Zend Framework devuelven un
  38. valor booleano para cuando un valor se valida satisfactoriamente o no.
  39. También proporcionan
  40. información sobre
  41. <emphasis>por qué</emphasis>
  42. un valor falló en la validación.
  43. La disponibilidad de las razones para los fracasos de
  44. validación puede ser
  45. valiosa para una aplicación por diversos motivos, tales como
  46. proporcionar
  47. estadísticas para análisis de usabilidad.
  48. </para>
  49. <para>
  50. La funcionalidad de los mensajes de validación básica de fallos están
  51. implementados en
  52. <classname>Zend_Validate_Abstract</classname>
  53. .
  54. A fin de incluir esta funcionalidad al crear una clase de validación,
  55. simplemente extienda
  56. <classname>Zend_Validate_Abstract</classname>
  57. .
  58. En la extensión de la clase deberá aplicar la lógica del método
  59. <methodname>isValid()</methodname>
  60. y definir las variables y plantillas de mensajes
  61. que correspondan a los tipos de fallos de
  62. validación que puedan suceder.
  63. Si falla un valor en su test de validación, entonces
  64. <methodname>isValid()</methodname>
  65. deberá devolver
  66. <constant>FALSE</constant>
  67. .
  68. Si el valor pasa su test de validación, entonces
  69. <methodname>isValid()</methodname>
  70. deberá devolver
  71. <constant>TRUE</constant>
  72. .
  73. </para>
  74. <para>
  75. En general, el método
  76. <methodname>isValid()</methodname>
  77. no debería arrojar
  78. excepciones, salvo que sea imposible determinar si el valor de entrada
  79. es
  80. válido o no.
  81. Algunos ejemplos de casos razonables para lanzar una excepción podría ser
  82. si un
  83. archivo no puede abrirse, que un servidor
  84. <acronym>LDAP</acronym>
  85. no pudiera ser
  86. contactado, o una conexión a una base de datos no estuviera disponible.
  87. Estos
  88. son casos en los que puede ser necesario determinar el éxito o
  89. fracaso de la validación.
  90. </para>
  91. <example id="zend.validate.writing_validators.example.simple">
  92. <title>Crear una Clase de Validación sencilla</title>
  93. <para>
  94. El siguiente ejemplo demuestra cómo podría escribirse un sencillo
  95. validador
  96. personalizado.
  97. En este caso las reglas de validación son simplemente que el valor
  98. de
  99. entrada debe ser de punto flotante.
  100. <programlisting language="php"><![CDATA[
  101. class MyValid_Float extends Zend_Validate_Abstract
  102. {
  103. const FLOAT = 'float';
  104. protected $_messageTemplates = array(
  105. self::FLOAT => "'%value%' no es un valor de punto flotante"
  106. );
  107. public function isValid($value)
  108. {
  109. $this->_setValue($value);
  110. if (!is_float($value)) {
  111. $this->_error();
  112. return false;
  113. }
  114. return true;
  115. }
  116. }
  117. ]]></programlisting>
  118. La clase define una plantilla para su único mensaje de fallo de
  119. validación, que incluye
  120. el mágico parámetro
  121. <emphasis>%value%</emphasis>
  122. .
  123. La llamada a
  124. <methodname>_setValue()</methodname>
  125. prepara al objeto para insertar
  126. automáticamente en el mensaje de fallo al valor probado,
  127. si éste
  128. falla en la validación.
  129. La llamada a
  130. <methodname>_error()</methodname>
  131. sigue las pistas para establecer
  132. una razón por el fracaso de la validación.
  133. Dado que esta
  134. clase sólo define un mensaje de fallo, no es necesario
  135. darle a
  136. <methodname>_error()</methodname>
  137. el nombre de la plantilla del mensaje
  138. de fallo.
  139. </para>
  140. </example>
  141. <example id="zend.validate.writing_validators.example.conditions.dependent">
  142. <title>Escribiendo una Clase de Validación habiendo Condiciones Dependientes </title>
  143. <para>
  144. El siguiente ejemplo muestra un conjunto de reglas de validación
  145. más complejo, donde es
  146. necesario que el valor de entrada ser numérico
  147. y dentro del límite de un rango de valores
  148. mínimos y máximos.
  149. Un valor de entrada podría fallar en la validación exactamente por una
  150. de las siguientes razones:
  151. </para>
  152. <itemizedlist>
  153. <listitem>
  154. <para>El valor de entrada no es numérico.</para>
  155. </listitem>
  156. <listitem>
  157. <para>El valor de entrada es menor que el valor mínimo permitido.</para>
  158. </listitem>
  159. <listitem>
  160. <para>El valor de entrada es mayor que el valor máximo permitido.</para>
  161. </listitem>
  162. </itemizedlist>
  163. <para>
  164. Estas razones en el fallo de validación, son traducidas a las definiciones en la
  165. clase:
  166. </para>
  167. <programlisting language="php"><![CDATA[
  168. class MyValid_NumericBetween extends Zend_Validate_Abstract
  169. {
  170. const MSG_NUMERIC = 'msgNumeric';
  171. const MSG_MINIMUM = 'msgMinimum';
  172. const MSG_MAXIMUM = 'msgMaximum';
  173. public $minimum = 0;
  174. public $maximum = 100;
  175. protected $_messageVariables = array(
  176. 'min' => 'minimum',
  177. 'max' => 'maximum'
  178. );
  179. protected $_messageTemplates = array(
  180. self::MSG_NUMERIC => "'%value%' no es numérico",
  181. self::MSG_MINIMUM => "'%value%' debe ser al menos '%min%'",
  182. self::MSG_MAXIMUM => "'%value%' debe ser no mayor a '%max%'"
  183. );
  184. public function isValid($value)
  185. {
  186. $this->_setValue($value);
  187. if (!is_numeric($value)) {
  188. $this->_error(self::MSG_NUMERIC);
  189. return false;
  190. }
  191. if ($value < $this->minimum) {
  192. $this->_error(self::MSG_MINIMUM);
  193. return false;
  194. }
  195. if ($value > $this->maximum) {
  196. $this->_error(self::MSG_MAXIMUM);
  197. return false;
  198. }
  199. return true;
  200. }
  201. }
  202. ]]></programlisting>
  203. <para>
  204. Las propiedades públicas
  205. <varname>$minimum</varname>
  206. y
  207. <varname>$maximum</varname>
  208. se han establecido para proporcionar los límites mínimo y máximo,
  209. respectivamente, de un
  210. valor a validar.
  211. La clase también define dos variables de mensajes que corresponden a
  212. las
  213. propiedades públicas y permiten usar
  214. <property>min</property>
  215. y
  216. <property>max</property>
  217. en plantillas de mensajes como parámetros mágicos, al igual que con
  218. <property>
  219. value
  220. </property>
  221. .
  222. </para>
  223. <para>
  224. Tenga en cuenta que si cualquiera de las comprobaciones de validación
  225. falla en
  226. <methodname>isValid()</methodname>
  227. , ya está preparado un mensaje apropiado,
  228. y el método inmediatamente devuelve
  229. <constant>FALSE</constant>
  230. .
  231. Estas reglas de validación son por lo tanto secuencialmente dependientes.
  232. Es decir, si
  233. uno de los tests falla, no hay necesidad de poner a
  234. prueba las posteriores reglas de
  235. validación.
  236. Sin embargo, esta necesidad no será el caso.
  237. El siguiente ejemplo ilustra cómo
  238. escribir una clase con reglas de
  239. validación independientes, donde el objeto validación
  240. puede devolver
  241. múltiples razones por las cuales fracasó un intento de validación en
  242. particular.
  243. </para>
  244. </example>
  245. <example id="zend.validate.writing_validators.example.conditions.independent">
  246. <title>Validación con Condiciones Independientes, Múltiples Razones del Fracaso</title>
  247. <para>
  248. Considere escribir una clase de validación y control de
  249. contraseñas - cuando es
  250. necesario que un usuario elija una
  251. contraseña que cumple determinados criterios para
  252. ayudar a tener
  253. cuentas de usuario seguras. Supongamos que la seguridad de la contraseña
  254. aplica criterios que fuerzan a lo siguiente:
  255. </para>
  256. <itemizedlist>
  257. <listitem>
  258. <para>debe tener al menos una longitud de 8 caracteres,</para>
  259. </listitem>
  260. <listitem>
  261. <para>contener al menos una letra en mayúscula,</para>
  262. </listitem>
  263. <listitem>
  264. <para>contener al menos una letra en minúscula,</para>
  265. </listitem>
  266. <listitem>
  267. <para>contener al menos un dígito.</para>
  268. </listitem>
  269. </itemizedlist>
  270. <para>
  271. La siguiente clase implementa estos criterios de validación:
  272. <programlisting language="php"><![CDATA[
  273. class MyValid_PasswordStrength extends Zend_Validate_Abstract
  274. {
  275. const LENGTH = 'length';
  276. const UPPER = 'upper';
  277. const LOWER = 'lower';
  278. const DIGIT = 'digit';
  279. protected $_messageTemplates = array(
  280. self::LENGTH => "'%value%' debe tener al menos una longitud de 8 caracteres",
  281. self::UPPER => "'%value%' debe contener al menos una letra en mayúscula",
  282. self::LOWER => "'%value%' debe contener al menos una letra en minúscula",
  283. self::DIGIT => "'%value%' debe contener al menos un dígito"
  284. );
  285. public function isValid($value)
  286. {
  287. $this->_setValue($value);
  288. $isValid = true;
  289. if (strlen($value) < 8) {
  290. $this->_error(self::LENGTH);
  291. $isValid = false;
  292. }
  293. if (!preg_match('/[A-Z]/', $value)) {
  294. $this->_error(self::UPPER);
  295. $isValid = false;
  296. }
  297. if (!preg_match('/[a-z]/', $value)) {
  298. $this->_error(self::LOWER);
  299. $isValid = false;
  300. }
  301. if (!preg_match('/\d/', $value)) {
  302. $this->_error(self::DIGIT);
  303. $isValid = false;
  304. }
  305. return $isValid;
  306. }
  307. }
  308. ]]></programlisting>
  309. Las cuatro pruebas de criterio en
  310. <methodname>isValid()</methodname>
  311. no devuelven
  312. inmediatamente
  313. <constant>FALSE</constant>
  314. .
  315. Esto permite a la clase de validación a proporcionar
  316. <emphasis role="bold">todas</emphasis>
  317. las razones por las que la contraseña de entrada no cumplió los requisitos
  318. de validación.
  319. Si, por ejemplo, un usuario ingresara el string "
  320. <methodname>#$%</methodname>
  321. "
  322. como contraseña,
  323. <methodname>isValid()</methodname>
  324. causaría que los cuatro
  325. mensajes de fracaso de validación sean devueltos por un llamado
  326. posterior
  327. a
  328. <methodname>getMessages()</methodname>
  329. .
  330. </para>
  331. </example>
  332. </sect1>
  333. <!--
  334. vim:se ts=4 sw=4 et:
  335. -->