統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Model / Validator / CakeValidationSet.php @ 0b1b8047

履歴 | 表示 | アノテート | ダウンロード (8.154 KB)

1
<?php
2
/**
3
 * CakeValidationSet.
4
 *
5
 * Provides the Model validation logic.
6
 *
7
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
 *
10
 * Licensed under The MIT License
11
 * For full copyright and license information, please see the LICENSE.txt
12
 * Redistributions of files must retain the above copyright notice.
13
 *
14
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
15
 * @link          http://cakephp.org CakePHP(tm) Project
16
 * @package       Cake.Model.Validator
17
 * @since         CakePHP(tm) v 2.2.0
18
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
19
 */
20

    
21
App::uses('CakeValidationRule', 'Model/Validator');
22

    
23
/**
24
 * CakeValidationSet object. Holds all validation rules for a field and exposes
25
 * methods to dynamically add or remove validation rules
26
 *
27
 * @package       Cake.Model.Validator
28
 * @link          http://book.cakephp.org/2.0/en/data-validation.html
29
 */
30
class CakeValidationSet implements ArrayAccess, IteratorAggregate, Countable {
31

    
32
/**
33
 * Holds the CakeValidationRule objects
34
 *
35
 * @var array
36
 */
37
        protected $_rules = array();
38

    
39
/**
40
 * List of methods available for validation
41
 *
42
 * @var array
43
 */
44
        protected $_methods = array();
45

    
46
/**
47
 * I18n domain for validation messages.
48
 *
49
 * @var string
50
 */
51
        protected $_validationDomain = null;
52

    
53
/**
54
 * Whether the validation is stopped
55
 *
56
 * @var bool
57
 */
58
        public $isStopped = false;
59

    
60
/**
61
 * Holds the fieldname
62
 *
63
 * @var string
64
 */
65
        public $field = null;
66

    
67
/**
68
 * Holds the original ruleSet
69
 *
70
 * @var array
71
 */
72
        public $ruleSet = array();
73

    
74
/**
75
 * Constructor
76
 *
77
 * @param string $fieldName The fieldname.
78
 * @param array $ruleSet Rules set.
79
 */
80
        public function __construct($fieldName, $ruleSet) {
81
                $this->field = $fieldName;
82

    
83
                if (!is_array($ruleSet) || (is_array($ruleSet) && isset($ruleSet['rule']))) {
84
                        $ruleSet = array($ruleSet);
85
                }
86

    
87
                foreach ($ruleSet as $index => $validateProp) {
88
                        $this->_rules[$index] = new CakeValidationRule($validateProp);
89
                }
90
                $this->ruleSet = $ruleSet;
91
        }
92

    
93
/**
94
 * Sets the list of methods to use for validation
95
 *
96
 * @param array &$methods Methods list
97
 * @return void
98
 */
99
        public function setMethods(&$methods) {
100
                $this->_methods =& $methods;
101
        }
102

    
103
/**
104
 * Sets the I18n domain for validation messages.
105
 *
106
 * @param string $validationDomain The validation domain to be used.
107
 * @return void
108
 */
109
        public function setValidationDomain($validationDomain) {
110
                $this->_validationDomain = $validationDomain;
111
        }
112

    
113
/**
114
 * Runs all validation rules in this set and returns a list of
115
 * validation errors
116
 *
117
 * @param array $data Data array
118
 * @param bool $isUpdate Is record being updated or created
119
 * @return array list of validation errors for this field
120
 */
121
        public function validate($data, $isUpdate = false) {
122
                $this->reset();
123
                $errors = array();
124
                foreach ($this->getRules() as $name => $rule) {
125
                        $rule->isUpdate($isUpdate);
126
                        if ($rule->skip()) {
127
                                continue;
128
                        }
129

    
130
                        $checkRequired = $rule->checkRequired($this->field, $data);
131
                        if (!$checkRequired && array_key_exists($this->field, $data)) {
132
                                if ($rule->checkEmpty($this->field, $data)) {
133
                                        break;
134
                                }
135
                                $rule->process($this->field, $data, $this->_methods);
136
                        }
137

    
138
                        if ($checkRequired || !$rule->isValid()) {
139
                                $errors[] = $this->_processValidationResponse($name, $rule);
140
                                if ($rule->isLast()) {
141
                                        break;
142
                                }
143
                        }
144
                }
145

    
146
                return $errors;
147
        }
148

    
149
/**
150
 * Resets internal state for all validation rules in this set
151
 *
152
 * @return void
153
 */
154
        public function reset() {
155
                foreach ($this->getRules() as $rule) {
156
                        $rule->reset();
157
                }
158
        }
159

    
160
/**
161
 * Gets a rule for a given name if exists
162
 *
163
 * @param string $name Field name.
164
 * @return CakeValidationRule
165
 */
166
        public function getRule($name) {
167
                if (!empty($this->_rules[$name])) {
168
                        return $this->_rules[$name];
169
                }
170
        }
171

    
172
/**
173
 * Returns all rules for this validation set
174
 *
175
 * @return array
176
 */
177
        public function getRules() {
178
                return $this->_rules;
179
        }
180

    
181
/**
182
 * Sets a CakeValidationRule $rule with a $name
183
 *
184
 * ## Example:
185
 *
186
 * ```
187
 *                $set
188
 *                        ->setRule('required', array('rule' => 'notBlank', 'required' => true))
189
 *                        ->setRule('between', array('rule' => array('lengthBetween', 4, 10))
190
 * ```
191
 *
192
 * @param string $name The name under which the rule should be set
193
 * @param CakeValidationRule|array $rule The validation rule to be set
194
 * @return $this
195
 */
196
        public function setRule($name, $rule) {
197
                if (!($rule instanceof CakeValidationRule)) {
198
                        $rule = new CakeValidationRule($rule);
199
                }
200
                $this->_rules[$name] = $rule;
201
                return $this;
202
        }
203

    
204
/**
205
 * Removes a validation rule from the set
206
 *
207
 * ## Example:
208
 *
209
 * ```
210
 *                $set
211
 *                        ->removeRule('required')
212
 *                        ->removeRule('inRange')
213
 * ```
214
 *
215
 * @param string $name The name under which the rule should be unset
216
 * @return $this
217
 */
218
        public function removeRule($name) {
219
                unset($this->_rules[$name]);
220
                return $this;
221
        }
222

    
223
/**
224
 * Sets the rules for a given field
225
 *
226
 * ## Example:
227
 *
228
 * ```
229
 *                $set->setRules(array(
230
 *                        'required' => array('rule' => 'notBlank', 'required' => true),
231
 *                        'inRange' => array('rule' => array('between', 4, 10)
232
 *                 ));
233
 * ```
234
 *
235
 * @param array $rules The rules to be set
236
 * @param bool $mergeVars [optional] If true, merges vars instead of replace. Defaults to true.
237
 * @return $this
238
 */
239
        public function setRules($rules = array(), $mergeVars = true) {
240
                if ($mergeVars === false) {
241
                        $this->_rules = array();
242
                }
243
                foreach ($rules as $name => $rule) {
244
                        $this->setRule($name, $rule);
245
                }
246
                return $this;
247
        }
248

    
249
/**
250
 * Fetches the correct error message for a failed validation
251
 *
252
 * @param string $name the name of the rule as it was configured
253
 * @param CakeValidationRule $rule the object containing validation information
254
 * @return string
255
 */
256
        protected function _processValidationResponse($name, $rule) {
257
                $message = $rule->getValidationResult();
258
                if (is_string($message)) {
259
                        return $message;
260
                }
261
                $message = $rule->message;
262

    
263
                if ($message !== null) {
264
                        $args = null;
265
                        if (is_array($message)) {
266
                                $result = $message[0];
267
                                $args = array_slice($message, 1);
268
                        } else {
269
                                $result = $message;
270
                        }
271
                        if (is_array($rule->rule) && $args === null) {
272
                                $args = array_slice($rule->rule, 1);
273
                        }
274
                        $args = $this->_translateArgs($args);
275

    
276
                        $message = __d($this->_validationDomain, $result, $args);
277
                } elseif (is_string($name)) {
278
                        if (is_array($rule->rule)) {
279
                                $args = array_slice($rule->rule, 1);
280
                                $args = $this->_translateArgs($args);
281
                                $message = __d($this->_validationDomain, $name, $args);
282
                        } else {
283
                                $message = __d($this->_validationDomain, $name);
284
                        }
285
                } else {
286
                        $message = __d('cake', 'This field cannot be left blank');
287
                }
288

    
289
                return $message;
290
        }
291

    
292
/**
293
 * Applies translations to validator arguments.
294
 *
295
 * @param array $args The args to translate
296
 * @return array Translated args.
297
 */
298
        protected function _translateArgs($args) {
299
                foreach ((array)$args as $k => $arg) {
300
                        if (is_string($arg)) {
301
                                $args[$k] = __d($this->_validationDomain, $arg);
302
                        }
303
                }
304
                return $args;
305
        }
306

    
307
/**
308
 * Returns whether an index exists in the rule set
309
 *
310
 * @param string $index name of the rule
311
 * @return bool
312
 */
313
        public function offsetExists($index) {
314
                return isset($this->_rules[$index]);
315
        }
316

    
317
/**
318
 * Returns a rule object by its index
319
 *
320
 * @param string $index name of the rule
321
 * @return CakeValidationRule
322
 */
323
        public function offsetGet($index) {
324
                return $this->_rules[$index];
325
        }
326

    
327
/**
328
 * Sets or replace a validation rule.
329
 *
330
 * This is a wrapper for ArrayAccess. Use setRule() directly for
331
 * chainable access.
332
 *
333
 * @param string $index Name of the rule.
334
 * @param CakeValidationRule|array $rule Rule to add to $index.
335
 * @return void
336
 * @see http://www.php.net/manual/en/arrayobject.offsetset.php
337
 */
338
        public function offsetSet($index, $rule) {
339
                $this->setRule($index, $rule);
340
        }
341

    
342
/**
343
 * Unsets a validation rule
344
 *
345
 * @param string $index name of the rule
346
 * @return void
347
 */
348
        public function offsetUnset($index) {
349
                unset($this->_rules[$index]);
350
        }
351

    
352
/**
353
 * Returns an iterator for each of the rules to be applied
354
 *
355
 * @return ArrayIterator
356
 */
357
        public function getIterator() {
358
                return new ArrayIterator($this->_rules);
359
        }
360

    
361
/**
362
 * Returns the number of rules in this set
363
 *
364
 * @return int
365
 */
366
        public function count() {
367
                return count($this->_rules);
368
        }
369

    
370
}