2012-04-08 41 views
3

我有一个扩展的基础模型。其中,我定义了两个验证过滤器。一个检查记录是否是唯一的,另一个检查记录是否存在。他们以完全相同的方式工作,除了返回值与其他值相反。锂:如何从另一个内部调用一个验证过滤器

因此,编写两次相同的代码只返回不同的值听起来不太合适。 我想知道如何从另一个调用一个自定义验证器。

这里是我的unique验证码:

<?php 
Validator::add('unique', function($value, $rule, $options) { 
    $model = $options['model']; 
    $primary = $model::meta('key'); 

    foreach ($options['conditions'] as $field => $check) { 
     if (!is_numeric($field)) { 
      if (is_array($check)) { 
       /** 
       * array(
       * 'exists', 
       * 'message' => 'You are too old.', 
       * 'conditions' => array(
       *  
       *  'Users.age' => array('>' => '18') 
       * ) 
       *) 
       */ 
       $conditions[$field] = $check; 
      } 
     } else { 
      /** 
      * Regular lithium conditions array: 
      * array(
      * 'exists', 
      * 'message' => 'This email already exists.', 
      * 'conditions' => array(
      *  'Users.email' //no key ($field) defined 
      * ) 
      *) 
      */ 
      $conditions[$check] = $value; 
     } 
    } 

    /** 
    * Checking to see if the entity exists. 
    * If it exists, record exists. 
    * If record exists, we make sure the record is not checked 
    * against itself by matching with the primary key. 
    */ 
    if (isset($options['values'][$primary])) { 
     //primary key value exists so it's probably an update 
     $conditions[$primary] = array('!=' => $options['values'][$primary]); 
    } 

    $exists = $model::count($conditions); 
    return ($exists) ? false : true; 
}); 
?> 

exists应该像这样工作:

<?php 
Validator::add('exists', function($value, $rule, $options) { 
    $model = $options['model']; 
    return !$model::unique($value, $rule, $options); 
}); 
?> 

但很明显,它不能那么做。我是否必须将验证函数定义为匿名函数,将其分配给一个变量并将其传入而不是关闭? 或者我可以从exists内拨打unique吗?

回答

2

匿名函数方法将工作。然后你可以在你为'exists'验证器定义的另一个匿名函数中使用该变量。这里的另一个想法,将其合并到你的基础模型类:

<?php 

namespace app\data\Model; 

use lithium\util\Validator; 

class Model extends \lithium\data\Model { 

    public static function __init() { 
     static::_isBase(__CLASS__, true); 
     Validator::add('unique', function($value, $rule, $options) { 
      $model = $options['model']; 
      return $model::unique(compact('value') + $options); 
     }); 
     Validator::add('exists', function($value, $rule, $options) { 
      $model = $options['model']; 
      return !$model::unique(compact('value') + $options); 
     }); 
     parent::__init(); 
    } 

    // ... code ... 

    public static function unique($options) { 
     $primary = static::meta('key'); 

     foreach ($options['conditions'] as $field => $check) { 
      if (!is_numeric($field)) { 
       if (is_array($check)) { 
        /** 
        * array(
        * 'exists', 
        * 'message' => 'You are too old.', 
        * 'conditions' => array(
        * 
        *  'Users.age' => array('>' => '18') 
        * ) 
        *) 
        */ 
        $conditions[$field] = $check; 
       } 
      } else { 
       /** 
       * Regular lithium conditions array: 
       * array(
       * 'exists', 
       * 'message' => 'This email already exists.', 
       * 'conditions' => array(
       *  'Users.email' //no key ($field) defined 
       * ) 
       *) 
       */ 
       $conditions[$check] = $options['value']; 
      } 
     } 

     /** 
     * Checking to see if the entity exists. 
     * If it exists, record exists. 
     * If record exists, we make sure the record is not checked 
     * against itself by matching with the primary key. 
     */ 
     if (isset($options['values'][$primary])) { 
      //primary key value exists so it's probably an update 
      $conditions[$primary] = array('!=' => $options['values'][$primary]); 
     } 

     $exists = $model::count($conditions); 
     return ($exists) ? false : true; 
    } 

} 

?> 
+0

谢谢@rmarscher。 我看到你缩短了回报线,傻了我,我应该这样做:) 但是你为什么要在那里设置'$ self'? – Housni 2012-04-10 21:20:56

+0

此外,您必须将$ value传递给'unique'方法,因为它在里面需要。 – Housni 2012-04-10 21:24:07

+1

嗯,我想我无意中复制并粘贴'$ self'设置,因为我必须在我的一些过滤器中这样做,以使当前对象在回调中可用('$ self'然后通过'使用函数定义的子句)。 我修复了'$ value'部分。但是,是的,你的方式很好的解决方案。如果我在提交之前刷新了页面,我不会发布我的。 – rmarscher 2012-04-13 01:51:37

1

我最终创建了一个单独的方法,其中包含我需要的功能,然后从我的验证过滤器调用它。 我已经修剪了我的基本模型,只保留其中的相关数据。希望它能帮助有类似问题的人。

<?php 
namespace app\extensions\data; 
class Model extends \lithium\data\Model { 

    public static function __init() { 
     parent::__init(); 

     Validator::add('unique', function($value, $rule, $options) { 
      $model = $options['model']; 
      return ($model::exists($value, $rule, $options, $model)) ? false : true; 
     }); 

     Validator::add('exists', function($value, $rule, $options) { 
      $model = $options['model']; 
      return ($model::exists($value, $rule, $options, $model)) ? true : false; 
     }); 
    } 


    public static function exists($value, $rule, $options, $model) { 
     $field = $options['field']; 
     $primary = $model::meta('key'); 

     if (isset($options['conditions']) && !empty($options['conditions'])) { 
      //go here only of `conditions` are given 
      foreach ($options['conditions'] as $field => $check) { 
       if (!is_numeric($field)) { 
        if (is_array($check)) { 
         /** 
         * 'conditions' => array(
         *  'Users.age' => array('>' => 18) //condition with custom operator 
         * ) 
         */ 
         $conditions[$field] = $check; 
        } 
       } else { 
        /** 
        * Regular lithium conditions array: 
        * 'conditions' => array(
        *  'Users.email' //no key ($field) defined 
        * ) 
        */ 
        $conditions[$check] = $value; 
       } 
      } 
     } else { 
      //since `conditions` is not set, we assume 
      $modelName = $model::meta('name'); 
      $conditions["$modelName.$field"] = $value; 
     } 

     /** 
     * Checking to see if the entity exists. 
     * If it exists, record exists. 
     * If record exists, we make sure the record is not checked 
     * against itself by matching with the primary key. 
     */ 
     if (isset($options['values'][$primary])) { 
      //primary key value exists so it's probably an update 
      $conditions[$primary] = array('!=' => $options['values'][$primary]); 
     } 

     return $model::count($conditions); 
    } 
} 
?> 
+0

哈......昨天晚上我起草了上面的回答,却忘了点击提交。我刚刚提交,现在我看到了你的答案。但是,同样的事情。 – rmarscher 2012-04-10 20:56:43

相关问题