2017-08-24 55 views
0

我正在使用CakePHP2.8,我想在模型之間共享多個自定義驗證方法。CakePHP 2共享自定義驗證方法,userDefined

我創建了一個幫助程序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在驗證器中的作用add不起作用,需要在多個模型之間重用許多自定義驗證方法。

感謝

+0

你確定這是不起作用的規則嗎?你測試過''beforeValidate()'方法是否被調用,特別是它被調用_before_驗證應用於'Job'模型數據? – ndm

+0

是的,我把一些登錄,在beforeValidate中的日誌工作在助手的規則沒有寫任何東西,所以沒有擊中規則。 – alistaircol

+0

您看過這個https://book.cakephp.org/2.0/en/models/data-validation.html#adding-your-own-validation-methods它解釋瞭如何正確定義自定義驗證方法 –

回答

0

你可以有幾個選擇這裏:

  • 定義自定義的驗證規則在AppModel,這樣你就可以在任何模型中使用,而不必複製
  • 創建一個抽象模型,例如Job,然後擴展此模型以創建CustomJobA,CustomJobB等,並在那裏定義自定義驗證。擴展Job模型的所有模型都可以使用您的驗證規則
  • 創建一個行爲並在其中定義驗證規則,並在任何模型上使用此行爲。