Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
- Chg #211, #221: Change PHP constraint in `composer.json` to `8.1 - 8.4` (@vjik)
- New #223: Add `Sort::getDefaultOrder()` method (@vjik)
- Enh #223: `KeysetPaginator` now uses default order from `Sort` when no sort is set (@vjik)
- Chg #224: Change `$iterableFilterHandlers` to context object in `IterableFilterHandlerInterface::match()` (@vjik)
- New #224: Add filtering by nested values support in `IterableDataReader` (@vjik)

## 1.0.1 January 25, 2023

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class OwnIterableNotTwoFilterHandler implements IterableFilterHandlerInterface
return OwnNotTwoFilter::getOperator();
}

public function match(array $item, array $arguments, array $filterHandlers): bool
public function match(array $item, array $arguments, Context $context): bool
{
[$field] = $arguments;
return $item[$field] != 2;
Expand Down
39 changes: 39 additions & 0 deletions src/Reader/Iterable/Context.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Yiisoft\Data\Reader\Iterable;

use LogicException;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\ValueReader\ValueReaderInterface;

use function sprintf;

final class Context
{
public function __construct(
/**
* @psalm-var array<string, IterableFilterHandlerInterface>
*/
public readonly array $iterableFilterHandlers,
private readonly ValueReaderInterface $valueReader,
) {
}

/**
* @psalm-param class-string<FilterInterface> $class
*/
public function getFilterHandler(string $class): IterableFilterHandlerInterface
{
return $this->iterableFilterHandlers[$class]
?? throw new LogicException(
sprintf('Filter "%s" is not supported.', $class),
);
}

public function readValue(array|object $item, string $field): mixed
{
return $this->valueReader->read($item, $field);
}
}
15 changes: 4 additions & 11 deletions src/Reader/Iterable/FilterHandler/AllHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use LogicException;
use Yiisoft\Data\Reader\Filter\All;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

use function sprintf;

/**
* `All` iterable filter handler allows combining multiple sub-filters.
* The filter matches only if all the sub-filters match.
Expand All @@ -22,18 +20,13 @@ public function getFilterClass(): string
return All::class;
}

public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
public function match(object|array $item, FilterInterface $filter, Context $context): bool
{
/** @var All $filter */

foreach ($filter->getFilters() as $subFilter) {
$filterHandler = $iterableFilterHandlers[$subFilter::class] ?? null;
if ($filterHandler === null) {
throw new LogicException(
sprintf('Filter "%s" is not supported.', $subFilter::class),
);
}
if (!$filterHandler->match($item, $subFilter, $iterableFilterHandlers)) {
$filterHandler = $context->getFilterHandler($subFilter::class);
if (!$filterHandler->match($item, $subFilter, $context)) {
return false;
}
}
Expand Down
15 changes: 4 additions & 11 deletions src/Reader/Iterable/FilterHandler/AnyHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use LogicException;
use Yiisoft\Data\Reader\Filter\Any;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

use function sprintf;

/**
* `Any` iterable filter handler allows combining multiple sub-filters.
* The filter matches if any of the sub-filters match.
Expand All @@ -22,18 +20,13 @@ public function getFilterClass(): string
return Any::class;
}

public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
public function match(object|array $item, FilterInterface $filter, Context $context): bool
{
/** @var Any $filter */

foreach ($filter->getFilters() as $subFilter) {
$filterHandler = $iterableFilterHandlers[$subFilter::class] ?? null;
if ($filterHandler === null) {
throw new LogicException(
sprintf('Filter "%s" is not supported.', $subFilter::class),
);
}
if ($filterHandler->match($item, $subFilter, $iterableFilterHandlers)) {
$filterHandler = $context->getFilterHandler($subFilter::class);
if ($filterHandler->match($item, $subFilter, $context)) {
return true;
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/Reader/Iterable/FilterHandler/BetweenHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use DateTimeInterface;
use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\Between;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

/**
Expand All @@ -21,11 +21,11 @@ public function getFilterClass(): string
return Between::class;
}

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

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

Expand Down
6 changes: 3 additions & 3 deletions src/Reader/Iterable/FilterHandler/EqualsHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use DateTimeInterface;
use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\Equals;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

/**
Expand All @@ -20,11 +20,11 @@ public function getFilterClass(): string
return Equals::class;
}

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

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

if (!$itemValue instanceof DateTimeInterface) {
Expand Down
6 changes: 3 additions & 3 deletions src/Reader/Iterable/FilterHandler/EqualsNullHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\EqualsNull;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

/**
Expand All @@ -19,10 +19,10 @@ public function getFilterClass(): string
return EqualsNull::class;
}

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

return ArrayHelper::getValue($item, $filter->getField()) === null;
return $context->readValue($item, $filter->getField()) === null;
}
}
6 changes: 3 additions & 3 deletions src/Reader/Iterable/FilterHandler/GreaterThanHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use DateTimeInterface;
use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\GreaterThan;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

/**
Expand All @@ -20,11 +20,11 @@ public function getFilterClass(): string
return GreaterThan::class;
}

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

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

if (!$itemValue instanceof DateTimeInterface) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use DateTimeInterface;
use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\GreaterThanOrEqual;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

/**
Expand All @@ -21,11 +21,11 @@ public function getFilterClass(): string
return GreaterThanOrEqual::class;
}

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

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

if (!$itemValue instanceof DateTimeInterface) {
Expand Down
6 changes: 3 additions & 3 deletions src/Reader/Iterable/FilterHandler/InHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\In;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

use function in_array;
Expand All @@ -21,11 +21,11 @@ public function getFilterClass(): string
return In::class;
}

public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
public function match(object|array $item, FilterInterface $filter, Context $context): bool
{
/** @var In $filter */

$itemValue = ArrayHelper::getValue($item, $filter->getField());
$itemValue = $context->readValue($item, $filter->getField());
$argumentValue = $filter->getValues();

return in_array($itemValue, $argumentValue);
Expand Down
6 changes: 3 additions & 3 deletions src/Reader/Iterable/FilterHandler/LessThanHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use DateTimeInterface;
use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\LessThan;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

/**
Expand All @@ -20,11 +20,11 @@ public function getFilterClass(): string
return LessThan::class;
}

public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
public function match(object|array $item, FilterInterface $filter, Context $context): bool
{
/** @var LessThan $filter */

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

if (!$itemValue instanceof DateTimeInterface) {
Expand Down
6 changes: 3 additions & 3 deletions src/Reader/Iterable/FilterHandler/LessThanOrEqualHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use DateTimeInterface;
use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\LessThanOrEqual;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

/**
Expand All @@ -21,11 +21,11 @@ public function getFilterClass(): string
return LessThanOrEqual::class;
}

public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
public function match(object|array $item, FilterInterface $filter, Context $context): bool
{
/** @var LessThanOrEqual $filter */

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

if (!$itemValue instanceof DateTimeInterface) {
Expand Down
6 changes: 3 additions & 3 deletions src/Reader/Iterable/FilterHandler/LikeHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use Yiisoft\Arrays\ArrayHelper;
use Yiisoft\Data\Reader\Filter\Like;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

use function is_string;
Expand All @@ -21,11 +21,11 @@ public function getFilterClass(): string
return Like::class;
}

public function match(object|array $item, FilterInterface $filter, array $iterableFilterHandlers): bool
public function match(object|array $item, FilterInterface $filter, Context $context): bool
{
/** @var Like $filter */

$itemValue = ArrayHelper::getValue($item, $filter->getField());
$itemValue = $context->readValue($item, $filter->getField());
if (!is_string($itemValue)) {
return false;
}
Expand Down
13 changes: 4 additions & 9 deletions src/Reader/Iterable/FilterHandler/NotHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

namespace Yiisoft\Data\Reader\Iterable\FilterHandler;

use LogicException;
use Yiisoft\Data\Reader\Filter\Not;
use Yiisoft\Data\Reader\FilterInterface;
use Yiisoft\Data\Reader\Iterable\Context;
use Yiisoft\Data\Reader\Iterable\IterableFilterHandlerInterface;

use function sprintf;

/**
* `Not` iterable filter handler negates another filter.
*/
Expand All @@ -21,16 +19,13 @@ public function getFilterClass(): string
return Not::class;
}

public function match(array|object $item, FilterInterface $filter, array $iterableFilterHandlers): bool
public function match(object|array $item, FilterInterface $filter, Context $context): bool
{
/** @var Not $filter */

$subFilter = $filter->getFilter();

$filterHandler = $iterableFilterHandlers[$subFilter::class] ?? null;
if ($filterHandler === null) {
throw new LogicException(sprintf('Filter "%s" is not supported.', $subFilter::class));
}
return !$filterHandler->match($item, $subFilter, $iterableFilterHandlers);
$filterHandler = $context->getFilterHandler($subFilter::class);
return !$filterHandler->match($item, $subFilter, $context);
}
}
Loading
Loading