[ZF-10089] Zend_Log
[zend.git] / documentation / manual / pl / module_specs / Zend_Validate-WritingValidators.xml
blobee4dd1c61b1fa25d24bb70965fbfb66dc3de2ffe
1 <sect1 id="zend.validate.writing_validators">
3     <title>Pisanie weryfikatorów</title>
5     <para>
6         Zend_Validate zapewnia zestaw najczęściej potrzebnych weryfikatorów, ale
7         programiści często potrzebują napisać własne weryfikatory dla ich
8         szczególnych zastosowań. Zadanie pisania własnego filtru jest opisane w
9         tej sekcji.
10     </para>
12     <para>
13         Interfejs <code>Zend_Validate_Interface</code> definiuje trzy metody,
14         <code>isValid()</code>, <code>getMessages()</code> oraz
15         <code>getErrors()</code>, które mogą być zaimplementowane przez klasę
16         użytkownika w celu utworzenia własnych obiektów weryfikujących. Obiekt,
17         który implementuje interfejs <code>Zend_Validate_Interface</code>
18         może być dodany do łańcucha weryfikatorów za pomocą metody
19         <code>Zend_Validate::addValidator()</code>.
20         Taki obiekt może być także użyty przez klasę
21           <link linkend="zend.filter.input"><code>Zend_Filter_Input</code></link>.
22     </para>
24     <para>
25         As you may already have inferred from the above description of <code>Zend_Validate_Interface</code>,
26         validation classes provided with Zend Framework return a boolean value for whether or not a value validates
27         successfully. They also provide information about <emphasis role="bold">why</emphasis> a value failed
28         validation. The availability of the reasons for validation failures may be valuable to an application for
29         various purposes, such as providing statistics for usability analysis.
30     </para>
32     <para>
33         Basic validation failure message functionality is implemented in <code>Zend_Validate_Abstract</code>. To
34         include this functionality when creating a validation class, simply extend
35         <code>Zend_Validate_Abstract</code>. In the extending class you would implement the
36         <code>isValid()</code> method logic and define the message variables and message templates that correspond to
37         the types of validation failures that can occur. If a value fails your validation tests, then
38         <code>isValid()</code> should return <code>false</code>. If the value passes your validation tests, then
39         <code>isValid()</code> should return <code>true</code>.
40     </para>
42     <para>
43         In general, the <code>isValid()</code> method should not throw any exceptions, except where it is impossible
44         to determine whether or not the input value is valid. A few examples of reasonable cases for throwing an
45         exception might be if a file cannot be opened, an LDAP server could not be contacted, or a database
46         connection is unavailable, where such a thing may be required for validation success or failure to be
47         determined.
48     </para>
50     <example id="zend.validate.writing_validators.example.simple">
52         <title>Creating a Simple Validation Class</title>
54         <para>
55             The following example demonstrates how a very simple custom validator might be written. In this case the
56             validation rules are simply that the input value must be a floating point value.
58             <programlisting role="php"><![CDATA[
59 class MyValid_Float extends Zend_Validate_Abstract
61     const FLOAT = 'float';
63     protected $_messageTemplates = array(
64         self::FLOAT => "'%value%' is not a floating point value"
65     );
67     public function isValid($value)
68     {
69         $this->_setValue($value);
71         if (!is_float($value)) {
72             $this->_error();
73             return false;
74         }
76         return true;
77     }
79 ]]>
80             </programlisting>
82             The class defines a template for its single validation failure message, which includes the built-in magic
83             parameter, <code>%value%</code>. The call to <code>_setValue()</code> prepares the object to insert the
84             tested value into the failure message automatically, should the value fail validation. The call to
85             <code>_error()</code> tracks a reason for validation failure. Since this class only defines one failure
86             message, it is not necessary to provide <code>_error()</code> with the name of the failure message
87             template.
88         </para>
90     </example>
92     <example id="zend.validate.writing_validators.example.conditions.dependent">
94         <title>Writing a Validation Class having Dependent Conditions</title>
96         <para>
97             The following example demonstrates a more complex set of validation rules, where it is required that the
98             input value be numeric and within the range of minimum and maximum boundary values. An input value would
99             fail validation for exactly one of the following reasons:
101             <itemizedlist>
102                 <listitem>
103                     <para>The input value is not numeric.</para>
104                 </listitem>
105                 <listitem>
106                     <para>The input value is less than the minimum allowed value.</para>
107                 </listitem>
108                 <listitem>
109                     <para>The input value is more than the maximum allowed value.</para>
110                 </listitem>
111             </itemizedlist>
112         </para>
114         <para>
115             These validation failure reasons are then translated to definitions in the class:
117             <programlisting role="php"><![CDATA[
118 class MyValid_NumericBetween extends Zend_Validate_Abstract
120     const MSG_NUMERIC = 'msgNumeric';
121     const MSG_MINIMUM = 'msgMinimum';
122     const MSG_MAXIMUM = 'msgMaximum';
124     public $minimum = 0;
125     public $maximum = 100;
127     protected $_messageVariables = array(
128         'min' => 'minimum',
129         'max' => 'maximum'
130     );
132     protected $_messageTemplates = array(
133         self::MSG_NUMERIC => "'%value%' is not numeric",
134         self::MSG_MINIMUM => "'%value%' must be at least '%min%'",
135         self::MSG_MAXIMUM => "'%value%' must be no more than '%max%'"
136     );
138     public function isValid($value)
139     {
140         $this->_setValue($value);
142         if (!is_numeric($value)) {
143             $this->_error(self::MSG_NUMERIC);
144             return false;
145         }
147         if ($value < $this->minimum) {
148             $this->_error(self::MSG_MINIMUM);
149             return false;
150         }
152         if ($value > $this->maximum) {
153             $this->_error(self::MSG_MAXIMUM);
154             return false;
155         }
157         return true;
158     }
161             </programlisting>
163             The public properties <code>$minimum</code> and <code>$maximum</code> have been established to provide
164             the minimum and maximum boundaries, respectively, for a value to successfully validate. The class also
165             defines two message variables that correspond to the public properties and allow <code>min</code> and
166             <code>max</code> to be used in message templates as magic parameters, just as with <code>value</code>.
167         </para>
169         <para>
170             Note that if any one of the validation checks in <code>isValid()</code> fails, an appropriate failure
171             message is prepared, and the method immediately returns <code>false</code>. These validation rules are
172             therefore sequentially dependent. That is, if one test should fail, there is no need to test any
173             subsequent validation rules. This need not be the case, however. The following example illustrates how to
174             write a class having independent validation rules, where the validation object may return multiple
175             reasons why a particular validation attempt failed.
176         </para>
178     </example>
180     <example id="zend.validate.writing_validators.example.conditions.independent">
182         <title>Validation with Independent Conditions, Multiple Reasons for Failure</title>
184         <para>
185             Consider writing a validation class for password strength enforcement - when a user is required to choose
186             a password that meets certain criteria for helping secure user accounts. Let us assume that the password
187             security criteria enforce that the password:
189             <itemizedlist>
190                 <listitem>
191                     <para>is at least 8 characters in length,</para>
192                 </listitem>
193                 <listitem>
194                     <para>contains at least one uppercase letter,</para>
195                 </listitem>
196                 <listitem>
197                     <para>contains at least one lowercase letter,</para>
198                 </listitem>
199                 <listitem>
200                     <para>and contains at least one digit character.</para>
201                 </listitem>
202             </itemizedlist>
203         </para>
205         <para>
206             The following class implements these validation criteria:
208             <programlisting role="php"><![CDATA[
209 class MyValid_PasswordStrength extends Zend_Validate_Abstract
211     const LENGTH = 'length';
212     const UPPER  = 'upper';
213     const LOWER  = 'lower';
214     const DIGIT  = 'digit';
216     protected $_messageTemplates = array(
217         self::LENGTH => "'%value%' must be at least 8 characters in length",
218         self::UPPER  => "'%value%' must contain at least one uppercase letter",
219         self::LOWER  => "'%value%' must contain at least one lowercase letter",
220         self::DIGIT  => "'%value%' must contain at least one digit character"
221     );
223     public function isValid($value)
224     {
225         $this->_setValue($value);
227         $isValid = true;
229         if (strlen($value) < 8) {
230             $this->_error(self::LENGTH);
231             $isValid = false;
232         }
234         if (!preg_match('/[A-Z]/', $value)) {
235             $this->_error(self::UPPER);
236             $isValid = false;
237         }
239         if (!preg_match('/[a-z]/', $value)) {
240             $this->_error(self::LOWER);
241             $isValid = false;
242         }
244         if (!preg_match('/\d/', $value)) {
245             $this->_error(self::DIGIT);
246             $isValid = false;
247         }
249         return $isValid;
250     }
253             </programlisting>
255             Note that the four criteria tests in <code>isValid()</code> do not immediately return <code>false</code>.
256             This allows the validation class to provide <emphasis role="bold">all</emphasis> of the reasons that the
257             input password failed to meet the validation requirements. If, for example, a user were to input the
258             string "<code>#$%</code>" as a password, <code>isValid()</code> would cause all four validation failure
259             messages to be returned by a subsequent call to <code>getMessages()</code>.
260         </para>
262     </example>
264 </sect1>