diff --git a/framework/db/QueryTrait.php b/framework/db/QueryTrait.php index 40d17f11cc0..1c1167a619b 100644 --- a/framework/db/QueryTrait.php +++ b/framework/db/QueryTrait.php @@ -375,4 +375,35 @@ public function offset($offset) $this->offset = $offset; return $this; } + + /** + * Helper for easy querying on gridview filter input allowing the use some common operators + * + * The comparison operator is intelligently determined based on the first few characters in the given value. In particular, it recognizes the following operators if they appear as the leading characters in the given value: + * <: the column must be less than the given value. + * >: the column must be greater than the given value. + * <=: the column must be less than or equal to the given value. + * >=: the column must be greater than or equal to the given value. + * <>: the column must not be the same as the given value. Note that when $partialMatch is true, this would mean the value must not be a substring of the column. + * =: the column must be equal to the given value. + * none of the above: use the $defaultOperator + * + * Note that when the value is empty, no comparison expression will be added to the search condition. + * + * @param string $name column name + * @param scalar $value column value + * @param string $defaultOperator Defaults to =, performing an exact match. + * For example: use 'like' for partial matching + */ + public function compare($name, $value, $defaultOperator = '=') + { + $matches=[]; + if (preg_match("/^(<>|>=|>|<=|<|=)/", $value, $matches)) { + $op = $matches[1]; + $value = substr($value, strlen($op)); + } else { + $op = $defaultOperator; + } + $this->andFilterWhere([$op, $name, $value]); + } } diff --git a/tests/framework/db/QueryTest.php b/tests/framework/db/QueryTest.php index 3f1cf07535c..5f0a9f7cc7b 100644 --- a/tests/framework/db/QueryTest.php +++ b/tests/framework/db/QueryTest.php @@ -220,6 +220,36 @@ public function testCount() $this->assertEquals(2, $count); } + /** + * @depends testFilterWhere + */ + public function testCompare() + { + $query = new Query; + + $query->compare('name', null); + $this->assertNull($query->where); + + $query->compare('name', ''); + $this->assertNull($query->where); + + $query->compare('name', 'John Doe'); + $condition = ['=', 'name', 'John Doe']; + $this->assertEquals($condition, $query->where); + + $condition = ['and', $condition, ['like', 'name', 'Doe']]; + $query->compare('name', 'Doe', 'like'); + $this->assertEquals($condition, $query->where); + + $condition = ['and', $condition, ['>', 'rating', '9']]; + $query->compare('rating', '>9'); + $this->assertEquals($condition, $query->where); + + $condition = ['and', $condition, ['<=', 'value', '100']]; + $query->compare('value', '<=100'); + $this->assertEquals($condition, $query->where); + } + /** * @see https://github.com/yiisoft/yii2/issues/8068 *