diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 51732a4..2db16ec 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -283,6 +283,9 @@ Yii Framework 2 Change Log - Enh #9263: Avoid extra DB query in RBAC DbManager in case auth item name is empty (samdark) - Enh #9268: Improved display of boolean parameters in logged SQL queries (arkhamvm, samdark) - Enh: Improved Console helper progress bar ETA time estimation, updated only once per second to avoid flapping (cebe) +- Enh #8444: Added `yii\widgets\LinkPager::$linkOptions` to allow configuring HTML attributes of the `a` tags (zinzinday) +- Enh #8486: Added support to automatically set the `maxlength` attribute for `Html::activeTextArea()` and `Html::activePassword()` (klimov-paul) +- Enh #8505: `yii\db\Query` now contains a andFilterCompare() method that allows filtering using operators in the query value (lennartvdd) - Chg #6354: `ErrorHandler::logException()` will now log the whole exception object instead of only its string representation (cebe) - Chg #8556: Extracted `yii\web\User::getAuthManager()` method (samdark) - Chg #9181: `yii\helpers\BaseStringHelper::truncateHtml()` is now using `runtime` directory for `HTMLPurifier` cache (webdevsega) diff --git a/framework/db/Query.php b/framework/db/Query.php index b6b379e..d6e736a 100644 --- a/framework/db/Query.php +++ b/framework/db/Query.php @@ -582,6 +582,43 @@ class Query extends Component implements QueryInterface } /** + * Adds a filtering condition for a specific column and allow the user to choose a filter operator. + * + * It adds an additional WHERE condition for the given field and determines the comparison operator + * based on the first few characters of the given value. + * The condition is added in the same way as in [[andFilterWhere]] so [[isEmpty()|empty values]] are ignored. + * The new condition and the existing one will be joined using the 'AND' operator. + * + * 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. + * - `=`: the column must be equal to the given value. + * - If none of the above operators is detected, the `$defaultOperator` will be used. + * + * @param string $name the column name. + * @param string $value the column value optionally prepended with the comparison operator. + * @param string $defaultOperator The operator to use, when no operator is given in `$value`. + * Defaults to `=`, performing an exact match. + * @return $this The query object itself + * @since 2.0.8 + */ + public function andFilterCompare($name, $value, $defaultOperator = '=') + { + if (preg_match("/^(<>|>=|>|<=|<|=)/", $value, $matches)) { + $operator = $matches[1]; + $value = substr($value, strlen($operator)); + } else { + $operator = $defaultOperator; + } + return $this->andFilterWhere([$operator, $name, $value]); + } + + /** * Appends a JOIN part to the query. * The first parameter specifies what type of join it is. * @param string $type the type of join, such as INNER JOIN, LEFT JOIN. diff --git a/tests/framework/db/QueryTest.php b/tests/framework/db/QueryTest.php index a9548f3..c183d3b 100644 --- a/tests/framework/db/QueryTest.php +++ b/tests/framework/db/QueryTest.php @@ -244,6 +244,37 @@ class QueryTest extends DatabaseTestCase } /** + * @depends testFilterWhere + */ + public function testAndFilterCompare() + { + $query = new Query; + + $result = $query->andFilterCompare('name', null); + $this->assertInstanceOf('yii\db\Query', $result); + $this->assertNull($query->where); + + $query->andFilterCompare('name', ''); + $this->assertNull($query->where); + + $query->andFilterCompare('name', 'John Doe'); + $condition = ['=', 'name', 'John Doe']; + $this->assertEquals($condition, $query->where); + + $condition = ['and', $condition, ['like', 'name', 'Doe']]; + $query->andFilterCompare('name', 'Doe', 'like'); + $this->assertEquals($condition, $query->where); + + $condition = ['and', $condition, ['>', 'rating', '9']]; + $query->andFilterCompare('rating', '>9'); + $this->assertEquals($condition, $query->where); + + $condition = ['and', $condition, ['<=', 'value', '100']]; + $query->andFilterCompare('value', '<=100'); + $this->assertEquals($condition, $query->where); + } + + /** * @see https://github.com/yiisoft/yii2/issues/8068 * * @depends testCount