diff --git a/CHANGELOG.md b/CHANGELOG.md index 7978b95f..9420f3f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,9 +24,9 @@ `PaginatorInterface::getCurrentPageSize()` and `OffsetPaginator::getTotalItems()` (@vjik) - Chg #165: Simplify `FilterInterface` and `FilterHandlerInterface` (@vjik) - Chg #166: Remove `EqualsEmpty` filter (@vjik) -- Bug #173: Make `Like` filter case-sensitive (@arogachev) -- New #173: Add `ILike` filter (case-insensitive variation of `Like` filter) (@arogachev) - New #176: Add `OrderHelper` (@vjik) +- New #173, #184: Add `$caseSensitive` parameter to `Like` filter to control whether the search must be case-sensitive + or not (@arogachev) ## 1.0.1 January 25, 2023 diff --git a/src/Reader/Filter/ILike.php b/src/Reader/Filter/ILike.php deleted file mode 100644 index 3cabf898..00000000 --- a/src/Reader/Filter/ILike.php +++ /dev/null @@ -1,33 +0,0 @@ -field; - } - - public function getValue(): string - { - return $this->value; - } -} diff --git a/src/Reader/Filter/Like.php b/src/Reader/Filter/Like.php index ffd79801..296972c8 100644 --- a/src/Reader/Filter/Like.php +++ b/src/Reader/Filter/Like.php @@ -7,17 +7,23 @@ use Yiisoft\Data\Reader\FilterInterface; /** - * `Like` filter defines a criteria for ensuring field value is like-match to a given value (case-sensitive). + * `Like` filter defines a criteria for ensuring field value is like-match to a given value. */ final class Like implements FilterInterface { /** * @param string $field Name of the field to compare. * @param string $value Value to like-compare with. + * @param bool|null $caseSensitive Whether search must be case-sensitive: + * + * - `null` - depends on implementation; + * - `true` - case-sensitive; + * - `false` - case-insensitive. */ public function __construct( private readonly string $field, private readonly string $value, + private readonly ?bool $caseSensitive = null, ) { } @@ -30,4 +36,9 @@ public function getValue(): string { return $this->value; } + + public function isCaseSensitive(): ?bool + { + return $this->caseSensitive; + } } diff --git a/src/Reader/Iterable/FilterHandler/ILikeHandler.php b/src/Reader/Iterable/FilterHandler/ILikeHandler.php deleted file mode 100644 index 65ff00b1..00000000 --- a/src/Reader/Iterable/FilterHandler/ILikeHandler.php +++ /dev/null @@ -1,33 +0,0 @@ -getField()); - - /** @infection-ignore-all MBString No suitable test case was found yet. */ - return is_string($itemValue) && mb_stripos($itemValue, $filter->getValue()) !== false; - } -} diff --git a/src/Reader/Iterable/FilterHandler/LikeHandler.php b/src/Reader/Iterable/FilterHandler/LikeHandler.php index 05eb5621..d6941ac8 100644 --- a/src/Reader/Iterable/FilterHandler/LikeHandler.php +++ b/src/Reader/Iterable/FilterHandler/LikeHandler.php @@ -26,8 +26,13 @@ public function match(object|array $item, FilterInterface $filter, array $iterab /** @var Like $filter */ $itemValue = ArrayHelper::getValue($item, $filter->getField()); + if (!is_string($itemValue)) { + return false; + } /** @infection-ignore-all MBString No suitable test case was found yet. */ - return is_string($itemValue) && mb_strpos($itemValue, $filter->getValue()) !== false; + return $filter->isCaseSensitive() === true + ? mb_strpos($itemValue, $filter->getValue()) !== false + : mb_stripos($itemValue, $filter->getValue()) !== false; } } diff --git a/src/Reader/Iterable/IterableDataReader.php b/src/Reader/Iterable/IterableDataReader.php index 211d5c6e..81cb90e1 100644 --- a/src/Reader/Iterable/IterableDataReader.php +++ b/src/Reader/Iterable/IterableDataReader.php @@ -20,7 +20,6 @@ use Yiisoft\Data\Reader\Iterable\FilterHandler\EqualsNullHandler; use Yiisoft\Data\Reader\Iterable\FilterHandler\GreaterThanHandler; use Yiisoft\Data\Reader\Iterable\FilterHandler\GreaterThanOrEqualHandler; -use Yiisoft\Data\Reader\Iterable\FilterHandler\ILikeHandler; use Yiisoft\Data\Reader\Iterable\FilterHandler\InHandler; use Yiisoft\Data\Reader\Iterable\FilterHandler\LessThanHandler; use Yiisoft\Data\Reader\Iterable\FilterHandler\LessThanOrEqualHandler; @@ -74,7 +73,6 @@ public function __construct(private iterable $data) new EqualsNullHandler(), new GreaterThanHandler(), new GreaterThanOrEqualHandler(), - new ILikeHandler(), new InHandler(), new LessThanHandler(), new LessThanOrEqualHandler(), diff --git a/tests/Reader/IterableDataReaderTest.php b/tests/Reader/IterableDataReaderTest.php index 112527de..2aff4f6a 100644 --- a/tests/Reader/IterableDataReaderTest.php +++ b/tests/Reader/IterableDataReaderTest.php @@ -14,7 +14,6 @@ use Yiisoft\Data\Reader\Filter\Equals; use Yiisoft\Data\Reader\Filter\GreaterThan; use Yiisoft\Data\Reader\Filter\GreaterThanOrEqual; -use Yiisoft\Data\Reader\Filter\ILike; use Yiisoft\Data\Reader\Filter\In; use Yiisoft\Data\Reader\Filter\LessThan; use Yiisoft\Data\Reader\Filter\LessThanOrEqual; @@ -275,18 +274,6 @@ public function testLikeFiltering(): void ], $reader->read()); } - public function testILikeFiltering(): void - { - $filter = new ILike('name', 'agent'); - $reader = (new IterableDataReader(self::DEFAULT_DATASET)) - ->withFilter($filter); - - $this->assertSame([ - 2 => self::ITEM_3, - 3 => self::ITEM_4, - ], $reader->read()); - } - public function testNotFiltering(): void { $filter = new Not(new Equals('id', 1)); diff --git a/tests/Reader/IterableHandler/ILikeTest.php b/tests/Reader/IterableHandler/ILikeTest.php deleted file mode 100644 index 24eef62e..00000000 --- a/tests/Reader/IterableHandler/ILikeTest.php +++ /dev/null @@ -1,32 +0,0 @@ - 1, 'value' => 'Great Cat Fighter'], 'value', 'Great Cat Fighter'], - [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Cat'], - [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'cat'], - [false, ['id' => 1, 'value' => 'Great Cat Fighter'], 'id', '1'], - [true, ['id' => 1, 'value' => '๐Ÿ™๐Ÿ™‚๐Ÿ™'], 'value', '๐Ÿ™‚'], - [true, ['id' => 1, 'value' => 'ะŸั€ะธะฒะตั‚ ะผะธั€'], 'value', ' '], - ]; - } - - #[DataProvider('matchDataProvider')] - public function testMatch(bool $expected, array $item, string $field, string $value): void - { - $processor = new ILikeHandler(); - $this->assertSame($expected, $processor->match($item, new ILike($field, $value), [])); - } -} diff --git a/tests/Reader/IterableHandler/LikeTest.php b/tests/Reader/IterableHandler/LikeTest.php index 4bed7caf..43c2e41d 100644 --- a/tests/Reader/IterableHandler/LikeTest.php +++ b/tests/Reader/IterableHandler/LikeTest.php @@ -14,19 +14,33 @@ final class LikeTest extends TestCase public static function matchDataProvider(): array { return [ - [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Great Cat Fighter'], - [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Cat'], - [false, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'cat'], - [false, ['id' => 1, 'value' => 'Great Cat Fighter'], 'id', '1'], - [true, ['id' => 1, 'value' => '๐Ÿ™๐Ÿ™‚๐Ÿ™'], 'value', '๐Ÿ™‚'], - [true, ['id' => 1, 'value' => 'ะŸั€ะธะฒะตั‚ ะผะธั€'], 'value', ' '], + [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Great Cat Fighter', null], + [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Cat', null], + [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'cat', null], + [false, ['id' => 1, 'value' => 'Great Cat Fighter'], 'id', '1', null], + [true, ['id' => 1, 'value' => '๐Ÿ™๐Ÿ™‚๐Ÿ™'], 'value', '๐Ÿ™‚', null], + [true, ['id' => 1, 'value' => 'ะŸั€ะธะฒะตั‚ ะผะธั€'], 'value', ' ', null], + + [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Great Cat Fighter', false], + [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Cat', false], + [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'cat', false], + [false, ['id' => 1, 'value' => 'Great Cat Fighter'], 'id', '1', false], + [true, ['id' => 1, 'value' => '๐Ÿ™๐Ÿ™‚๐Ÿ™'], 'value', '๐Ÿ™‚', false], + [true, ['id' => 1, 'value' => 'ะŸั€ะธะฒะตั‚ ะผะธั€'], 'value', ' ', false], + + [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Great Cat Fighter', true], + [true, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'Cat', true], + [false, ['id' => 1, 'value' => 'Great Cat Fighter'], 'value', 'cat', true], + [false, ['id' => 1, 'value' => 'Great Cat Fighter'], 'id', '1', true], + [true, ['id' => 1, 'value' => '๐Ÿ™๐Ÿ™‚๐Ÿ™'], 'value', '๐Ÿ™‚', true], + [true, ['id' => 1, 'value' => 'ะŸั€ะธะฒะตั‚ ะผะธั€'], 'value', ' ', true], ]; } #[DataProvider('matchDataProvider')] - public function testMatch(bool $expected, array $item, string $field, string $value): void + public function testMatch(bool $expected, array $item, string $field, string $value, ?bool $caseSensitive): void { $processor = new LikeHandler(); - $this->assertSame($expected, $processor->match($item, new Like($field, $value), [])); + $this->assertSame($expected, $processor->match($item, new Like($field, $value, $caseSensitive), [])); } }