From 2fe765664ba505dead3dc1515f93c1941d993cb3 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sun, 27 Jul 2025 22:16:49 +0300 Subject: [PATCH 1/4] refactor filters --- src/Reader/Filter/Between.php | 21 +++------------------ src/Reader/Filter/Compare.php | 18 +++--------------- src/Reader/Filter/EqualsNull.php | 7 +------ src/Reader/Filter/In.php | 30 ++++++++---------------------- src/Reader/Filter/Like.php | 21 +++------------------ src/Reader/Filter/Not.php | 7 +------ 6 files changed, 19 insertions(+), 85 deletions(-) diff --git a/src/Reader/Filter/Between.php b/src/Reader/Filter/Between.php index 79fa2aac..dad52c3e 100644 --- a/src/Reader/Filter/Between.php +++ b/src/Reader/Filter/Between.php @@ -19,24 +19,9 @@ final class Between implements FilterInterface * @param bool|DateTimeInterface|float|int|string $maxValue Maximal field value. */ public function __construct( - private readonly string $field, - private readonly bool|DateTimeInterface|float|int|string $minValue, - private readonly bool|DateTimeInterface|float|int|string $maxValue + public readonly string $field, + public readonly bool|DateTimeInterface|float|int|string $minValue, + public readonly bool|DateTimeInterface|float|int|string $maxValue ) { } - - public function getField(): string - { - return $this->field; - } - - public function getMinValue(): float|DateTimeInterface|bool|int|string - { - return $this->minValue; - } - - public function getMaxValue(): float|DateTimeInterface|bool|int|string - { - return $this->maxValue; - } } diff --git a/src/Reader/Filter/Compare.php b/src/Reader/Filter/Compare.php index 546da999..b71542df 100644 --- a/src/Reader/Filter/Compare.php +++ b/src/Reader/Filter/Compare.php @@ -17,28 +17,16 @@ abstract class Compare implements FilterInterface * @param bool|DateTimeInterface|float|int|string $value Value to compare to. */ public function __construct( - private readonly string $field, - private bool|DateTimeInterface|float|int|string $value, + public readonly string $field, + public readonly bool|DateTimeInterface|float|int|string $value, ) { } - public function getField(): string - { - return $this->field; - } - - public function getValue(): float|DateTimeInterface|bool|int|string - { - return $this->value; - } - /** * @param bool|DateTimeInterface|float|int|string $value Value to compare to. */ final public function withValue(bool|DateTimeInterface|float|int|string $value): static { - $new = clone $this; - $new->value = $value; - return $new; + return new static($this->field, $value); } } diff --git a/src/Reader/Filter/EqualsNull.php b/src/Reader/Filter/EqualsNull.php index 9a48c4c1..0b50edba 100644 --- a/src/Reader/Filter/EqualsNull.php +++ b/src/Reader/Filter/EqualsNull.php @@ -15,12 +15,7 @@ final class EqualsNull implements FilterInterface * @param string $field Name of the field to check. */ public function __construct( - private readonly string $field, + public readonly string $field, ) { } - - public function getField(): string - { - return $this->field; - } } diff --git a/src/Reader/Filter/In.php b/src/Reader/Filter/In.php index 76c0d430..fb818ae7 100644 --- a/src/Reader/Filter/In.php +++ b/src/Reader/Filter/In.php @@ -15,21 +15,21 @@ */ final class In implements FilterInterface { - /** - * @var bool[]|float[]|int[]|string[] Values to check against. - */ - private array $values; - /** * @param string $field Name of the field to compare. * @param bool[]|float[]|int[]|string[] $values Values to check against. */ public function __construct( - private readonly string $field, - array $values + public readonly string $field, + /** @var bool[]|float[]|int[]|string[] Values to check against. */ + public readonly array $values ) { + $this->assertValues($values); + } + + private function assertValues(array $values): void + { foreach ($values as $value) { - /** @psalm-suppress DocblockTypeContradiction */ if (!is_scalar($value)) { throw new InvalidArgumentException( sprintf( @@ -39,19 +39,5 @@ public function __construct( ); } } - $this->values = $values; - } - - public function getField(): string - { - return $this->field; - } - - /** - * @return bool[]|float[]|int[]|string[] - */ - public function getValues(): array - { - return $this->values; } } diff --git a/src/Reader/Filter/Like.php b/src/Reader/Filter/Like.php index 762dc17d..8180bea4 100644 --- a/src/Reader/Filter/Like.php +++ b/src/Reader/Filter/Like.php @@ -21,24 +21,9 @@ final class Like implements FilterInterface * - `false` - case-insensitive. */ public function __construct( - private readonly string $field, - private readonly string $value, - private readonly ?bool $caseSensitive = null, + public readonly string $field, + public readonly string $value, + public readonly ?bool $caseSensitive = null, ) { } - - public function getField(): string - { - return $this->field; - } - - public function getValue(): string - { - return $this->value; - } - - public function getCaseSensitive(): ?bool - { - return $this->caseSensitive; - } } diff --git a/src/Reader/Filter/Not.php b/src/Reader/Filter/Not.php index a7de17b1..a31c8e20 100644 --- a/src/Reader/Filter/Not.php +++ b/src/Reader/Filter/Not.php @@ -15,12 +15,7 @@ final class Not implements FilterInterface * @param FilterInterface $filter Filter to negate. */ public function __construct( - private readonly FilterInterface $filter, + public readonly FilterInterface $filter, ) { } - - public function getFilter(): FilterInterface - { - return $this->filter; - } } From 7bfedb1ae31b24422dce47248a6d687da601be32 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sun, 27 Jul 2025 22:31:57 +0300 Subject: [PATCH 2/4] fix psalm --- src/Reader/Filter/Compare.php | 2 +- src/Reader/Iterable/FilterHandler/BetweenHandler.php | 6 +++--- src/Reader/Iterable/FilterHandler/EqualsHandler.php | 4 ++-- src/Reader/Iterable/FilterHandler/EqualsNullHandler.php | 2 +- src/Reader/Iterable/FilterHandler/GreaterThanHandler.php | 4 ++-- .../Iterable/FilterHandler/GreaterThanOrEqualHandler.php | 4 ++-- src/Reader/Iterable/FilterHandler/InHandler.php | 4 ++-- src/Reader/Iterable/FilterHandler/LessThanHandler.php | 4 ++-- .../Iterable/FilterHandler/LessThanOrEqualHandler.php | 4 ++-- src/Reader/Iterable/FilterHandler/LikeHandler.php | 8 ++++---- src/Reader/Iterable/FilterHandler/NotHandler.php | 2 +- 11 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Reader/Filter/Compare.php b/src/Reader/Filter/Compare.php index b71542df..87d85511 100644 --- a/src/Reader/Filter/Compare.php +++ b/src/Reader/Filter/Compare.php @@ -16,7 +16,7 @@ abstract class Compare implements FilterInterface * @param string $field Name of the field to compare. * @param bool|DateTimeInterface|float|int|string $value Value to compare to. */ - public function __construct( + final public function __construct( public readonly string $field, public readonly bool|DateTimeInterface|float|int|string $value, ) { diff --git a/src/Reader/Iterable/FilterHandler/BetweenHandler.php b/src/Reader/Iterable/FilterHandler/BetweenHandler.php index 8f572714..ec4721e5 100644 --- a/src/Reader/Iterable/FilterHandler/BetweenHandler.php +++ b/src/Reader/Iterable/FilterHandler/BetweenHandler.php @@ -25,9 +25,9 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var Between $filter */ - $value = $context->readValue($item, $filter->getField()); - $min = $filter->getMinValue(); - $max = $filter->getMaxValue(); + $value = $context->readValue($item, $filter->field); + $min = $filter->minValue; + $max = $filter->maxValue; if (!$value instanceof DateTimeInterface) { return $value >= $min && $value <= $max; diff --git a/src/Reader/Iterable/FilterHandler/EqualsHandler.php b/src/Reader/Iterable/FilterHandler/EqualsHandler.php index efe68968..bc6539c3 100644 --- a/src/Reader/Iterable/FilterHandler/EqualsHandler.php +++ b/src/Reader/Iterable/FilterHandler/EqualsHandler.php @@ -24,8 +24,8 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var Equals $filter */ - $itemValue = $context->readValue($item, $filter->getField()); - $argumentValue = $filter->getValue(); + $itemValue = $context->readValue($item, $filter->field); + $argumentValue = $filter->value; if (!$itemValue instanceof DateTimeInterface) { return $itemValue == $argumentValue; diff --git a/src/Reader/Iterable/FilterHandler/EqualsNullHandler.php b/src/Reader/Iterable/FilterHandler/EqualsNullHandler.php index 90c84572..6eae9ad0 100644 --- a/src/Reader/Iterable/FilterHandler/EqualsNullHandler.php +++ b/src/Reader/Iterable/FilterHandler/EqualsNullHandler.php @@ -23,6 +23,6 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var EqualsNull $filter */ - return $context->readValue($item, $filter->getField()) === null; + return $context->readValue($item, $filter->field) === null; } } diff --git a/src/Reader/Iterable/FilterHandler/GreaterThanHandler.php b/src/Reader/Iterable/FilterHandler/GreaterThanHandler.php index cc185b5b..8032f4fc 100644 --- a/src/Reader/Iterable/FilterHandler/GreaterThanHandler.php +++ b/src/Reader/Iterable/FilterHandler/GreaterThanHandler.php @@ -24,8 +24,8 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var GreaterThan $filter */ - $itemValue = $context->readValue($item, $filter->getField()); - $argumentValue = $filter->getValue(); + $itemValue = $context->readValue($item, $filter->field); + $argumentValue = $filter->value; if (!$itemValue instanceof DateTimeInterface) { return $itemValue > $argumentValue; diff --git a/src/Reader/Iterable/FilterHandler/GreaterThanOrEqualHandler.php b/src/Reader/Iterable/FilterHandler/GreaterThanOrEqualHandler.php index c39ac511..8065cce2 100644 --- a/src/Reader/Iterable/FilterHandler/GreaterThanOrEqualHandler.php +++ b/src/Reader/Iterable/FilterHandler/GreaterThanOrEqualHandler.php @@ -25,8 +25,8 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var GreaterThanOrEqual $filter */ - $itemValue = $context->readValue($item, $filter->getField()); - $argumentValue = $filter->getValue(); + $itemValue = $context->readValue($item, $filter->field); + $argumentValue = $filter->value; if (!$itemValue instanceof DateTimeInterface) { return $itemValue >= $argumentValue; diff --git a/src/Reader/Iterable/FilterHandler/InHandler.php b/src/Reader/Iterable/FilterHandler/InHandler.php index 4d4a67fe..fe12f17b 100644 --- a/src/Reader/Iterable/FilterHandler/InHandler.php +++ b/src/Reader/Iterable/FilterHandler/InHandler.php @@ -25,8 +25,8 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var In $filter */ - $itemValue = $context->readValue($item, $filter->getField()); - $argumentValue = $filter->getValues(); + $itemValue = $context->readValue($item, $filter->field); + $argumentValue = $filter->values; return in_array($itemValue, $argumentValue); } diff --git a/src/Reader/Iterable/FilterHandler/LessThanHandler.php b/src/Reader/Iterable/FilterHandler/LessThanHandler.php index 011a2d2f..4ef0f34c 100644 --- a/src/Reader/Iterable/FilterHandler/LessThanHandler.php +++ b/src/Reader/Iterable/FilterHandler/LessThanHandler.php @@ -24,8 +24,8 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var LessThan $filter */ - $itemValue = $context->readValue($item, $filter->getField()); - $argumentValue = $filter->getValue(); + $itemValue = $context->readValue($item, $filter->field); + $argumentValue = $filter->value; if (!$itemValue instanceof DateTimeInterface) { return $itemValue < $argumentValue; diff --git a/src/Reader/Iterable/FilterHandler/LessThanOrEqualHandler.php b/src/Reader/Iterable/FilterHandler/LessThanOrEqualHandler.php index 5ddd9f62..f6c01200 100644 --- a/src/Reader/Iterable/FilterHandler/LessThanOrEqualHandler.php +++ b/src/Reader/Iterable/FilterHandler/LessThanOrEqualHandler.php @@ -25,8 +25,8 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var LessThanOrEqual $filter */ - $itemValue = $context->readValue($item, $filter->getField()); - $argumentValue = $filter->getValue(); + $itemValue = $context->readValue($item, $filter->field); + $argumentValue = $filter->value; if (!$itemValue instanceof DateTimeInterface) { return $itemValue <= $argumentValue; diff --git a/src/Reader/Iterable/FilterHandler/LikeHandler.php b/src/Reader/Iterable/FilterHandler/LikeHandler.php index d0f0d024..46168638 100644 --- a/src/Reader/Iterable/FilterHandler/LikeHandler.php +++ b/src/Reader/Iterable/FilterHandler/LikeHandler.php @@ -25,13 +25,13 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var Like $filter */ - $itemValue = $context->readValue($item, $filter->getField()); + $itemValue = $context->readValue($item, $filter->field); if (!is_string($itemValue)) { return false; } - return $filter->getCaseSensitive() === true - ? str_contains($itemValue, $filter->getValue()) - : mb_stripos($itemValue, $filter->getValue()) !== false; + return $filter->caseSensitive === true + ? str_contains($itemValue, $filter->value) + : mb_stripos($itemValue, $filter->value) !== false; } } diff --git a/src/Reader/Iterable/FilterHandler/NotHandler.php b/src/Reader/Iterable/FilterHandler/NotHandler.php index a65b7f74..abfebab3 100644 --- a/src/Reader/Iterable/FilterHandler/NotHandler.php +++ b/src/Reader/Iterable/FilterHandler/NotHandler.php @@ -23,7 +23,7 @@ public function match(object|array $item, FilterInterface $filter, Context $cont { /** @var Not $filter */ - $subFilter = $filter->getFilter(); + $subFilter = $filter->filter; $filterHandler = $context->getFilterHandler($subFilter::class); return !$filterHandler->match($item, $subFilter, $context); From 380e77e14b1fa67de65477e6681a4363449b5ea0 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sun, 27 Jul 2025 22:40:31 +0300 Subject: [PATCH 3/4] fix tests --- tests/Reader/Filter/CompareTest.php | 14 ++++++--- tests/Reader/Filter/LikeTest.php | 29 ------------------- .../Iterable/IterableDataReaderTest.php | 2 +- 3 files changed, 11 insertions(+), 34 deletions(-) delete mode 100644 tests/Reader/Filter/LikeTest.php diff --git a/tests/Reader/Filter/CompareTest.php b/tests/Reader/Filter/CompareTest.php index ac5915a5..385f0ebb 100644 --- a/tests/Reader/Filter/CompareTest.php +++ b/tests/Reader/Filter/CompareTest.php @@ -7,13 +7,19 @@ use PHPUnit\Framework\TestCase; use Yiisoft\Data\Reader\Filter\LessThan; +use function PHPUnit\Framework\assertNotSame; +use function PHPUnit\Framework\assertSame; + final class CompareTest extends TestCase { - public function testWithValue() + public function testWithValue(): void { - $filter = new LessThan('field', 1); + $sourceFilter = new LessThan('field', 1); + + $filter = $sourceFilter->withValue(2); - $this->assertNotSame($filter, $filter->withValue(1)); - $this->assertSame(2, $filter->withValue(2)->getValue()); + assertNotSame($sourceFilter, $filter); + assertSame('field', $filter->field); + assertSame(2, $filter->value); } } diff --git a/tests/Reader/Filter/LikeTest.php b/tests/Reader/Filter/LikeTest.php deleted file mode 100644 index 5afbcb99..00000000 --- a/tests/Reader/Filter/LikeTest.php +++ /dev/null @@ -1,29 +0,0 @@ -assertSame('name', $like->getField()); - $this->assertSame('Kesha', $like->getValue()); - $this->assertNull($like->getCaseSensitive()); - } - - public function testWithCaseSensitive(): void - { - $like = new Like('name', 'Kesha', true); - - $this->assertSame('name', $like->getField()); - $this->assertSame('Kesha', $like->getValue()); - $this->assertTrue($like->getCaseSensitive()); - } -} diff --git a/tests/Reader/Iterable/IterableDataReaderTest.php b/tests/Reader/Iterable/IterableDataReaderTest.php index 06c49bca..fd816080 100644 --- a/tests/Reader/Iterable/IterableDataReaderTest.php +++ b/tests/Reader/Iterable/IterableDataReaderTest.php @@ -431,7 +431,7 @@ public function match( Context $context, ): bool { /** @var Equals $filter */ - return $item[$filter->getField()] === 2; + return $item[$filter->field] === 2; } } ); From 593a20e5faf7f29e4b9dfe1df935397d92c740e3 Mon Sep 17 00:00:00 2001 From: Sergei Predvoditelev Date: Sun, 27 Jul 2025 22:43:16 +0300 Subject: [PATCH 4/4] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1406806c..3fa69b0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ - Chg #224: Change `$iterableFilterHandlers` to context object in `IterableFilterHandlerInterface::match()` (@vjik) - New #224: Add filtering by nested values support in `IterableDataReader` (@vjik) - Chg #225: Rename classes: `All` to `AndX`, `Any` to `OrX`. Remove `Group` class (@vjik) +- Chg #226: Refactor filter classes to use readonly properties instead of getters (@vjik) ## 1.0.1 January 25, 2023