I am using CakePHP2.8 and I would like to share multiple custom validation methods between models.
I have created a helper CustomValidators.php class using custom validation methods known to work within models. Logic here is not problem, here only for illustration.
<?php
App::uses('CakeLog', 'Utility');
class CustomValidators {
public function checkDateNotFuturePast($checks, $params)
{
$params += array(
'type' => 'past', //Date cannot be in the past
'current_date' => 'now', //Todays date
'include_current_date' => false //Allow current date to pass validation
);
CakeLog::write('error', print_r(json_encode([
'checks' => $checks,
'params' => $params,
]), true));
$date = array_values($checks)[0];
try {
$timezone = new DateTimeZone("UTC");
$input_date = new DateTime($date, $timezone);
$current_date = new DateTime($params['current_date'], $timezone);
} catch(Exception $e) {
return false;
}
switch ($params['type']) {
case 'future':
if($params['include_current_date']){
if($input_date->format('dmY') != $current_date->format('dmY')&&$input_date->format('U') > $current_date->format('U')) return false;
}else{
if($input_date->format('U') > $current_date->format('U')) return false;
}
break;
case 'past':
if($params['include_current_date']){
if($input_date->format('dmY') != $current_date->format('dmY')&&$input_date->format('U') <= $current_date->format('U')) return false;
}else{
if($input_date->format('U') < $current_date->format('U')) return false;
}
break;
}
return true;
}
public function checkNotOlderThan($check, $params)
{
CakeLog::write('error', 'CustomValidators::checkNotOlderThan');
$params += [
'current_date' => date('Y-m-d'),
];
CakeLog::write('error', print_r(json_encode([
'checks' => $checks,
'params' => $params,
]), true));
if (!isset($params['range'])) {
return false;
}
$date = array_values($check)[0];
try {
$current_date = new DateTime($params['current_date']);
$current_date->modify('-' . $params['range']);
$input_date = new DateTime($date);
} catch(Exception $e) {
return false;
}
if ($input_date >= $current_date) {
return true;
}
return false;
}
}
I am including this file in the model JobCustomA and instantiating it in beforeValidate.
public function beforeValidate($options = [])
{
$CustomValidators = new CustomValidators();
I'm trying to have all validation for JobCustomA in its model which will validate data from Job.
In my JobCustomA model I want to add validation on Job, I'm doing like so:
public function beforeValidate($options = [])
{
$CustomValidators = new CustomValidators();
$this->Job->validator()->add('deposit_paid', [
'not_future' => [
'rule' => [
'userDefined', $CustomValidators, 'checkDateNotFuturePast', [
'type' => 'future',
]
],
'message' => 'Deposit date can\'t be in the future',
],
'nottooold' => [
'rule' => [
'userDefined', $CustomValidators, 'checkNotOlderThan', [
'current_date' => date('Y-m-d'),
'range' => '120 days',
],
],
'message' => 'Deposit date can\'t have been paid more than 120 days ago',
],
]);
// ...
}
However it doesn't seem to be going to these custom validation methods, I'm not sure how to fix this. I need to be able to reuse custom validation methods between many classes without duplicating them in each model.
TL;DR: Using userDefined role in validator add is not working, need to reuse many custom validation methods between multiple models.
Thanks
beforeValidate()method is being invoked at all, and especially that it is being invoked before validation is applied on theJobmodel data?beforeValidate()callback is being invoked after the validation on the parent model has already been applied.