Skip to content

Commit 17ec31e

Browse files
vjikTigrov
andauthored
Add value reader to IterableDataReader (#224)
Co-authored-by: Sergei Tigrov <rrr-r@ya.ru>
1 parent a737b94 commit 17ec31e

35 files changed

+270
-108
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
- Chg #211, #221: Change PHP constraint in `composer.json` to `8.1 - 8.4` (@vjik)
5454
- New #223: Add `Sort::getDefaultOrder()` method (@vjik)
5555
- Enh #223: `KeysetPaginator` now uses default order from `Sort` when no sort is set (@vjik)
56+
- Chg #224: Change `$iterableFilterHandlers` to context object in `IterableFilterHandlerInterface::match()` (@vjik)
57+
- New #224: Add filtering by nested values support in `IterableDataReader` (@vjik)
5658

5759
## 1.0.1 January 25, 2023
5860

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class OwnIterableNotTwoFilterHandler implements IterableFilterHandlerInterface
189189
return OwnNotTwoFilter::getOperator();
190190
}
191191

192-
public function match(array $item, array $arguments, array $filterHandlers): bool
192+
public function match(array $item, array $arguments, Context $context): bool
193193
{
194194
[$field] = $arguments;
195195
return $item[$field] != 2;

src/Reader/Iterable/Context.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Data\Reader\Iterable;
6+
7+
use LogicException;
8+
use Yiisoft\Data\Reader\FilterInterface;
9+
use Yiisoft\Data\Reader\Iterable\ValueReader\ValueReaderInterface;
10+
11+
use function sprintf;
12+
13+
final class Context
14+
{
15+
public function __construct(
16+
/**
17+
* @psalm-var array<string, IterableFilterHandlerInterface>
18+
*/
19+
public readonly array $iterableFilterHandlers,
20+
private readonly ValueReaderInterface $valueReader,
21+
) {
22+
}
23+
24+
/**
25+
* @psalm-param class-string<FilterInterface> $class
26+
*/
27+
public function getFilterHandler(string $class): IterableFilterHandlerInterface
28+
{
29+
return $this->iterableFilterHandlers[$class]
30+
?? throw new LogicException(
31+
sprintf('Filter "%s" is not supported.', $class),
32+
);
33+
}
34+
35+
public function readValue(array|object $item, string $field): mixed
36+
{
37+
return $this->valueReader->read($item, $field);
38+
}
39+
}

src/Reader/Iterable/FilterHandler/AllHandler.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44

55
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;
66

7-
use LogicException;
87
use Yiisoft\Data\Reader\Filter\All;
98
use Yiisoft\Data\Reader\FilterInterface;
9+
use Yiisoft\Data\Reader\Iterable\Context;
1010
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;
1111

12-
use function sprintf;
13-
1412
/**
1513
* `All` iterable filter handler allows combining multiple sub-filters.
1614
* The filter matches only if all the sub-filters match.
@@ -22,18 +20,13 @@ public function getFilterClass(): string
2220
return All::class;
2321
}
2422

25-
public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
23+
public function match(object|array $item, FilterInterface $filter, Context $context): bool
2624
{
2725
/** @var All $filter */
2826

2927
foreach ($filter->getFilters() as $subFilter) {
30-
$filterHandler = $iterableFilterHandlers[$subFilter::class] ?? null;
31-
if ($filterHandler === null) {
32-
throw new LogicException(
33-
sprintf('Filter "%s" is not supported.', $subFilter::class),
34-
);
35-
}
36-
if (!$filterHandler->match($item, $subFilter, $iterableFilterHandlers)) {
28+
$filterHandler = $context->getFilterHandler($subFilter::class);
29+
if (!$filterHandler->match($item, $subFilter, $context)) {
3730
return false;
3831
}
3932
}

src/Reader/Iterable/FilterHandler/AnyHandler.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44

55
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;
66

7-
use LogicException;
87
use Yiisoft\Data\Reader\Filter\Any;
98
use Yiisoft\Data\Reader\FilterInterface;
9+
use Yiisoft\Data\Reader\Iterable\Context;
1010
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;
1111

12-
use function sprintf;
13-
1412
/**
1513
* `Any` iterable filter handler allows combining multiple sub-filters.
1614
* The filter matches if any of the sub-filters match.
@@ -22,18 +20,13 @@ public function getFilterClass(): string
2220
return Any::class;
2321
}
2422

25-
public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
23+
public function match(object|array $item, FilterInterface $filter, Context $context): bool
2624
{
2725
/** @var Any $filter */
2826

2927
foreach ($filter->getFilters() as $subFilter) {
30-
$filterHandler = $iterableFilterHandlers[$subFilter::class] ?? null;
31-
if ($filterHandler === null) {
32-
throw new LogicException(
33-
sprintf('Filter "%s" is not supported.', $subFilter::class),
34-
);
35-
}
36-
if ($filterHandler->match($item, $subFilter, $iterableFilterHandlers)) {
28+
$filterHandler = $context->getFilterHandler($subFilter::class);
29+
if ($filterHandler->match($item, $subFilter, $context)) {
3730
return true;
3831
}
3932
}

src/Reader/Iterable/FilterHandler/BetweenHandler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;
66

77
use DateTimeInterface;
8-
use Yiisoft\Arrays\ArrayHelper;
98
use Yiisoft\Data\Reader\Filter\Between;
109
use Yiisoft\Data\Reader\FilterInterface;
10+
use Yiisoft\Data\Reader\Iterable\Context;
1111
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;
1212

1313
/**
@@ -21,11 +21,11 @@ public function getFilterClass(): string
2121
return Between::class;
2222
}
2323

24-
public function match(array|object $item, FilterInterface $filter, array $iterableFilterHandlers): bool
24+
public function match(object|array $item, FilterInterface $filter, Context $context): bool
2525
{
2626
/** @var Between $filter */
2727

28-
$value = ArrayHelper::getValue($item, $filter->getField());
28+
$value = $context->readValue($item, $filter->getField());
2929
$min = $filter->getMinValue();
3030
$max = $filter->getMaxValue();
3131

src/Reader/Iterable/FilterHandler/EqualsHandler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;
66

77
use DateTimeInterface;
8-
use Yiisoft\Arrays\ArrayHelper;
98
use Yiisoft\Data\Reader\Filter\Equals;
109
use Yiisoft\Data\Reader\FilterInterface;
10+
use Yiisoft\Data\Reader\Iterable\Context;
1111
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;
1212

1313
/**
@@ -20,11 +20,11 @@ public function getFilterClass(): string
2020
return Equals::class;
2121
}
2222

23-
public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
23+
public function match(object|array $item, FilterInterface $filter, Context $context): bool
2424
{
2525
/** @var Equals $filter */
2626

27-
$itemValue = ArrayHelper::getValue($item, $filter->getField());
27+
$itemValue = $context->readValue($item, $filter->getField());
2828
$argumentValue = $filter->getValue();
2929

3030
if (!$itemValue instanceof DateTimeInterface) {

src/Reader/Iterable/FilterHandler/EqualsNullHandler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;
66

7-
use Yiisoft\Arrays\ArrayHelper;
87
use Yiisoft\Data\Reader\Filter\EqualsNull;
98
use Yiisoft\Data\Reader\FilterInterface;
9+
use Yiisoft\Data\Reader\Iterable\Context;
1010
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;
1111

1212
/**
@@ -19,10 +19,10 @@ public function getFilterClass(): string
1919
return EqualsNull::class;
2020
}
2121

22-
public function match(array|object $item, FilterInterface $filter, array $iterableFilterHandlers): bool
22+
public function match(object|array $item, FilterInterface $filter, Context $context): bool
2323
{
2424
/** @var EqualsNull $filter */
2525

26-
return ArrayHelper::getValue($item, $filter->getField()) === null;
26+
return $context->readValue($item, $filter->getField()) === null;
2727
}
2828
}

src/Reader/Iterable/FilterHandler/GreaterThanHandler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;
66

77
use DateTimeInterface;
8-
use Yiisoft\Arrays\ArrayHelper;
98
use Yiisoft\Data\Reader\Filter\GreaterThan;
109
use Yiisoft\Data\Reader\FilterInterface;
10+
use Yiisoft\Data\Reader\Iterable\Context;
1111
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;
1212

1313
/**
@@ -20,11 +20,11 @@ public function getFilterClass(): string
2020
return GreaterThan::class;
2121
}
2222

23-
public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
23+
public function match(object|array $item, FilterInterface $filter, Context $context): bool
2424
{
2525
/** @var GreaterThan $filter */
2626

27-
$itemValue = ArrayHelper::getValue($item, $filter->getField());
27+
$itemValue = $context->readValue($item, $filter->getField());
2828
$argumentValue = $filter->getValue();
2929

3030
if (!$itemValue instanceof DateTimeInterface) {

src/Reader/Iterable/FilterHandler/GreaterThanOrEqualHandler.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;
66

77
use DateTimeInterface;
8-
use Yiisoft\Arrays\ArrayHelper;
98
use Yiisoft\Data\Reader\Filter\GreaterThanOrEqual;
109
use Yiisoft\Data\Reader\FilterInterface;
10+
use Yiisoft\Data\Reader\Iterable\Context;
1111
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;
1212

1313
/**
@@ -21,11 +21,11 @@ public function getFilterClass(): string
2121
return GreaterThanOrEqual::class;
2222
}
2323

24-
public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
24+
public function match(object|array $item, FilterInterface $filter, Context $context): bool
2525
{
2626
/** @var GreaterThanOrEqual $filter */
2727

28-
$itemValue = ArrayHelper::getValue($item, $filter->getField());
28+
$itemValue = $context->readValue($item, $filter->getField());
2929
$argumentValue = $filter->getValue();
3030

3131
if (!$itemValue instanceof DateTimeInterface) {

0 commit comments

Comments
 (0)