Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Proposal: Custom Validation Objects #913

Closed
wants to merge 22 commits into from

7 participants

@marcopeg

My proposal is to create a Model/Validation repo where to store validation rules collection classes.

This way we can keep model's logic into behaviors and validation logic into validation classes.

I don't know how to pack tests for this pull request.
Any suggestion welcome!

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);
+ list($className,$method) = explode('::',$class);
@ADmad Collaborator
ADmad added a note

Space missing after comma ,

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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);
+ list($className,$method) = explode('::',$class);
+ $location = 'Model/Validation';
+ if ( $plugin ) $location = $plugin . '.' . $location;
@ADmad Collaborator
ADmad added a note

Extra space after ( and before ). If block should always have braces {} even for single lines.

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
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);
+ list($className,$method) = explode('::',$class);
+ $location = 'Model/Validation';
+ if ( $plugin ) $location = $plugin . '.' . $location;
+ App::uses($className, $location);
+ if ( class_exists($className) ) $this->_valid = call_user_func_array(array($className, $method), $this->_ruleParams);
@ADmad Collaborator
ADmad added a note

Same comments are above. As requested earlier read the coding standards page on manual or used the code sniffer.

fixed

@majna
majna added a note

It's better to check for is_callable() here. Function call_user_func_array() could return false if Validation method doesn't exists or isn't visible in given context (which should be an error/exception, not invalid model data). Maybe I'm wrong, please check/test this case.

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

Please add a comment when you've checked your PR with the code sniffer, so we can focus on the changes and not the formatting discrepancies.

lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,15 @@ 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 ,'::')) {
@dereuromark Collaborator

still not the right spacing here

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,17 @@ 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);
+ list($className,$method) = explode('::', $class);
@dereuromark Collaborator

missing space

fixed

@dereuromark Collaborator

you dont need to always comment that its fixed. we can all see that :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,17 @@ 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);
+ list($className,$method) = explode('::', $class);
+ $location = 'Model/Validation';
+ if ( $plugin ) $location = $plugin . '.' . $location;
@dereuromark Collaborator

too many spaces, also always use {}

fixed (i will install code sniffer quite soon!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,17 @@ 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);
+ list($className,$method) = explode('::', $class);
+ $location = 'Model/Validation';
+ if ( $plugin ) $location = $plugin . '.' . $location;
+ App::uses($className, $location);
+ if (class_exists($className) && method_exists($className, $method)) {
+ $this->_valid = call_user_func_array(array($className, $method), $this->_ruleParams);
+ } else {
+ $this->_valid = false;
@majna
majna added a note

You should trigger_error here if validation handler is not found?

I consider non existing validation methods as failed validations... It's simplest than triggering errors.

Anyway we can listen other contributors thoughts and implement it.

@markstory Owner

An error is better. Failing the validation rule gives the wrong feedback.

ok, triggered an error.
i'm not sure if to tell user the rule should not be solved (actual implementation) or implement a deep investigation to define if class or method does not exist.

your opinion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,17 @@ 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, '::')) {
@dereuromark Collaborator

using strpos without type safe checks is never a good idea!

How do you suggest to change this line?

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

@dereuromark Collaborator

autsch. no. you usually use strpos with !== false

mmm I don't think so.

if given string is like "::something" then "!== false" is a true condition... but given string is a very bad error because does not contain any class name.

I need to enter the if tree only if "::" is upper than one.

@dereuromark Collaborator

I disagree. Passing "::somestring" would be invalid either way and the developers fault (you cant possibly cover all mistakes possible here).
But using the type safe check we would at least result in a meaningful exception: "trigger_error(__d('cake_dev', 'Could not find custom validation rule %s'" instead of trying to execute it as a preg match string.

@marcopeg
marcopeg added a note

understood, thank your for explanation.

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

An easy way to write tests for this is to include a sample validation object in the TestApp directory, and create a simple validation rule there, and use it. Ensure that it can both pass & fail validation on a model field. Without tests this will not be merged sorry.

@marcopeg marcopeg trigger_error
added a trigger_error instruction when try to load a non existing
method or non existing custom validation class as suggested by
@markstory
101d486
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,17 @@ 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);
+ list($className, $method) = explode('::', $class);
+ $location = 'Model/Validation';
+ if ($plugin) $location = $plugin . '.' . $location;
+ App::uses($className, $location);
+ if (class_exists($className) && method_exists($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);
+ }
@ADmad Collaborator
ADmad added a note

Extra space before ),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -271,6 +274,17 @@ 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);
+ list($className, $method) = explode('::', $class);
+ $location = 'Model/Validation';
+ if ($plugin) $location = $plugin . '.' . $location;
@ADmad Collaborator
ADmad added a note

Missing braces { }. Please take the trouble of carefully reading the coding standards page on the manual and setting up the code sniffer and fix all the formatting errors. We appreciate your contribution but your patch won't be merged in if it doesn't confer to cake's coding standards. Its really not practical for us to go about pointing out each mistake.

Once you are done please also squash your commits to avoid unnecessary noise in the repo history.

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

Finally installed phpcs, but be carefull... it does not alert me about white spaces near "()" or commas...
I tested it breaking code rules intentionally. It alert me about white lines... but not so more.

I installed pear and phpcs following cakepho git's rules and repos...

Anyway at writing time no alert is given by the phpcs utility.

@markstory i will create a test controller+model today. I create that files into the test-app then commit to this PR, right?

@markstory
Owner

@thepeg you also need to install the CakePHP codesniffer rules, and use them to check your code.

@marcopeg

@markstory i created a model, a custom validation object and a test controller in /test_app as requested.

All my code passed the phpcs test with CakePHP standards.

Running CustomValidationObject controller a debug will display validation errors for test data passed to the model.
A waring is thrown by a non existing validation rule. It is an intentional error to demonstrate how my code triggers errors if custom rule/object does not exists.

@markstory
Owner

Things look good on the phpcs front. However, there still aren't any test cases for the feature.

@marcopeg

@markstory uh, I didn't sync committed changes!

here are listed test files:
/test_app/Controller/CustomValidationObjectController.php
/test_app/Model/CustomValidationModel.php
/test_app/Model/Validation/CustomValidationObject.php

@ADmad
Collaborator

In the localised plugin recently the Validation folder was moved directly under the app folder, so for consistency here too it would be better to use app/Validation instead of app/Model/Validation

@marcopeg

@ADmad i'm not sure if your suggestion is really consistent to the CakePHP framework.
Let me explain my point of view.

Custom validation objects are always related to models.
Validation itself is a model stuff.

I'm quite sure to maintain app/Model/Validation structure for my plugin and I suggest to roll back in your.

@markstory what do you think about this question?

@ADmad
Collaborator

..in your.

@thepeg The "Localised" plugin is not my personal plugin. It's an offical CakePHP plugin maintained by the core devs.

@marcopeg

my mistake :-)

... but I think app/Validation is not the best organization for that kind of objects.

just wait for @markstory opinion... it's trivial to move from app/Model/Validation to app/Validation and vice-versa... it is not a technical problem, just organization!

thank you for comment this PR and suggest this argument!

@ADmad
Collaborator

For what it's worth I too prefer app/Model/Validation. But at the end of the day all I want is consistency.

@markstory
Owner

I prefer Model/Validation, as the model class is the one loading these validation classes. The localised repo, has extensions to the core Validation class, allowing you to do Validation::postal($value, 'nl'); I think they are different enough to be in different places.

I wonder if only allowing static methods is going to be a problem?

@marcopeg

Would you suggest an alternative?
Next days I will study the localised plugin to propose an enhancement to my PR.

@dereuromark
Collaborator

maybe the localized plugin then should be adjusted to also use app/Model/Validation - for the sake of consistency...

@AD7six
Collaborator

I agree with markstory regarding different purposes

But we currently have:

  • Cake\\Utility\\Validation
  • Localized\\Validation\\XXValidation
  • Model\\Validator

And with this PR

  • Plugin\\Model\\Validation\\X

4 different places for validation related classes seems a bit much.

@marcopeg

Please consider this assertion:
"validation is a model related stuff"

isn't true?

How do you do (the team) to make a decision about this kind of things?
This is mi first PR (but not the last) so I need to learn!

@AD7six
Collaborator

@thepeg not sure what your last comment means - models handle data, and data is the thing that gets validated. Validation is a model related task.

Decisions are made by discussion/agreement :).

@marcopeg

@AD7six you wrote what I mean, better :-)

so, can I keep my code implementing a "Model/Validation" folder structure?

@ADmad
Collaborator

@markstory the different purposes might be easily apparent to us experienced users but not to new users. 4 different locations for validation related classes which @AD7six pointed out will surely confuse them.

So I propose moving the localised validation classes back under Localized\Lib\Validation or under Localised\Model\Validation similar to this PR.

@thepeg No change needed to your PR :smile:. I think pretty much everyone is fine with having custom validation classes under Model\Validation

@markstory
Owner

@ADmad I agree that 4 is too many, especially given there are only 2 kinds of validation extensions we support. I would prefer we only have 2 places where custom validators can live :smile:

@AD7six I don't think plugins should count towards the total, as they are packaged sets of libraries. They basically duplicate the app folders.

