1: <?php
  2:   3:   4:   5:   6:   7:   8:   9:  10:  11:  12:  13:  14:  15:  16:  17:  18:  19:  20: 
 21: 
 22: App::uses('Validation', 'Utility');
 23: 
 24:  25:  26:  27:  28:  29:  30: 
 31: class CakeValidationRule {
 32: 
 33:  34:  35:  36:  37: 
 38:     protected $_valid = true;
 39: 
 40:  41:  42:  43:  44: 
 45:     protected $_recordExists = false;
 46: 
 47:  48:  49:  50:  51: 
 52:     protected $_rule = null;
 53: 
 54:  55:  56:  57:  58: 
 59:     protected $_ruleParams = array();
 60: 
 61:  62:  63:  64:  65: 
 66:     protected $_passedOptions = array();
 67: 
 68:  69:  70:  71:  72: 
 73:     public $rule = 'blank';
 74: 
 75:  76:  77:  78:  79: 
 80:     public $required = null;
 81: 
 82:  83:  84:  85:  86: 
 87:     public $allowEmpty = null;
 88: 
 89:  90:  91:  92:  93: 
 94:     public $on = null;
 95: 
 96:  97:  98:  99: 100: 
101:     public $last = true;
102: 
103: 104: 105: 106: 107: 
108:     public $message = null;
109: 
110: 111: 112: 113: 114: 
115:     public function __construct($validator = array()) {
116:         $this->_addValidatorProps($validator);
117:     }
118: 
119: 120: 121: 122: 123: 
124:     public function isValid() {
125:         if (!$this->_valid || (is_string($this->_valid) && !empty($this->_valid))) {
126:             return false;
127:         }
128: 
129:         return true;
130:     }
131: 
132: 133: 134: 135: 136: 
137:     public function isEmptyAllowed() {
138:         return $this->skip() || $this->allowEmpty === true;
139:     }
140: 
141: 142: 143: 144: 145: 
146:     public function isRequired() {
147:         if (in_array($this->required, array('create', 'update'), true)) {
148:             if ($this->required === 'create' && !$this->isUpdate() || $this->required === 'update' && $this->isUpdate()) {
149:                 return true;
150:             } else {
151:                 return false;
152:             }
153:         }
154: 
155:         return $this->required;
156:     }
157: 
158: 159: 160: 161: 162: 163: 
164:     public function checkRequired($field, &$data) {
165:         return (
166:             (!array_key_exists($field, $data) && $this->isRequired() === true) ||
167:             (
168:                 array_key_exists($field, $data) && (empty($data[$field]) &&
169:                 !is_numeric($data[$field])) && $this->allowEmpty === false
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:     public function isUpdate($exists = null) {
251:         if ($exists === null) {
252:             return $this->_recordExists;
253:         }
254:         return $this->_recordExists = $exists;
255:     }
256: 
257: 258: 259: 260: 261: 
262:     public function process($field, &$data, &$methods) {
263:         $this->_valid = true;
264:         $this->_parseRule($field, $data);
265: 
266:         $validator = $this->_getPropertiesArray();
267:         $rule = strtolower($this->_rule);
268:         if (isset($methods[$rule])) {
269:             $this->_ruleParams[] = array_merge($validator, $this->_passedOptions);
270:             $this->_ruleParams[0] = array($field => $this->_ruleParams[0]);
271:             $this->_valid = call_user_func_array($methods[$rule], $this->_ruleParams);
272:         } elseif (class_exists('Validation') && method_exists('Validation', $this->_rule)) {
273:             $this->_valid = call_user_func_array(array('Validation', $this->_rule), $this->_ruleParams);
274:         } elseif (is_string($validator['rule'])) {
275:             $this->_valid = preg_match($this->_rule, $data[$field]);
276:         } elseif (Configure::read('debug') > 0) {
277:             trigger_error(__d('cake_dev', 'Could not find validation handler %s for %s', $this->_rule, $field), E_USER_WARNING);
278:             return false;
279:         }
280: 
281:         return true;
282:     }
283: 
284: 285: 286: 287: 288: 289: 
290:     public function reset() {
291:         $this->_valid = true;
292:         $this->_recordExists = false;
293:     }
294: 
295: 296: 297: 298: 299: 
300:     public function getOptions($key) {
301:         if (!isset($this->_passedOptions[$key])) {
302:             return null;
303:         }
304:         return $this->_passedOptions[$key];
305:     }
306: 
307: 308: 309: 310: 311: 312: 
313:     protected function _addValidatorProps($validator = array()) {
314:         if (!is_array($validator)) {
315:             $validator = array('rule' => $validator);
316:         }
317:         foreach ($validator as $key => $value) {
318:             if (isset($value) || !empty($value)) {
319:                 if (in_array($key, array('rule', 'required', 'allowEmpty', 'on', 'message', 'last'))) {
320:                     $this->{$key} = $validator[$key];
321:                 } else {
322:                     $this->_passedOptions[$key] = $value;
323:                 }
324:             }
325:         }
326:     }
327: 
328: 329: 330: 331: 332: 
333:     protected function _parseRule($field, &$data) {
334:         if (is_array($this->rule)) {
335:             $this->_rule = $this->rule[0];
336:             $this->_ruleParams = array_merge(array($data[$field]), array_values(array_slice($this->rule, 1)));
337:         } else {
338:             $this->_rule = $this->rule;
339:             $this->_ruleParams = array($data[$field]);
340:         }
341:     }
342: 
343: }
344: