Skip to content

Proposal: Custom Validation Objects #912

Closed
wants to merge 11 commits into from

5 participants

@marcopeg

I've packed up a solution to use custom validation rules from outside the model class namespace.

I was inspired by a discussion and code-posting I found here (http://goo.gl/8u4FN) between MarkStory and saleh.

I changed /lib/Cake/Model/CakeValidationRule.php adding a code block to process() method to search for custom rules into external objects.

I find this solution mandatory to CakePHP letting developers to pack validation rules into their plugins!
I wrote a post to my blog to explain the problem and this solution: http://bit.ly/RXxw43

Bye,
MPeg.

marcopeg added some commits Oct 25, 2012
@marcopeg marcopeg Allow Custom Validator Objects
I propose a way to allow models to use custom validation rules from
external classes, even packed into plugins.

Proposal documentation and explanation:
http://bit.ly/RXxw43
357986c
@marcopeg marcopeg Custom Validation Objects
updated inline comment
58e01c6
@marcopeg marcopeg edit internal comments ecddfa3
@dereuromark dereuromark and 2 others commented on an outdated diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
+ * It allow to create a custom validator object like:
+ *
+ * // App/Model/Validation
+ * class MyValidator {
+ * public static function isReallyInt() {}
+ * }
+ *
+ * // App/Model/Users.php
+ * ...
+ * $validate = array(
+ * 'username' => 'MyValidator::isReallyInt'
+ *);
+ * ...
+ *
+ */
+ } elseif ( strpos($this->_rule , '::') ){
@dereuromark
CakePHP member
dereuromark added a note Oct 25, 2012

there shouldnt be any extra spaces (i count three)

@marcopeg
marcopeg added a note Oct 25, 2012

fixed

@dereuromark
CakePHP member
dereuromark added a note Oct 25, 2012

not really, before commas there are also no spaces. but after.

@AD7six
CakePHP member
AD7six added a note Oct 25, 2012
} elseif (strpos($this->_rule ,'::')) {

should be

} elseif (strpos($this->_rule,'::')) {

It's a good idea to run your code though phpcs using the cake code standard

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@dereuromark dereuromark and 1 other commented on an outdated diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
+ * // App/Model/Users.php
+ * ...
+ * $validate = array(
+ * 'username' => 'MyValidator::isReallyInt'
+ *);
+ * ...
+ *
+ */
+ } elseif ( strpos($this->_rule , '::') ){
+
+ list($plugin, $class) = pluginSplit($this->_rule);
+ list($className,$method) = explode('::',$class);
+
+ // Contestualize lazy loading to validation repository even into plugins
+ $location = 'Model/Validation';
+ if ( $plugin ) $location = $plugin.'.'.$location;
@dereuromark
CakePHP member
dereuromark added a note Oct 25, 2012

but between concat there should: $plugin . '.' . $location

@marcopeg
marcopeg added a note Oct 25, 2012

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ADmad
CakePHP member
ADmad commented Oct 25, 2012

Please follow cake's coding standards. Use the code sniffer. Also remove comments from the code.

@marcopeg

willco

@ADmad
CakePHP member
ADmad commented Oct 25, 2012

The validator can already use behavior functions too for validation so you can just keep all your custom functions in a behavior for easy manageability and usability. So I am not sure if the ability to use any arbitrary function for validation is really necessary.

@AD7six AD7six and 1 other commented on an outdated diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
if (isset($methods[$rule])) {
$this->_ruleParams[] = array_merge($validator, $this->_passedOptions);
$this->_ruleParams[0] = array($field => $this->_ruleParams[0]);
$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);
+
+
@AD7six
CakePHP member
AD7six added a note Oct 25, 2012

double new line

@marcopeg
marcopeg added a note Oct 25, 2012

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@AD7six AD7six and 1 other commented on an outdated diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
if (isset($methods[$rule])) {
$this->_ruleParams[] = array_merge($validator, $this->_passedOptions);
$this->_ruleParams[0] = array($field => $this->_ruleParams[0]);
$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);
+
+
+ /**
@AD7six
CakePHP member
AD7six added a note Oct 25, 2012

no inline docs - use the funcion doc block

@marcopeg
marcopeg added a note Oct 25, 2012

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@AD7six AD7six and 1 other commented on an outdated diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -265,14 +265,55 @@ public function process($field, &$data, &$methods) {
$validator = $this->_getPropertiesArray();
$rule = strtolower($this->_rule);
+
+
@AD7six
CakePHP member
AD7six added a note Oct 25, 2012

double new line

@marcopeg
marcopeg added a note Oct 25, 2012

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@AD7six AD7six and 1 other commented on an outdated diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
+ * }
+ *
+ * // App/Model/Users.php
+ * ...
+ * $validate = array(
+ * 'username' => 'MyValidator::isReallyInt'
+ *);
+ * ...
+ *
+ */
+ } elseif (strpos($this->_rule ,'::')) {
+
+ list($plugin, $class) = pluginSplit($this->_rule);
+ list($className,$method) = explode('::',$class);
+
+ // Contestualize lazy loading to validation repository even into plugins
@AD7six
CakePHP member
AD7six added a note Oct 25, 2012

no idea what Contestualize means, but please avoid inline comments. if it's not in a doc block - it doesn't show up in the api.

@marcopeg
marcopeg added a note Oct 25, 2012

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@AD7six AD7six and 1 other commented on an outdated diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
} elseif (is_string($validator['rule'])) {
$this->_valid = preg_match($this->_rule, $data[$field]);
+
+
+
@AD7six
CakePHP member
AD7six added a note Oct 25, 2012

more extra newlines

@marcopeg
marcopeg added a note Oct 25, 2012

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@marcopeg

@ADmad behaviors is meant to collect shared model logic.

I think to model logic as "what a model does with data".
Validation rules are "how data was expected to be".

Add or remove or changes validation rules applied to model's data is a model logic and should be shifted to a behavior.

Extend core validation methods adding some general pourpose validation is not responsibility of any behavior.

CakePHP core collects validation rules in a class who's not a behavior so I think my proposal is a good and correct interpretation of difference between behaviors and validation objects.

(i will fix my code to fit CakePHP standards in a few hours)

@markstory
CakePHP member

Where are the tests? This will not be merged without tests.

@markstory
CakePHP member

Additionally new features will not be merged onto the master branch. You will probably have to open a new pull request against the 2.3 branch.

@markstory markstory commented on the diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,13 @@ public function process($field, &$data, &$methods) {
$this->_valid = call_user_func_array($methods[$rule], $this->_ruleParams);
@markstory
CakePHP member
markstory added a note Oct 25, 2012

Missing braces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@markstory markstory commented on the diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -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
@markstory
CakePHP member
markstory added a note Oct 25, 2012

Missing spaces after ,. Please use the code sniffer for these types of errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@markstory markstory commented on an outdated diff Oct 25, 2012
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,13 @@ 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 ,'::')) {
+ list($plugin, $class) = pluginSplit($this->_rule);
@markstory
CakePHP member
markstory added a note Oct 25, 2012

Braces are required around all control structures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@marcopeg

@markstory i'm not really sure how to produce tests for this code. it just load a class from a repo then search inside for a static method to call.

I will create a new pull request to the 2.3 branch.

@dereuromark
CakePHP member

closing as duplicate of the new PR

@zeroasterisk zeroasterisk pushed a commit that referenced this pull request Oct 31, 2012
@markstory markstory Fix issue in TimeHelper with translated values.
LC_TIME files using unicode code points would incorrectly display.
Use either the Multibyte class or mbstring to correctly detect
and convert values.

Fixes #912
b587537
@destinydriven destinydriven pushed a commit that referenced this pull request Jan 7, 2013
@markstory markstory Fix issue in TimeHelper with translated values.
LC_TIME files using unicode code points would incorrectly display.
Use either the Multibyte class or mbstring to correctly detect
and convert values.

Fixes #912

Conflicts:

	lib/Cake/View/Helper/TimeHelper.php
c8ab4ad
@ggiraudon ggiraudon pushed a commit that referenced this pull request Nov 27, 2015
@markstory markstory Fix issue in TimeHelper with translated values.
LC_TIME files using unicode code points would incorrectly display.
Use either the Multibyte class or mbstring to correctly detect
and convert values.

Fixes #912
8bf10c2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.