lib/Cake/Model/Validator/CakeValidationRule.php
@@ -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, '::')) {
+ list($plugin, $class) = pluginSplit($this->_rule);
+ list($className, $method) = explode('::', $class);
+ $location = 'Model/Validation';
+ if ($plugin) {
+ $location = $plugin . '.' . $location;
+ }
+ App::uses($className, $location);
+ if (class_exists($className) && method_exists($className, $method)) {
@ADmad Collaborator
ADmad added a note

Why not just use is_callable() here.

@marcopeg
marcopeg added a note

good idea!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
...t_app/Controller/CustomValidationObjectController.php
@@ -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' );
@ADmad Collaborator
ADmad added a note

Extra space after ( and before )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
...t_app/Controller/CustomValidationObjectController.php
((2 lines not shown))
+/**
+ * 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(
@ADmad Collaborator
ADmad added a note

Extra space after array(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@ADmad ADmad commented on the diff
...t_app/Controller/CustomValidationObjectController.php
((10 lines not shown))
+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);
@ADmad Collaborator
ADmad added a note

Left over debug statement.

@marcopeg
marcopeg added a note

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.

@ADmad Collaborator
ADmad added a note

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.

@marcopeg
marcopeg added a note

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?

@markstory Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Cake/Test/test_app/Model/CustomValidationModel.php
((3 lines not shown))
+ * 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',
@ADmad Collaborator
ADmad added a note

Extra spaces before =>, same issue on next line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
lib/Cake/Model/Validator/CakeValidationRule.php
@@ -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, '::')) {
+ 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)) ) {
@dereuromark Collaborator

arent here still lots of coding standard violations?

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

I like the idea, but I think it is still half-baked. Not confortable with the idea of static only methods and it leaves things out like configuring validation. But it might be a good start while we figure out a more flexible approach.

@marcopeg

@lorenzo This conditional tree handles stati methods.

May be another PR will implement a different if-tree to handle an object/method rule format... like:

} elseif (is_array($this->_rule) && is_callable($this->_rule)) {

NOTE: above code is written just as a hypothesi...

@lorenzo lorenzo closed this
@lorenzo
Owner

Please reopen targeting the 2.4 branch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 25, 2012
  1. @marcopeg

    Allow Custom Validator Objects

    marcopeg authored
    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
  2. @marcopeg

    Custom Validation Objects

    marcopeg authored
    updated inline comment
  3. @marcopeg

    edit internal comments

    marcopeg authored
  4. @marcopeg
  5. @marcopeg

    fixed code standards

    marcopeg authored
  6. @marcopeg

    fixed code standards

    marcopeg authored
  7. @marcopeg

    fixed code standards

    marcopeg authored
  8. @marcopeg

    updated help block

    marcopeg authored
  9. @marcopeg

    fixed code standards

    marcopeg authored
  10. @marcopeg

    fixed code standards

    marcopeg authored
  11. @marcopeg
  12. @marcopeg

    fixed code standards

    marcopeg authored
Commits on Oct 26, 2012
  1. @marcopeg

    trigger_error

    marcopeg authored
    added a trigger_error instruction when try to load a non existing
    method or non existing custom validation class as suggested by
    @markstory
  2. @marcopeg

    fixed code standards

    marcopeg authored
  3. @marcopeg

    fixed code standards

    marcopeg authored
Commits on Oct 29, 2012
  1. @marcopeg
Commits on Oct 30, 2012
  1. @marcopeg

    updated test comments

    marcopeg authored
Commits on Nov 2, 2012
  1. @marcopeg

    fix PR suggestions

    marcopeg authored
Commits on Nov 3, 2012
  1. @marcopeg

    fix

    marcopeg authored
    thanks to @dereuromark
Commits on Jan 9, 2013
  1. @marcopeg

    10:19 up 12 days, 17:45, 2 users, load averages: 1,26 1,41 1,32

    marcopeg authored
    USER     TTY      FROM              LOGIN@  IDLE WHAT
    peg      console  -                27Dic12 12days -
    peg      s000     -                10:16       - w
Commits on Jan 15, 2013
  1. @marcopeg
Commits on Jan 20, 2013
  1. @marcopeg
This page is out of date. Refresh to see the latest.
View
16 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
*/
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) {
View
28 lib/Cake/Test/test_app/Controller/CustomValidationObjectController.php
@@ -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);
@ADmad Collaborator
ADmad added a note

Left over debug statement.

@marcopeg
marcopeg added a note

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.

@ADmad Collaborator
ADmad added a note

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.

@marcopeg
marcopeg added a note

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?

@markstory Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ }
+
+}
View
30 lib/Cake/Test/test_app/Model/CustomValidationModel.php
@@ -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'
+ )
+ );
+
+}
View
12 lib/Cake/Test/test_app/Model/Validation/CustomValidationObject.php
@@ -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));
+ }
+
+}
Something went wrong with that request. Please try again.