Development

/branches/1.1/lib/validator/sfValidatorBase.class.php

You must first sign up to be able to contribute.

root/branches/1.1/lib/validator/sfValidatorBase.class.php

Revision 17473, 10.9 kB (checked in by fabien, 5 years ago)

[1.1, 1.2, 1.3] made some small performance optimization on widgets and validators (closes #6311)

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 <?php
2
3 /*
4  * This file is part of the symfony package.
5  * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 /**
12  * sfValidatorBase is the base class for all validators.
13  *
14  * It also implements the required option for all validators.
15  *
16  * @package    symfony
17  * @subpackage validator
18  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
19  * @version    SVN: $Id$
20  */
21 abstract class sfValidatorBase
22 {
23   protected static
24     $charset = 'UTF-8';
25
26   protected
27     $requiredOptions = array(),
28     $defaultMessages = array(),
29     $defaultOptions  = array(),
30     $messages        = array(),
31     $options         = array();
32
33   /**
34    * Constructor.
35    *
36    * Available options:
37    *
38    *  * required:    true if the value is required, false otherwise (default to true)
39    *  * trim:        true if the value must be trimmed, false otherwise (default to false)
40    *  * empty_value: empty value when value is not required
41    *
42    * Available error codes:
43    *
44    *  * required
45    *  * invalid
46    *
47    * @param array $options   An array of options
48    * @param array $messages  An array of error messages
49    */
50   public function __construct($options = array(), $messages = array())
51   {
52     $this->options  = array_merge(array('required' => true, 'trim' => false, 'empty_value' => null), $this->options);
53     $this->messages = array_merge(array('required' => 'Required.', 'invalid' => 'Invalid.'), $this->messages);
54
55     $this->configure($options, $messages);
56
57     $this->setDefaultOptions($this->getOptions());
58     $this->setDefaultMessages($this->getMessages());
59
60     $currentOptionKeys = array_keys($this->options);
61     $optionKeys = array_keys($options);
62
63     // check option names
64     if ($diff = array_diff($optionKeys, array_merge($currentOptionKeys, $this->requiredOptions)))
65     {
66       throw new InvalidArgumentException(sprintf('%s does not support the following options: \'%s\'.', get_class($this), implode('\', \'', $diff)));
67     }
68
69     // check error code names
70     if ($diff = array_diff(array_keys($messages), array_keys($this->messages)))
71     {
72       throw new InvalidArgumentException(sprintf('%s does not support the following error codes: \'%s\'.', get_class($this), implode('\', \'', $diff)));
73     }
74
75     // check required options
76     if ($diff = array_diff($this->requiredOptions, array_merge($currentOptionKeys, $optionKeys)))
77     {
78       throw new RuntimeException(sprintf('%s requires the following options: \'%s\'.', get_class($this), implode('\', \'', $diff)));
79     }
80
81     $this->options  = array_merge($this->options, $options);
82     $this->messages = array_merge($this->messages, $messages);
83   }
84
85   /**
86    * Configures the current validator.
87    *
88    * This method allows each validator to add options and error messages
89    * during validator creation.
90    *
91    * If some options and messages are given in the sfValidatorBase constructor
92    * they will take precedence over the options and messages you configure
93    * in this method.
94    *
95    * @param array $options   An array of options
96    * @param array $messages  An array of error messages
97    *
98    * @see __construct()
99    */
100   protected function configure($options = array(), $messages = array())
101   {
102   }
103
104   /**
105    * Returns an error message given an error code.
106    *
107    * @param  string $name  The error code
108    *
109    * @return string The error message, or the empty string if the error code does not exist
110    */
111   public function getMessage($name)
112   {
113     return isset($this->messages[$name]) ? $this->messages[$name] : '';
114   }
115
116   /**
117    * Adds a new error code with a default error message.
118    *
119    * @param string $name   The error code
120    * @param string $value  The error message
121    */
122   public function addMessage($name, $value)
123   {
124     $this->messages[$name] = $value;
125   }
126
127   /**
128    * Changes an error message given the error code.
129    *
130    * @param string $name   The error code
131    * @param string $value  The error message
132    */
133   public function setMessage($name, $value)
134   {
135     if (!in_array($name, array_keys($this->messages)))
136     {
137       throw new InvalidArgumentException(sprintf('%s does not support the following error code: \'%s\'.', get_class($this), $name));
138     }
139
140     $this->messages[$name] = $value;
141   }
142
143   /**
144    * Returns an array of current error messages.
145    *
146    * @return array An array of messages
147    */
148   public function getMessages()
149   {
150     return $this->messages;
151   }
152
153   /**
154    * Changes all error messages.
155    *
156    * @param array $values  An array of error messages
157    */
158   public function setMessages($values)
159   {
160     $this->messages = $values;
161   }
162
163   /**
164    * Gets an option value.
165    *
166    * @param  string $name  The option name
167    *
168    * @return mixed  The option value
169    */
170   public function getOption($name)
171   {
172     return isset($this->options[$name]) ? $this->options[$name] : null;
173   }
174
175   /**
176    * Adds a new option value with a default value.
177    *
178    * @param string $name   The option name
179    * @param mixed  $value  The default value
180    */
181   public function addOption($name, $value = null)
182   {
183     $this->options[$name] = $value;
184   }
185
186   /**
187    * Changes an option value.
188    *
189    * @param string $name   The option name
190    * @param mixed  $value  The value
191    */
192   public function setOption($name, $value)
193   {
194     if (!in_array($name, array_merge(array_keys($this->options), $this->requiredOptions)))
195     {
196       throw new InvalidArgumentException(sprintf('%s does not support the following option: \'%s\'.', get_class($this), $name));
197     }
198
199     $this->options[$name] = $value;
200   }
201
202   /**
203    * Returns true if the option exists.
204    *
205    * @param  string $name  The option name
206    *
207    * @return bool true if the option exists, false otherwise
208    */
209   public function hasOption($name)
210   {
211     return isset($this->options[$name]);
212   }
213
214   /**
215    * Returns all options.
216    *
217    * @return array An array of options
218    */
219   public function getOptions()
220   {
221     return $this->options;
222   }
223
224   /**
225    * Changes all options.
226    *
227    * @param array $values  An array of options
228    */
229   public function setOptions($values)
230   {
231     $this->options = $values;
232   }
233
234   /**
235    * Adds a required option.
236    *
237    * @param string $name  The option name
238    */
239   public function addRequiredOption($name)
240   {
241     $this->requiredOptions[] = $name;
242   }
243
244   /**
245    * Returns all required option names.
246    *
247    * @param array An array of required option names
248    */
249   public function getRequiredOptions()
250   {
251     return $this->requiredOptions;
252   }
253
254   /**
255    * Cleans the input value.
256    *
257    * This method is also responsible for trimming the input value
258    * and checking the required option.
259    *
260    * @param  mixed $value  The input value
261    *
262    * @return mixed The cleaned value
263    *
264    * @throws sfValidatorError
265    */
266   public function clean($value)
267   {
268     $clean = $value;
269
270     if ($this->options['trim'] && is_string($clean))
271     {
272       $clean = trim($clean);
273     }
274
275     // empty value?
276     if ($this->isEmpty($clean))
277     {
278       // required?
279       if ($this->options['required'])
280       {
281         throw new sfValidatorError($this, 'required');
282       }
283
284       return $this->getEmptyValue();
285     }
286
287     return $this->doClean($clean);
288   }
289
290   /**
291    * Cleans the input value.
292    *
293    * Every subclass must implements this method.
294    *
295    * @param  mixed $value  The input value
296    *
297    * @return mixed The cleaned value
298    *
299    * @throws sfValidatorError
300    */
301   abstract protected function doClean($value);
302
303   /**
304    * Sets the charset to use when validating strings.
305    *
306    * @param string $charset  The charset
307    */
308   static public function setCharset($charset)
309   {
310     self::$charset = $charset;
311   }
312
313   /**
314    * Returns the charset to use when validating strings.
315    *
316    * @return string The charset (default to UTF-8)
317    */
318   static public function getCharset()
319   {
320     return self::$charset;
321   }
322
323   /**
324    * Returns true if the value is empty.
325    *
326    * @param  mixed $value  The input value
327    *
328    * @return bool true if the value is empty, false otherwise
329    */
330   protected function isEmpty($value)
331   {
332     return in_array($value, array(null, '', array()), true);
333   }
334
335   /**
336    * Returns an empty value for this validator.
337    *
338    * @return mixed The empty value for this validator
339    */
340   protected function getEmptyValue()
341   {
342     return $this->getOption('empty_value');
343   }
344
345   /**
346    * Returns an array of all error codes for this validator.
347    *
348    * @return array An array of possible error codes
349    *
350    * @see getDefaultMessages()
351    */
352   final public function getErrorCodes()
353   {
354     return array_keys($this->getDefaultMessages());
355   }
356
357   /**
358    * Returns default messages for all possible error codes.
359    *
360    * @return array An array of default error codes and messages
361    */
362   public function getDefaultMessages()
363   {
364     return $this->defaultMessages;
365   }
366
367   /**
368    * Sets default messages for all possible error codes.
369    *
370    * @param array $messages  An array of default error codes and messages
371    */
372   protected function setDefaultMessages($messages)
373   {
374     $this->defaultMessages = $messages;
375   }
376
377   /**
378    * Returns default option values.
379    *
380    * @return array An array of default option values
381    */
382   public function getDefaultOptions()
383   {
384     return $this->defaultOptions;
385   }
386
387   /**
388    * Sets default option values.
389    *
390    * @param array $options  An array of default option values
391    */
392   protected function setDefaultOptions($options)
393   {
394     $this->defaultOptions = $options;
395   }
396
397   /**
398    * Returns a string representation of this validator.
399    *
400    * @param  int $indent  Indentation (number of spaces before each line)
401    *
402    * @return string The string representation of the validator
403    */
404   public function asString($indent = 0)
405   {
406     $options = $this->getOptionsWithoutDefaults();
407     $messages = $this->getMessagesWithoutDefaults();
408
409     return sprintf('%s%s(%s%s)',
410       str_repeat(' ', $indent),
411       str_replace('sfValidator', '', get_class($this)),
412       $options ? sfYamlInline::dump($options) : ($messages ? '{}' : ''),
413       $messages ? ', '.sfYamlInline::dump($messages) : ''
414     );
415   }
416
417   /**
418    * Returns all error messages with non default values.
419    *
420    * @return string A string representation of the error messages
421    */
422   protected function getMessagesWithoutDefaults()
423   {
424     $messages = $this->messages;
425
426     // remove default option values
427     foreach ($this->getDefaultMessages() as $key => $value)
428     {
429       if (array_key_exists($key, $messages) && $messages[$key] === $value)
430       {
431         unset($messages[$key]);
432       }
433     }
434
435     return $messages;
436   }
437
438   /**
439    * Returns all options with non default values.
440    *
441    * @return string  A string representation of the options
442    */
443   protected function getOptionsWithoutDefaults()
444   {
445     $options = $this->options;
446
447     // remove default option values
448     foreach ($this->getDefaultOptions() as $key => $value)
449     {
450       if (array_key_exists($key, $options) && $options[$key] === $value)
451       {
452         unset($options[$key]);
453       }
454     }
455
456     return $options;
457   }
458 }
459
Note: See TracBrowser for help on using the browser.