我有一个扩展的基础模型。 在其中,我定义了两个验证过滤器。一个检查记录是否唯一,另一个检查记录是否存在。它们的工作方式完全相同,只是返回值与另一个相反。
因此,将相同的代码编写两次以仅返回不同的值听起来是不对的。 我想知道如何从另一个调用一个自定义验证器。
以下是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);
});
?>
但显然,不可能那样做。我是否必须将验证函数定义为匿名函数,将其分配给变量并将其传递给而不是闭包?
或者我可以从unique
内拨打exists
吗?
答案 0 :(得分:2)
匿名函数方法可行。然后,您可以在为“存在”验证器定义的另一个匿名函数中使用该变量。这是将其合并到基础模型类中的另一个想法:
<?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;
}
}
?>
答案 1 :(得分: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);
}
}
?>