简体   繁体   中英

CakePHP 2 sharing custom validation methods, userDefined

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

You could have couple options here:

  • Define the custom validation rules in the AppModel, this way you can use them in any model without copying
  • Create an abstract model, for example Job, and then extend this model to create CustomJobA, CustomJobB etc, and define the custom validations there. All the models which extends the Job model could use your validation rules
  • Create a behavior, and define the validation rules there, and use this behavior on any model.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM