mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-13 04:38:03 +08:00
Merge pull request #2885 branch 'query-filter'
* query-filter: added CHANGELOG lines added tests for redis added proper tests for elasticsearch removed unnecessary code duplication adjusted tests typo renamed Query::filter() to Query::filterWhere() reverted elasticsearch rename of filter Adjusted search model code generated by Gii CRUD generator Added support for arbitrary number of parameters for NOT, AND, OR in filter methods of Query Gii CRUD generator now uses new addFilter method Query::filter() adjustments fixes #2002 Added tests for Query::filter() Conflicts: framework/db/QueryTrait.php
This commit is contained in:
@@ -114,6 +114,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 #2002: Added filterWhere() method to yii\db\Query to allow easy addition of search filter conditions by ignoring empty search fields (samdark, cebe)
|
||||
- Enh #2003: Added `filter` property to `ExistValidator` and `UniqueValidator` to support adding additional filtering conditions (qiangxue)
|
||||
- Enh #2008: `yii message/extract` is now able to save translation strings to database (kate-kate, samdark)
|
||||
- Enh #2043: Added support for custom request body parsers (danschmidt5189, cebe)
|
||||
|
||||
@@ -526,7 +526,6 @@ class Query extends Component implements QueryInterface
|
||||
{
|
||||
$this->where = $condition;
|
||||
$this->addParams($params);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -570,7 +569,65 @@ class Query extends Component implements QueryInterface
|
||||
$this->where = ['or', $this->where, $condition];
|
||||
}
|
||||
$this->addParams($params);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the WHERE part of the query ignoring empty parameters.
|
||||
*
|
||||
* @param string|array $condition the conditions that should be put in the WHERE part. Please refer to [[where()]]
|
||||
* on how to specify this parameter.
|
||||
* @param array $params the parameters (name => value) to be bound to the query.
|
||||
* @return static the query object itself
|
||||
* @see andFilter()
|
||||
* @see orFilter()
|
||||
*/
|
||||
public function filterWhere($condition, $params = [])
|
||||
{
|
||||
$condition = $this->filterCondition($condition);
|
||||
if ($condition !== []) {
|
||||
$this->where($condition, $params);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an additional WHERE condition to the existing one ignoring empty parameters.
|
||||
* The new condition and the existing one will be joined using the 'AND' operator.
|
||||
*
|
||||
* @param string|array $condition the new WHERE condition. Please refer to [[where()]]
|
||||
* on how to specify this parameter.
|
||||
* @param array $params the parameters (name => value) to be bound to the query.
|
||||
* @return static the query object itself
|
||||
* @see filter()
|
||||
* @see orFilter()
|
||||
*/
|
||||
public function andFilterWhere($condition, $params = [])
|
||||
{
|
||||
$condition = $this->filterCondition($condition);
|
||||
if ($condition !== []) {
|
||||
$this->andWhere($condition, $params);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an additional WHERE condition to the existing one ignoring empty parameters.
|
||||
* The new condition and the existing one will be joined using the 'OR' operator.
|
||||
*
|
||||
* @param string|array $condition the new WHERE condition. Please refer to [[where()]]
|
||||
* on how to specify this parameter.
|
||||
* @param array $params the parameters (name => value) to be bound to the query.
|
||||
* @return static the query object itself
|
||||
* @see filter()
|
||||
* @see andFilter()
|
||||
*/
|
||||
public function orFilterWhere($condition, $params = [])
|
||||
{
|
||||
$condition = $this->filterCondition($condition);
|
||||
if ($condition !== []) {
|
||||
$this->orWhere($condition, $params);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,6 +143,17 @@ interface QueryInterface
|
||||
*/
|
||||
public function where($condition);
|
||||
|
||||
/**
|
||||
* Sets the WHERE part of the query ignoring empty parameters.
|
||||
*
|
||||
* @param array $condition the conditions that should be put in the WHERE part. Please refer to [[where()]]
|
||||
* on how to specify this parameter.
|
||||
* @return static the query object itself
|
||||
* @see andFilterWhere()
|
||||
* @see orFilterWhere()
|
||||
*/
|
||||
public function filterWhere($condition);
|
||||
|
||||
/**
|
||||
* Adds an additional WHERE condition to the existing one.
|
||||
* The new condition and the existing one will be joined using the 'AND' operator.
|
||||
@@ -154,6 +165,17 @@ interface QueryInterface
|
||||
*/
|
||||
public function andWhere($condition);
|
||||
|
||||
/**
|
||||
* Adds an additional WHERE condition to the existing one ignoring empty parameters.
|
||||
* The new condition and the existing one will be joined using the 'AND' operator.
|
||||
* @param string|array $condition the new WHERE condition. Please refer to [[where()]]
|
||||
* on how to specify this parameter.
|
||||
* @return static the query object itself
|
||||
* @see filterWhere()
|
||||
* @see orFilterWhere()
|
||||
*/
|
||||
public function andFilterWhere($condition);
|
||||
|
||||
/**
|
||||
* Adds an additional WHERE condition to the existing one.
|
||||
* The new condition and the existing one will be joined using the 'OR' operator.
|
||||
@@ -165,6 +187,17 @@ interface QueryInterface
|
||||
*/
|
||||
public function orWhere($condition);
|
||||
|
||||
/**
|
||||
* Adds an additional WHERE condition to the existing one ignoring empty parameters.
|
||||
* The new condition and the existing one will be joined using the 'OR' operator.
|
||||
* @param string|array $condition the new WHERE condition. Please refer to [[where()]]
|
||||
* on how to specify this parameter.
|
||||
* @return static the query object itself
|
||||
* @see filterWhere()
|
||||
* @see andFilterWhere()
|
||||
*/
|
||||
public function orFilterWhere($condition);
|
||||
|
||||
/**
|
||||
* Sets the ORDER BY part of the query.
|
||||
* @param string|array $columns the columns (and the directions) to be ordered by.
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
namespace yii\db;
|
||||
|
||||
use yii\base\NotSupportedException;
|
||||
|
||||
/**
|
||||
* The BaseQuery trait represents the minimum method set of a database Query.
|
||||
*
|
||||
@@ -125,6 +127,149 @@ trait QueryTrait
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the WHERE part of the query but ignores [[isParameterNotEmpty|empty parameters]].
|
||||
*
|
||||
* This function can be used to pass fields of a search form directly as search condition
|
||||
* by ignoring fields that have not been filled.
|
||||
*
|
||||
* @param array $condition the conditions that should be put in the WHERE part.
|
||||
* See [[where()]] on how to specify this parameter.
|
||||
* @return static the query object itself
|
||||
* @see where()
|
||||
* @see andFilterWhere()
|
||||
* @see orFilterWhere()
|
||||
*/
|
||||
public function filterWhere($condition)
|
||||
{
|
||||
$condition = $this->filterCondition($condition);
|
||||
if ($condition !== []) {
|
||||
$this->where($condition);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an additional WHERE condition to the existing one but ignores [[isParameterNotEmpty|empty parameters]].
|
||||
* The new condition and the existing one will be joined using the 'AND' operator.
|
||||
* @param string|array $condition the new WHERE condition. Please refer to [[where()]]
|
||||
* on how to specify this parameter.
|
||||
* @return static the query object itself
|
||||
* @see filterWhere()
|
||||
* @see orFilterWhere()
|
||||
*/
|
||||
public function andFilterWhere($condition)
|
||||
{
|
||||
$condition = $this->filterCondition($condition);
|
||||
if ($condition !== []) {
|
||||
$this->andWhere($condition);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an additional WHERE condition to the existing one but ignores [[isParameterNotEmpty|empty parameters]].
|
||||
* The new condition and the existing one will be joined using the 'OR' operator.
|
||||
* @param string|array $condition the new WHERE condition. Please refer to [[where()]]
|
||||
* on how to specify this parameter.
|
||||
* @return static the query object itself
|
||||
* @see filterWhere()
|
||||
* @see andFilterWhere()
|
||||
*/
|
||||
public function orFilterWhere($condition)
|
||||
{
|
||||
$condition = $this->filterCondition($condition);
|
||||
if ($condition !== []) {
|
||||
$this->orWhere($condition);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new condition with [[isParameterNotEmpty|empty parameters]] removed.
|
||||
*
|
||||
* @param array $condition original condition
|
||||
* @return array condition with [[isParameterNotEmpty|empty parameters]] removed.
|
||||
* @throws NotSupportedException if the condition format is not supported
|
||||
*/
|
||||
protected function filterCondition($condition)
|
||||
{
|
||||
if (is_array($condition) && isset($condition[0])) {
|
||||
$operator = strtoupper($condition[0]);
|
||||
|
||||
switch ($operator) {
|
||||
case 'NOT':
|
||||
case 'AND':
|
||||
case 'OR':
|
||||
for ($i = 1, $operandsCount = count($condition); $i < $operandsCount; $i++) {
|
||||
$subCondition = $this->filterCondition($condition[$i]);
|
||||
if ($this->isParameterNotEmpty($subCondition)) {
|
||||
$condition[$i] = $subCondition;
|
||||
} else {
|
||||
unset($condition[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$operandsCount = count($condition) - 1;
|
||||
if ($operator === 'NOT' && $operandsCount === 0) {
|
||||
$condition = [];
|
||||
} else {
|
||||
// reindex array
|
||||
array_splice($condition, 0, 0);
|
||||
if ($operandsCount === 1) {
|
||||
$condition = $condition[1];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'IN':
|
||||
case 'NOT IN':
|
||||
case 'LIKE':
|
||||
case 'OR LIKE':
|
||||
case 'NOT LIKE':
|
||||
case 'OR NOT LIKE':
|
||||
if (!$this->isParameterNotEmpty($condition[2])) {
|
||||
$condition = [];
|
||||
}
|
||||
break;
|
||||
case 'BETWEEN':
|
||||
case 'NOT BETWEEN':
|
||||
if (!$this->isParameterNotEmpty($condition[2]) && !$this->isParameterNotEmpty($condition[3])) {
|
||||
$condition = [];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException("filterWhere() does not support the '$operator' operator.");
|
||||
}
|
||||
} elseif (is_array($condition)) {
|
||||
// hash format: 'column1' => 'value1', 'column2' => 'value2', ...
|
||||
return array_filter($condition, [$this, 'isParameterNotEmpty']);
|
||||
} else {
|
||||
throw new NotSupportedException("filterWhere() does not support plain string conditions use where() instead.");
|
||||
}
|
||||
return $condition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if value passed is not "empty".
|
||||
*
|
||||
* The value is considered "empty", if
|
||||
*
|
||||
* - it is `null`,
|
||||
* - an empty string (`''`),
|
||||
* - a string containing only whitespace characters,
|
||||
* - or an empty array.
|
||||
*
|
||||
* @param $value
|
||||
* @return boolean if parameter is empty
|
||||
*/
|
||||
protected function isParameterNotEmpty($value)
|
||||
{
|
||||
if (is_string($value)) {
|
||||
$value = trim($value);
|
||||
}
|
||||
return $value !== '' && $value !== [] && $value !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ORDER BY part of the query.
|
||||
* @param string|array $columns the columns (and the directions) to be ordered by.
|
||||
|
||||
Reference in New Issue
Block a user