2012-04-08 8 views
3

私が拡張したベースモデルがあります。 ここでは、2つの検証フィルタを定義しました。レコードが一意であるかどうかをチェックし、レコードが存在するかどうかをチェックします。それらは、返り値が他の値の逆になることを除いて全く同じ方法で動作します。リチウム:別の内部から1つのバリデーションフィルタを呼び出す方法

したがって、異なる値を返すだけで同じコードを2回書くのは正しいとは言えません。 カスタムバリデーターを別のバリデーターから呼び出す方法を知りたいです。

<?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は次のように動作するはずです::

ここuniqueバリのための私のコードです

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

+0

また、内部で必要とされるため、$ valueを 'unique'メソッドに渡す必要があります。 – Housni

+1

ああ、偶然、 '$ self'の設定をコピーして貼り付けたと思うのですが、これは、現在のオブジェクトをコールバック内で利用できるようにするためにフィルタのいくつかで行う必要があるからです(' $ self'は '関数定義の 'use'節を参照してください)。 そして、私は '$ value'部分を修正しました。しかし、ええ、あなたのところに良い解決策。投稿を打つ前にページをリフレッシュしていれば私は投稿していないでしょう。 – rmarscher

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

Ha ...私は昨夜、上記の回答を起草しましたが、提出するのを忘れました。私はちょうど提出をヒットし、今あなたの答えを参照してください。しかし、ええ、同じこと。 – rmarscher

関連する問題