Development

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

You must first sign up to be able to contribute.

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

Revision 22446, 12.5 kB (checked in by fabien, 5 years ago)

[1.3] added a fluent interface to the form framework (closes #6438)

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