我的表单(忘记密码表单)上有两个字段:用户名和电子邮件 ID。用户应输入其中之一。我的意思是要检索密码,用户可以输入用户名或电子邮件 ID。有人能给我指出这一点的验证规则吗?
有我可以使用的内置规则吗?
我今天试图解决同样的问题。我得到的是下面的代码。
public function rules()
{
return array(
// array('username, email', 'required'), // Remove these fields from required!!
array('email', 'email'),
array('username, email', 'my_equired'), // do it below any validation of username and email field
);
}
public function my_required($attribute_name, $params)
{
if (empty($this->username)
&& empty($this->email)
) {
$this->addError($attribute_name, Yii::t('user', 'At least 1 of the field must be filled up properly'));
return false;
}
return true;
}
总体思路是将“必需”验证移至自定义 my_required() 方法,该方法可以检查是否填充了任何字段。
我看到这篇文章是 2011 年的,但我找不到任何其他解决方案。我希望它将来对您或其他人有用。
享受吧。
这样的东西更通用一点,可以重复使用。
public function rules() {
return array(
array('username','either','other'=>'email'),
);
}
public function either($attribute_name, $params)
{
$field1 = $this->getAttributeLabel($attribute_name);
$field2 = $this->getAttributeLabel($params['other']);
if (empty($this->$attribute_name) && empty($this->$params['other'])) {
$this->addError($attribute_name, Yii::t('user', "either {$field1} or {$field2} is required."));
return false;
}
return true;
}
Yii2
namespace common\components;
use yii\validators\Validator;
class EitherValidator extends Validator
{
/**
* @inheritdoc
*/
public function validateAttributes($model, $attributes = null)
{
$labels = [];
$values = [];
$attributes = $this->attributes;
foreach($attributes as $attribute) {
$labels[] = $model->getAttributeLabel($attribute);
if(!empty($model->$attribute)) {
$values[] = $model->$attribute;
}
}
if (empty($values)) {
$labels = '«' . implode('» or «', $labels) . '»';
foreach($attributes as $attribute) {
$this->addError($model, $attribute, "Fill {$labels}.");
}
return false;
}
return true;
}
}
型号:
public function rules()
{
return [
[['attribute1', 'attribute2', 'attribute3', ...], EitherValidator::className()],
];
}
我认为没有预定义的规则适用于这种情况,但是很容易定义自己的规则,对于用户名和密码字段,规则是“if empty($username . $password) {返回错误}” - 您可能还想检查最小长度或其他字段级要求。
这对我有用:
['clientGroupId', 'required', 'when' => function($model) {
return empty($model->clientId);
}, 'message' => 'Client group or client selection is required'],
您可以在模型类中使用私有属性来防止两次显示错误(不要将错误分配给模型的属性,而只添加到模型而不指定它):
class CustomModel extends CFormModel
{
public $username;
public $email;
private $_addOtherOneOfTwoValidationError = true;
public function rules()
{
return array(
array('username, email', 'requiredOneOfTwo'),
);
}
public function requiredOneOfTwo($attribute, $params)
{
if(empty($this->username) && empty($this->email))
{
// if error is not already added to model, add it!
if($this->_addOtherOneOfTwoValidationError)
{
$this->addErrors(array('Please enter your username or emailId.'));
// after first error adding, make error addition impossible
$this->_addOtherOneOfTwoValidationError = false;
}
return false;
}
return true;
}
}
不要忘记“skipOnEmpty”属性。这花了我几个小时。
protected function customRules()
{
return [
[['name', 'surname', 'phone'], 'compositeRequired', 'skipOnEmpty' => false,],
];
}
public function compositeRequired($attribute_name, $params)
{
if (empty($this->name)
&& empty($this->surname)
&& empty($this->phone)
) {
$this->addError($attribute_name, Yii::t('error', 'At least 1 of the field must be filled up properly'));
return false;
}
return true;
}
Yii 1
当然可以优化,但可能对某人有帮助
class OneOfThemRequiredValidator extends \CValidator
{
public function validateAttribute($object, $attribute)
{
$all_empty = true;
foreach($this->attributes as $_attribute) {
if (!$this->isEmpty($object->{$_attribute})) {
$all_empty = false;
break;
}
}
if ($all_empty) {
$message = "Either of the following attributes are required: ";
$attributes_labels = array_map(function($a) use ($object) {
return $object->getAttributeLabel($a);
}, $this->attributes);
$this->addError($object, $_attribute, $message . implode(',',
$attributes_labels));
}
}
}
yii1
public function rules(): array
{
return [
[
'id', // attribute for error
'requiredOneOf', // validator func
'id', // to params array
'name', // to params array
],
];
}
public function requiredOneOf($attribute, $params): void
{
$arr = array_filter($params, function ($key) {
return isset($this->$key);
});
if (empty($arr)) {
$this->addError(
$attribute,
Yii::t('yii', 'Required one of: [{attributes}]', [
'{attributes}' => implode(', ', $params),
])
);
}
}