Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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: sfValidatorBase.class.php 32653 2011-06-15 18:32:02Z fabien $
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 = array_merge(array('required' => self::$globalDefaultMessages['required'], 'invalid' => self::$globalDefaultMessages['invalid']), $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 = array_merge(array('required' => true, 'trim' => false, 'empty_value' => null), $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
   * Cleans the input value.
296
   *
297
   * This method is also responsible for trimming the input value
298
   * and checking the required option.
299
   *
300
   * @param  mixed $value  The input value
301
   *
302
   * @return mixed The cleaned value
303
   *
304
   * @throws sfValidatorError
305
   */
306
  public function clean($value)
307
  {
308
    $clean = $value;
309
 
310
    if ($this->options['trim'] && is_string($clean))
311
    {
312
      $clean = trim($clean);
313
    }
314
 
315
    // empty value?
316
    if ($this->isEmpty($clean))
317
    {
318
      // required?
319
      if ($this->options['required'])
320
      {
321
        throw new sfValidatorError($this, 'required');
322
      }
323
 
324
      return $this->getEmptyValue();
325
    }
326
 
327
    return $this->doClean($clean);
328
  }
329
 
330
  /**
331
   * Cleans the input value.
332
   *
333
   * Every subclass must implements this method.
334
   *
335
   * @param  mixed $value  The input value
336
   *
337
   * @return mixed The cleaned value
338
   *
339
   * @throws sfValidatorError
340
   */
341
  abstract protected function doClean($value);
342
 
343
  /**
344
   * Sets the charset to use when validating strings.
345
   *
346
   * @param string $charset  The charset
347
   */
348
  static public function setCharset($charset)
349
  {
350
    self::$charset = $charset;
351
  }
352
 
353
  /**
354
   * Returns the charset to use when validating strings.
355
   *
356
   * @return string The charset (default to UTF-8)
357
   */
358
  static public function getCharset()
359
  {
360
    return self::$charset;
361
  }
362
 
363
  /**
364
   * Returns true if the value is empty.
365
   *
366
   * @param  mixed $value  The input value
367
   *
368
   * @return bool true if the value is empty, false otherwise
369
   */
370
  protected function isEmpty($value)
371
  {
372
    return in_array($value, array(null, '', array()), true);
373
  }
374
 
375
  /**
376
   * Returns an empty value for this validator.
377
   *
378
   * @return mixed The empty value for this validator
379
   */
380
  protected function getEmptyValue()
381
  {
382
    return $this->getOption('empty_value');
383
  }
384
 
385
  /**
386
   * Returns an array of all error codes for this validator.
387
   *
388
   * @return array An array of possible error codes
389
   *
390
   * @see getDefaultMessages()
391
   */
392
  final public function getErrorCodes()
393
  {
394
    return array_keys($this->getDefaultMessages());
395
  }
396
 
397
  /**
398
   * Returns default messages for all possible error codes.
399
   *
400
   * @return array An array of default error codes and messages
401
   */
402
  public function getDefaultMessages()
403
  {
404
    return $this->defaultMessages;
405
  }
406
 
407
  /**
408
   * Sets default messages for all possible error codes.
409
   *
410
   * @param array $messages  An array of default error codes and messages
411
   */
412
  protected function setDefaultMessages($messages)
413
  {
414
    $this->defaultMessages = $messages;
415
  }
416
 
417
  /**
418
   * Returns default option values.
419
   *
420
   * @return array An array of default option values
421
   */
422
  public function getDefaultOptions()
423
  {
424
    return $this->defaultOptions;
425
  }
426
 
427
  /**
428
   * Sets default option values.
429
   *
430
   * @param array $options  An array of default option values
431
   */
432
  protected function setDefaultOptions($options)
433
  {
434
    $this->defaultOptions = $options;
435
  }
436
 
437
  /**
438
   * Returns a string representation of this validator.
439
   *
440
   * @param  int $indent  Indentation (number of spaces before each line)
441
   *
442
   * @return string The string representation of the validator
443
   */
444
  public function asString($indent = 0)
445
  {
446
    $options = $this->getOptionsWithoutDefaults();
447
    $messages = $this->getMessagesWithoutDefaults();
448
 
449
    return sprintf('%s%s(%s%s)',
450
      str_repeat(' ', $indent),
451
      str_replace('sfValidator', '', get_class($this)),
452
      $options ? sfYamlInline::dump($options) : ($messages ? '{}' : ''),
453
      $messages ? ', '.sfYamlInline::dump($messages) : ''
454
    );
455
  }
456
 
457
  /**
458
   * Returns all error messages with non default values.
459
   *
460
   * @return string A string representation of the error messages
461
   */
462
  protected function getMessagesWithoutDefaults()
463
  {
464
    $messages = $this->messages;
465
 
466
    // remove default option values
467
    foreach ($this->getDefaultMessages() as $key => $value)
468
    {
469
      if (array_key_exists($key, $messages) && $messages[$key] === $value)
470
      {
471
        unset($messages[$key]);
472
      }
473
    }
474
 
475
    return $messages;
476
  }
477
 
478
  /**
479
   * Returns all options with non default values.
480
   *
481
   * @return string  A string representation of the options
482
   */
483
  protected function getOptionsWithoutDefaults()
484
  {
485
    $options = $this->options;
486
 
487
    // remove default option values
488
    foreach ($this->getDefaultOptions() as $key => $value)
489
    {
490
      if (array_key_exists($key, $options) && $options[$key] === $value)
491
      {
492
        unset($options[$key]);
493
      }
494
    }
495
 
496
    return $options;
497
  }
498
}