1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19: 
 20: 
 21: App::uses('Validation', 'Utility');
 22: 
 23:  24:  25:  26:  27:  28:  29: 
 30: class CakeValidationRule {
 31: 
 32:  33:  34:  35:  36: 
 37:     protected $_valid = true;
 38: 
 39:  40:  41:  42:  43: 
 44:     protected $_recordExists = false;
 45: 
 46:  47:  48:  49:  50: 
 51:     protected $_rule = null;
 52: 
 53:  54:  55:  56:  57: 
 58:     protected $_ruleParams = array();
 59: 
 60:  61:  62:  63:  64: 
 65:     protected $_passedOptions = array();
 66: 
 67:  68:  69:  70:  71: 
 72:     public $rule = 'blank';
 73: 
 74:  75:  76:  77:  78: 
 79:     public $required = null;
 80: 
 81:  82:  83:  84:  85: 
 86:     public $allowEmpty = null;
 87: 
 88:  89:  90:  91:  92: 
 93:     public $on = null;
 94: 
 95:  96:  97:  98:  99: 
100:     public $last = true;
101: 
102: 103: 104: 105: 106: 
107:     public $message = null;
108: 
109: 110: 111: 112: 113: 
114:     public function __construct($validator = array()) {
115:         $this->_addValidatorProps($validator);
116:     }
117: 
118: 119: 120: 121: 122: 
123:     public function isValid() {
124:         if (!$this->_valid || (is_string($this->_valid) && !empty($this->_valid))) {
125:             return false;
126:         }
127: 
128:         return true;
129:     }
130: 
131: 132: 133: 134: 135: 
136:     public function isEmptyAllowed() {
137:         return $this->skip() || $this->allowEmpty === true;
138:     }
139: 
140: 141: 142: 143: 144: 
145:     public function isRequired() {
146:         if (in_array($this->required, array('create', 'update'), true)) {
147:             if ($this->required === 'create' && !$this->isUpdate() || $this->required === 'update' && $this->isUpdate()) {
148:                 return true;
149:             }
150:             return false;
151:         }
152: 
153:         return $this->required;
154:     }
155: 
156: 157: 158: 159: 160: 161: 162: 
163:     public function checkRequired($field, &$data) {
164:         return (
165:             (!array_key_exists($field, $data) && $this->isRequired() === true) ||
166:             (
167:                 array_key_exists($field, $data) && (empty($data[$field]) &&
168:                 !is_numeric($data[$field])) && $this->allowEmpty === false
169:             )
170:         );
171:     }
172: 
173: 174: 175: 176: 177: 178: 179: 
180:     public function checkEmpty($field, &$data) {
181:         if (empty($data[$field]) && $data[$field] != '0' && $this->allowEmpty === true) {
182:             return true;
183:         }
184:         return false;
185:     }
186: 
187: 188: 189: 190: 191: 
192:     public function skip() {
193:         if (!empty($this->on)) {
194:             if ($this->on === 'create' && $this->isUpdate() || $this->on === 'update' && !$this->isUpdate()) {
195:                 return true;
196:             }
197:         }
198:         return false;
199:     }
200: 
201: 202: 203: 204: 205: 206: 
207:     public function isLast() {
208:         return (bool)$this->last;
209:     }
210: 
211: 212: 213: 214: 215: 
216:     public function getValidationResult() {
217:         return $this->_valid;
218:     }
219: 
220: 221: 222: 223: 224: 
225:     protected function _getPropertiesArray() {
226:         $rule = $this->rule;
227:         if (!is_string($rule)) {
228:             unset($rule[0]);
229:         }
230:         return array(
231:             'rule' => $rule,
232:             'required' => $this->required,
233:             'allowEmpty' => $this->allowEmpty,
234:             'on' => $this->on,
235:             'last' => $this->last,
236:             'message' => $this->message
237:         );
238:     }
239: 
240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 
251:     public function isUpdate($exists = null) {
252:         if ($exists === null) {
253:             return $this->_recordExists;
254:         }
255:         return $this->_recordExists = $exists;
256:     }
257: 
258: 259: 260: 261: 262: 263: 264: 265: 
266:     public function process($field, &$data, &$methods) {
267:         $this->_valid = true;
268:         $this->_parseRule($field, $data);
269: 
270:         $validator = $this->_getPropertiesArray();
271:         $rule = strtolower($this->_rule);
272:         if (isset($methods[$rule])) {
273:             $this->_ruleParams[] = array_merge($validator, $this->_passedOptions);
274:             $this->_ruleParams[0] = array($field => $this->_ruleParams[0]);
275:             $this->_valid = call_user_func_array($methods[$rule], $this->_ruleParams);
276:         } elseif (class_exists('Validation') && method_exists('Validation', $this->_rule)) {
277:             $this->_valid = call_user_func_array(array('Validation', $this->_rule), $this->_ruleParams);
278:         } elseif (is_string($validator['rule'])) {
279:             $this->_valid = preg_match($this->_rule, $data[$field]);
280:         } else {
281:             trigger_error(__d('cake_dev', 'Could not find validation handler %s for %s', $this->_rule, $field), E_USER_WARNING);
282:             return false;
283:         }
284: 
285:         return true;
286:     }
287: 
288: 289: 290: 291: 292: 293: 
294:     public function reset() {
295:         $this->_valid = true;
296:         $this->_recordExists = false;
297:     }
298: 
299: 300: 301: 302: 303: 304: 
305:     public function getOptions($key) {
306:         if (!isset($this->_passedOptions[$key])) {
307:             return null;
308:         }
309:         return $this->_passedOptions[$key];
310:     }
311: 
312: 313: 314: 315: 316: 317: 
318:     protected function _addValidatorProps($validator = array()) {
319:         if (!is_array($validator)) {
320:             $validator = array('rule' => $validator);
321:         }
322:         foreach ($validator as $key => $value) {
323:             if (isset($value) || !empty($value)) {
324:                 if (in_array($key, array('rule', 'required', 'allowEmpty', 'on', 'message', 'last'))) {
325:                     $this->{$key} = $validator[$key];
326:                 } else {
327:                     $this->_passedOptions[$key] = $value;
328:                 }
329:             }
330:         }
331:     }
332: 
333: 334: 335: 336: 337: 338: 339: 
340:     protected function _parseRule($field, &$data) {
341:         if (is_array($this->rule)) {
342:             $this->_rule = $this->rule[0];
343:             $this->_ruleParams = array_merge(array($data[$field]), array_values(array_slice($this->rule, 1)));
344:         } else {
345:             $this->_rule = $this->rule;
346:             $this->_ruleParams = array($data[$field]);
347:         }
348:     }
349: 
350: }
351: