Skip to content

Commit 0a82e9a

Browse files
author
Igor Chepurnoy
committed
added simple condition
1 parent 006530d commit 0a82e9a

File tree

3 files changed

+159
-15
lines changed

3 files changed

+159
-15
lines changed

.php_cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ $config = PhpCsFixer\Config::create()
1919
'concat_space' => ['spacing' => 'one'],
2020
'ordered_imports' => true,
2121
'array_syntax' => ['syntax' => 'short'],
22+
'yoda_style' => false,
2223
])
2324
->setFinder($finder);
2425

QueryProcessor.php

Lines changed: 99 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class QueryProcessor extends Component
4040
'NOT LIKE' => 'filterLikeCondition',
4141
'OR LIKE' => 'filterLikeCondition',
4242
'OR NOT LIKE' => 'filterLikeCondition',
43+
'CALLBACK' => 'filterCallbackCondition',
4344
];
4445

4546
/**
@@ -50,9 +51,9 @@ class QueryProcessor extends Component
5051
/**
5152
* @param ArrayQuery $query
5253
*
53-
* @return array
54+
* @return array[]
5455
*/
55-
public function process($query): array
56+
public function process($query)
5657
{
5758
$this->_query = $query;
5859

@@ -72,7 +73,7 @@ public function process($query): array
7273
*
7374
* @return array sorted data
7475
*/
75-
protected function applyOrderBy(array $data, $orderBy): array
76+
protected function applyOrderBy(array $data, $orderBy)
7677
{
7778
if (!empty($orderBy)) {
7879
ArrayHelper::multisort($data, array_keys($orderBy), array_values($orderBy));
@@ -90,7 +91,7 @@ protected function applyOrderBy(array $data, $orderBy): array
9091
*
9192
* @return array data
9293
*/
93-
protected function applyLimit(array $data, $limit, $offset): array
94+
protected function applyLimit(array $data, $limit, $offset)
9495
{
9596
if (empty($limit) && empty($offset)) {
9697
return $data;
@@ -115,7 +116,7 @@ protected function applyLimit(array $data, $limit, $offset): array
115116
*
116117
* @return array data
117118
*/
118-
protected function applyWhere(array $data, $where): array
119+
protected function applyWhere(array $data, $where)
119120
{
120121
return $this->filterCondition($data, $where);
121122
}
@@ -130,7 +131,7 @@ protected function applyWhere(array $data, $where): array
130131
*
131132
* @throws InvalidParamException
132133
*/
133-
protected function filterCondition(array $data, $condition): array
134+
public function filterCondition(array $data, $condition)
134135
{
135136
if (empty($condition)) {
136137
return $data;
@@ -145,12 +146,13 @@ protected function filterCondition(array $data, $condition): array
145146
if (isset($this->conditionFilters[$operator])) {
146147
$method = $this->conditionFilters[$operator];
147148
} else {
148-
throw new InvalidParamException("Invalid condition filter '{$operator}'");
149+
$method = 'filterSimpleCondition';
149150
}
151+
150152
array_shift($condition);
151153

152154
return $this->$method($data, $operator, $condition);
153-
} else {
155+
} else { // hash format: 'column1' => 'value1', 'column2' => 'value2', ...
154156
return $this->filterHashCondition($data, $condition);
155157
}
156158
}
@@ -163,13 +165,18 @@ protected function filterCondition(array $data, $condition): array
163165
*
164166
* @return array filtered data
165167
*/
166-
protected function filterHashCondition(array $data, $condition): array
168+
public function filterHashCondition(array $data, $condition)
167169
{
168170
foreach ($condition as $column => $value) {
169171
if (is_array($value)) {
172+
// IN condition
170173
$data = $this->filterInCondition($data, 'IN', [$column, $value]);
171174
} else {
172175
$data = array_filter($data, function ($row) use ($column, $value) {
176+
if ($value instanceof \Closure) {
177+
return call_user_func($value, $row[$column]);
178+
}
179+
173180
return $row[$column] == $value;
174181
});
175182
}
@@ -187,7 +194,7 @@ protected function filterHashCondition(array $data, $condition): array
187194
*
188195
* @return array filtered data
189196
*/
190-
protected function filterAndCondition(array $data, $operator, $operands): array
197+
protected function filterAndCondition(array $data, $operator, $operands)
191198
{
192199
foreach ($operands as $operand) {
193200
if (is_array($operand)) {
@@ -207,7 +214,7 @@ protected function filterAndCondition(array $data, $operator, $operands): array
207214
*
208215
* @return array filtered data
209216
*/
210-
protected function filterOrCondition(array $data, $operator, $operands): array
217+
protected function filterOrCondition(array $data, $operator, $operands)
211218
{
212219
$parts = [];
213220
foreach ($operands as $operand) {
@@ -242,7 +249,7 @@ protected function filterOrCondition(array $data, $operator, $operands): array
242249
*
243250
* @throws InvalidParamException if wrong number of operands have been given
244251
*/
245-
protected function filterNotCondition(array $data, $operator, $operands): array
252+
protected function filterNotCondition(array $data, $operator, $operands)
246253
{
247254
if (count($operands) != 1) {
248255
throw new InvalidParamException("Operator '$operator' requires exactly one operand.");
@@ -280,7 +287,7 @@ protected function filterNotCondition(array $data, $operator, $operands): array
280287
*
281288
* @throws InvalidParamException if wrong number of operands have been given
282289
*/
283-
protected function filterBetweenCondition(array $data, $operator, $operands): array
290+
protected function filterBetweenCondition(array $data, $operator, $operands)
284291
{
285292
if (!isset($operands[0], $operands[1], $operands[2])) {
286293
throw new InvalidParamException("Operator '$operator' requires three operands.");
@@ -311,7 +318,7 @@ protected function filterBetweenCondition(array $data, $operator, $operands): ar
311318
*
312319
* @throws InvalidParamException if wrong number of operands have been given
313320
*/
314-
protected function filterInCondition(array $data, $operator, $operands): array
321+
protected function filterInCondition(array $data, $operator, $operands)
315322
{
316323
if (!isset($operands[0], $operands[1])) {
317324
throw new InvalidParamException("Operator '$operator' requires two operands.");
@@ -362,7 +369,7 @@ protected function filterInCondition(array $data, $operator, $operands): array
362369
*
363370
* @throws InvalidParamException if wrong number of operands have been given
364371
*/
365-
protected function filterLikeCondition(array $data, $operator, $operands): array
372+
protected function filterLikeCondition(array $data, $operator, $operands)
366373
{
367374
if (!isset($operands[0], $operands[1])) {
368375
throw new InvalidParamException("Operator '$operator' requires two operands.");
@@ -431,4 +438,81 @@ protected function filterLikeCondition(array $data, $operator, $operands): array
431438
return true;
432439
});
433440
}
441+
442+
/**
443+
* Applies 'CALLBACK' condition.
444+
*
445+
* @param array $data data to be filtered
446+
* @param string $operator operator
447+
* @param array $operands the only one operand is the PHP callback, which should be compatible with
448+
* `array_filter()` PHP function, e.g.:
449+
*
450+
* ```php
451+
* function ($row) {
452+
* //return bool whether row matches condition or not
453+
* }
454+
* ```
455+
*
456+
* @return array filtered data
457+
*
458+
* @throws InvalidParamException if wrong number of operands have been given
459+
*
460+
* @since 1.0.3
461+
*/
462+
public function filterCallbackCondition(array $data, $operator, $operands)
463+
{
464+
if (count($operands) != 1) {
465+
throw new InvalidParamException("Operator '$operator' requires exactly one operand.");
466+
}
467+
468+
$callback = reset($operands);
469+
470+
return array_filter($data, $callback);
471+
}
472+
473+
/**
474+
* Applies comparison condition, e.g. `column operator value`.
475+
*
476+
* @param array $data data to be filtered
477+
* @param string $operator operator
478+
* @param array $operands
479+
*
480+
* @return array filtered data
481+
*
482+
* @throws InvalidParamException if wrong number of operands have been given or operator is not supported
483+
*
484+
* @since 1.0.4
485+
*/
486+
public function filterSimpleCondition(array $data, $operator, $operands)
487+
{
488+
if (count($operands) !== 2) {
489+
throw new InvalidParamException("Operator '$operator' requires two operands.");
490+
}
491+
list($column, $value) = $operands;
492+
493+
return array_filter($data, function ($row) use ($operator, $column, $value) {
494+
switch ($operator) {
495+
case '=':
496+
case '==':
497+
return $row[$column] == $value;
498+
case '===':
499+
return $row[$column] === $value;
500+
case '!=':
501+
case '<>':
502+
return $row[$column] != $value;
503+
case '!==':
504+
return $row[$column] !== $value;
505+
case '>':
506+
return $row[$column] > $value;
507+
case '<':
508+
return $row[$column] < $value;
509+
case '>=':
510+
return $row[$column] >= $value;
511+
case '<=':
512+
return $row[$column] <= $value;
513+
default:
514+
throw new InvalidParamException("Operator '$operator' is not supported.");
515+
}
516+
});
517+
}
434518
}

tests/ArrayQueryTest.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,63 @@ public function testSetCustomPrimaryKey()
245245
$this->assertCount(2, $rows);
246246
$this->assertEquals('username', $query->primaryKeyName);
247247
}
248+
249+
public function testGreaterThanCondition()
250+
{
251+
$query = $this->createArrayQuery();
252+
$query->where(['>', 'id', 1]);
253+
$rows = $query->all();
254+
255+
$this->assertCount(2, $rows);
256+
}
257+
258+
public function testLessThanCondition()
259+
{
260+
$query = $this->createArrayQuery();
261+
$query->where(['<', 'id', 2]);
262+
$rows = $query->all();
263+
264+
$this->assertCount(1, $rows);
265+
$this->assertEquals(1, $rows[0]['id']);
266+
}
267+
268+
public function testGreaterThanOrEqualToCondition()
269+
{
270+
$query = $this->createArrayQuery();
271+
$query->where(['>=', 'id', 2]);
272+
$rows = $query->all();
273+
274+
$this->assertCount(2, $rows);
275+
$this->assertEquals(3, $rows[1]['id']);
276+
}
277+
278+
public function testLessThanOrEqualToCondition()
279+
{
280+
$query = $this->createArrayQuery();
281+
$query->where(['<=', 'id', 2]);
282+
$rows = $query->all();
283+
284+
$this->assertCount(2, $rows);
285+
}
286+
287+
public function testEqualCondition()
288+
{
289+
$query = $this->createArrayQuery();
290+
$query->where(['=', 'id', 1]);
291+
$rows = $query->all();
292+
293+
$this->assertCount(1, $rows);
294+
$this->assertEquals(1, $rows[0]['id']);
295+
}
296+
297+
public function testNotEqualCondition()
298+
{
299+
$query = $this->createArrayQuery();
300+
$query->where(['!=', 'id', 1]);
301+
$rows = $query->all();
302+
303+
$this->assertCount(2, $rows);
304+
$this->assertEquals(2, $rows[0]['id']);
305+
$this->assertEquals(3, $rows[1]['id']);
306+
}
248307
}

0 commit comments

Comments
 (0)