CakePHP 2共享自定义验证方法,userDefined

时间:2017-08-24 12:29:08

标签: php validation cakephp cakephp-2.0 cakephp-2.8

我正在使用CakePHP2.8,我想在模型之间共享多种自定义验证方法。

我使用已知在模型中工作的自定义验证方法创建了一个帮助器CustomValidators.php类。 此处的逻辑不存在问题,此处仅用于说明。

<?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;
  }

}

我将此文件包含在模型JobCustomA中,并在beforeValidate中实例化。

  public function beforeValidate($options = [])
  {
    $CustomValidators = new CustomValidators();

我正在尝试在其模型中对JobCustomA进行所有验证,验证来自Job的数据。

在我的JobCustomA模型中,我想在Job上添加验证,我这样做:

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',
    ],
  ]);

  // ...
}

然而,似乎没有这些自定义验证方法,我不知道如何解决这个问题。我需要能够在许多类之间重用自定义验证方法,而不必在每个模型中重复它们。

TL; DR:在验证程序添加中使用userDefined角色无效,需要在多个模型之间重复使用许多自定义验证方法。

由于

1 个答案:

答案 0 :(得分:0)

你可以在这里有两个选择:

  • 在AppModel中定义自定义验证规则,这样您就可以在任何模型中使用它们而无需复制
  • 创建一个抽象模型,例如Job,然后扩展此模型以创建CustomJobA,CustomJobB等,并在那里定义自定义验证。扩展作业模型的所有模型都可以使用您的验证规则
  • 创建行为,并在那里定义验证规则,并在任何模型上使用此行为。