mirror of
https://github.com/yiisoft/yii2.git
synced 2025-08-14 06:11:35 +08:00
Fixes #2003: Added filter
property to ExistValidator
and UniqueValidator
to support adding additional filtering conditions
This commit is contained in:
@ -69,6 +69,7 @@ Yii Framework 2 Change Log
|
||||
- Enh #1921: Grid view ActionColumn now allow to name buttons like `{controller/action}` (creocoder)
|
||||
- Enh #1973: `yii message/extract` is now able to generate `.po` files (SergeiKutanov, samdark)
|
||||
- Enh #1984: ActionFilter will now mark event as handled when action run is aborted (cebe)
|
||||
- Enh #2003: Added `filter` property to `ExistValidator` and `UniqueValidator` to support adding additional filtering conditions (qiangxue)
|
||||
- Enh: Added `favicon.ico` and `robots.txt` to default application templates (samdark)
|
||||
- Enh: Added `Widget::autoIdPrefix` to support prefixing automatically generated widget IDs (qiangxue)
|
||||
- Enh: Support for file aliases in console command 'message' (omnilight)
|
||||
|
@ -54,6 +54,13 @@ class ExistValidator extends Validator
|
||||
* If the key and the value are the same, you can just specify the value.
|
||||
*/
|
||||
public $targetAttribute;
|
||||
/**
|
||||
* @var string|array|\Closure additional filter to be applied to the DB query used to check the existence of the attribute value.
|
||||
* This can be a string or an array representing the additional query condition (refer to [[\yii\db\Query::where()]]
|
||||
* on the format of query condition), or an anonymous function with the signature `function ($query)`, where `$query`
|
||||
* is the [[\yii\db\Query|Query]] object that you can modify in the function.
|
||||
*/
|
||||
public $filter;
|
||||
|
||||
|
||||
/**
|
||||
@ -72,8 +79,6 @@ class ExistValidator extends Validator
|
||||
*/
|
||||
public function validateAttribute($object, $attribute)
|
||||
{
|
||||
/** @var \yii\db\ActiveRecordInterface $targetClass */
|
||||
$targetClass = $this->targetClass === null ? get_class($object) : $this->targetClass;
|
||||
$targetAttribute = $this->targetAttribute === null ? $attribute : $this->targetAttribute;
|
||||
|
||||
if (is_array($targetAttribute)) {
|
||||
@ -92,8 +97,11 @@ class ExistValidator extends Validator
|
||||
}
|
||||
}
|
||||
|
||||
$targetClass = $this->targetClass === null ? get_class($object) : $this->targetClass;
|
||||
$query = $this->createQuery($targetClass, $params);
|
||||
|
||||
/** @var \yii\db\ActiveRecordInterface $className */
|
||||
if (!$targetClass::find()->where($params)->exists()) {
|
||||
if (!$query->exists()) {
|
||||
$this->addError($object, $attribute, $this->message);
|
||||
}
|
||||
}
|
||||
@ -113,10 +121,20 @@ class ExistValidator extends Validator
|
||||
throw new InvalidConfigException('The "targetAttribute" property must be configured as a string.');
|
||||
}
|
||||
|
||||
/** @var \yii\db\ActiveRecordInterface $targetClass */
|
||||
$targetClass = $this->targetClass;
|
||||
$query = $targetClass::find();
|
||||
$query->where([$this->targetAttribute => $value]);
|
||||
$query = $this->createQuery($this->targetClass, [$this->targetAttribute => $value]);
|
||||
|
||||
return $query->exists() ? null : [$this->message, []];
|
||||
}
|
||||
|
||||
protected function createQuery($targetClass, $condition)
|
||||
{
|
||||
/** @var \yii\db\ActiveRecordInterface $targetClass */
|
||||
$query = $targetClass::find()->where($condition);
|
||||
if ($this->filter instanceof \Closure) {
|
||||
call_user_func($this->filter, $query);
|
||||
} elseif ($this->filter !== null) {
|
||||
$query->andWhere($this->filter);
|
||||
}
|
||||
return $query;
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,13 @@ class UniqueValidator extends Validator
|
||||
* If the key and the value are the same, you can just specify the value.
|
||||
*/
|
||||
public $targetAttribute;
|
||||
/**
|
||||
* @var string|array|\Closure additional filter to be applied to the DB query used to check the uniqueness of the attribute value.
|
||||
* This can be a string or an array representing the additional query condition (refer to [[\yii\db\Query::where()]]
|
||||
* on the format of query condition), or an anonymous function with the signature `function ($query)`, where `$query`
|
||||
* is the [[\yii\db\Query|Query]] object that you can modify in the function.
|
||||
*/
|
||||
public $filter;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
@ -91,6 +98,12 @@ class UniqueValidator extends Validator
|
||||
$query = $targetClass::find();
|
||||
$query->where($params);
|
||||
|
||||
if ($this->filter instanceof \Closure) {
|
||||
call_user_func($this->filter, $query);
|
||||
} elseif ($this->filter !== null) {
|
||||
$query->andWhere($this->filter);
|
||||
}
|
||||
|
||||
if (!$object instanceof ActiveRecordInterface || $object->getIsNewRecord()) {
|
||||
// if current $object isn't in the database yet then it's OK just to call exists()
|
||||
$exists = $query->exists();
|
||||
|
Reference in New Issue
Block a user