Proposal: Custom Validation Objects #913

Closed
wants to merge 22 commits into
from
Jump to file or symbol
Failed to load files and symbols.
+86 −0
Diff settings

Always

Just for now

@@ -257,6 +257,9 @@ public function isUpdate($exists = null) {
/**
* Dispatches the validation rule to the given validator method
*
+ * Use "PluginName.ClassName::method" as validation rule name to refer to a custom validator object.
+ * /App/Plugin/Model/Validation/ClassName.php
+ *
* @return boolean True if the rule could be dispatched, false otherwise
*/
public function process($field, &$data, &$methods) {
@@ -271,6 +274,19 @@ public function process($field, &$data, &$methods) {
$this->_valid = call_user_func_array($methods[$rule], $this->_ruleParams);
} elseif (class_exists('Validation') && method_exists('Validation', $this->_rule)) {
$this->_valid = call_user_func_array(array('Validation', $this->_rule), $this->_ruleParams);
+ } elseif (strpos($this->_rule, '::') !== false) {
+ list($plugin, $class) = pluginSplit($this->_rule);
+ list($className, $method) = explode('::', $class);
+ $location = 'Model/Validation';
+ if ($plugin) {
+ $location = $plugin . '.' . $location;
+ }
+ App::uses($className, $location);
+ if (is_callable(array($className, $method))) {
+ $this->_valid = call_user_func_array(array($className, $method), $this->_ruleParams);
+ } else {
+ trigger_error(__d('cake_dev', 'Could not find custom validation rule %s', $this->_rule), E_USER_WARNING);
+ }
} elseif (is_string($validator['rule'])) {
$this->_valid = preg_match($this->_rule, $data[$field]);
} elseif (Configure::read('debug') > 0) {
@@ -0,0 +1,28 @@
+<?php
+/**
+ * CustomValidationObjectController
+ *
+ * This controller tryies to validate a model dataset with
+ * standard CakePHP model's validation rules.
+ *
+ * Output is created throught debug() method
+ */
+class CustomValidationObjectController extends AppController {
+
+ public $autoRender = false;
+
+ public $uses = array('CustomValidationModel');
+
+ public function index() {
+ $data = array('CustomValidationModel' => array(
+ 'name' => '',
+ 'surname' => '',
+ 'age' => '',
+ 'odd_number' => 23
+ ));
+ $this->CustomValidationModel->set($data);
+ $this->CustomValidationModel->validates();
+ debug($this->CustomValidationModel->validationErrors);

This comment has been minimized.

Show comment Hide comment
@ADmad

ADmad Nov 1, 2012

Member

Left over debug statement.

@ADmad

ADmad Nov 1, 2012

Member

Left over debug statement.

This comment has been minimized.

Show comment Hide comment
@marcopeg

marcopeg Nov 2, 2012

I'm not sure what you mean.
This debug() statement is part of the test to display validation errors generated by the model.

Please tell me how to change it to make this code meaningful to the test.

@marcopeg

marcopeg Nov 2, 2012

I'm not sure what you mean.
This debug() statement is part of the test to display validation errors generated by the model.

Please tell me how to change it to make this code meaningful to the test.

This comment has been minimized.

Show comment Hide comment
@ADmad

ADmad Nov 2, 2012

Member

You are not supposed to use debug() in test code to check variable contents. Do you you see such debugs anywhere in the other core tests? Use asserts in the test cases to compare the validation errors property against expected data.

@ADmad

ADmad Nov 2, 2012

Member

You are not supposed to use debug() in test code to check variable contents. Do you you see such debugs anywhere in the other core tests? Use asserts in the test cases to compare the validation errors property against expected data.

This comment has been minimized.

Show comment Hide comment
@marcopeg

marcopeg Nov 3, 2012

but I don't need to test a validation rule to work... I need to test a custom validation object is imported and initialized.
Don't know how to write that code.

Can you help?

@marcopeg

marcopeg Nov 3, 2012

but I don't need to test a validation rule to work... I need to test a custom validation object is imported and initialized.
Don't know how to write that code.

Can you help?

This comment has been minimized.

Show comment Hide comment
@markstory

markstory Nov 6, 2012

Member

The included controller file isn't necessary at all. Nor is the additional model class. You should add a unit test case to the existing model validation test suite. Here example of a method similar to what you would want.

@markstory

markstory Nov 6, 2012

Member

The included controller file isn't necessary at all. Nor is the additional model class. You should add a unit test case to the existing model validation test suite. Here example of a method similar to what you would want.

+ }
+
+}
@@ -0,0 +1,30 @@
+<?php
+/**
+ * CustomValidationModel
+ *
+ * It uses core "notEmpty" validation.
+ *
+ * a custom validation "CustomValidationObject::myCustomRule" loaded
+ * from /Model/Validation/CustomValidationObject
+ *
+ * and a non-existing validation from "NonExistingObject::nonExistingMethod".
+ * this rule will trigger a notice
+ */
+class CustomValidationModel extends AppModel {
+
+ public $useTable = false;
+
+ public $validate = array(
+ 'name' => 'notEmpty',
+ 'surname' => array(
+ 'rule' => 'CustomValidationObject::myCustomRule',
+ 'message' => 'value not accepted'
+ ),
+ 'age' => 'NonExistingObject::nonExistingMethod',
+ 'odd_number' => array(
+ 'rule' => 'CustomValidationObject::odd',
+ 'message' => 'Please insert odd number'
+ )
+ );
+
+}
@@ -0,0 +1,12 @@
+<?php
+class CustomValidationObject {
+
+ public static function odd($value) {
+ return $value & 1;
+ }
+
+ public static function myCustomRule($value) {
+ return self::odd(rand(2,10));
+ }
+
+}