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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
not found (@vjik)
- Enh #161: Add more specified psalm annotations to `CountableDataInterface::count()`,
`PaginatorInterface::getCurrentPageSize()` and `OffsetPaginator::getTotalItems()` (@vjik)
- Chg #165: Simplify `FilterInterface` and `FilterHandlerInterface` (@vjik)
- Chg #166: Remove `EqualsEmpty` filter (@vjik)

## 1.0.1 January 25, 2023
Expand Down
22 changes: 8 additions & 14 deletions src/Reader/Filter/All.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,18 @@
namespace Yiisoft\Data\Reader\Filter;

/**
* `All` filter allows combining multiple criteria or sub-filters using "and" operator.
* `All` filter allows combining multiple sub-filters using "and" operator.
*
* ```php
* $dataReader->withFilter((new All())->withCriteriaArray(
* [
* ['>', 'id', 88],
* ['and', [
* ['=', 'state', 2],
* ['like', 'name', 'eva'],
* ],
* ]
* ));
* $dataReader->withFilter(
* new All(
* new GreaterThan('id', 88),
* new Equals('state', 2),
* new Like('name', 'eva'),
* )
* );
* ```
*/
final class All extends Group
{
public static function getOperator(): string
{
return 'and';
}
}
21 changes: 7 additions & 14 deletions src/Reader/Filter/Any.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,17 @@
namespace Yiisoft\Data\Reader\Filter;

/**
* `Any` filter allows combining multiple criteria or sub-filters using "or" operator.
* `Any` filter allows combining multiple sub-filters using "or" operator.
*
* ```php
* $dataReader->withFilter((new Any())->withCriteriaArray(
* [
* ['>', 'id', 88],
* ['or', [
* ['=', 'state', 2],
* ['like', 'name', 'eva'],
* ],
* ]
* ));
* $dataReader->withFilter(
* new Any(
* new GreaterThan('id', 88),
* new Equals('state', 2),
* )
* );
* ```
*/
final class Any extends Group
{
public static function getOperator(): string
{
return 'or';
}
}
28 changes: 13 additions & 15 deletions src/Reader/Filter/Between.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Yiisoft\Data\Reader\Filter;

use DateTimeInterface;
use Yiisoft\Data\Reader\FilterAssert;
use Yiisoft\Data\Reader\FilterInterface;

/**
Expand All @@ -14,31 +13,30 @@
*/
final class Between implements FilterInterface
{
private bool|DateTimeInterface|float|int|string $minValue;

private bool|DateTimeInterface|float|int|string $maxValue;

/**
* @param string $field Name of the field to compare.
* @param bool|DateTimeInterface|float|int|string $minValue Minimal field value.
* @param bool|DateTimeInterface|float|int|string $maxValue Maximal field value.
*/
public function __construct(private string $field, mixed $minValue, mixed $maxValue)
{
FilterAssert::isScalarOrInstanceOfDateTimeInterface($minValue);
FilterAssert::isScalarOrInstanceOfDateTimeInterface($maxValue);
public function __construct(
private readonly string $field,
private readonly bool|DateTimeInterface|float|int|string $minValue,
private readonly bool|DateTimeInterface|float|int|string $maxValue
) {
}

$this->minValue = $minValue;
$this->maxValue = $maxValue;
public function getField(): string
{
return $this->field;
}

public function toCriteriaArray(): array
public function getMinValue(): float|DateTimeInterface|bool|int|string
{
return [self::getOperator(), $this->field, $this->minValue, $this->maxValue];
return $this->minValue;
}

public static function getOperator(): string
public function getMaxValue(): float|DateTimeInterface|bool|int|string
{
return 'between';
return $this->maxValue;
}
}
34 changes: 15 additions & 19 deletions src/Reader/Filter/Compare.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,40 @@
namespace Yiisoft\Data\Reader\Filter;

use DateTimeInterface;
use Yiisoft\Data\Reader\FilterAssert;
use Yiisoft\Data\Reader\FilterInterface;

/**
* `Compare` filter is a base class that defines a criteria for comparing field value with a given value.
* The operator is defined by child classes.
*/
abstract class Compare implements FilterInterface
{
private bool|DateTimeInterface|float|int|string $value;

/**
* @param string $field Name of the field to compare.
* @param bool|DateTimeInterface|float|int|string $value Value to compare to.
*/
public function __construct(private string $field, mixed $value)
{
$this->setValue($value);
public function __construct(
private readonly string $field,
private bool|DateTimeInterface|float|int|string $value,
) {
}

/**
* @param bool|DateTimeInterface|float|int|string $value Value to compare to.
*/
final public function withValue(mixed $value): static
public function getField(): string
{
$new = clone $this;
$new->setValue($value);
return $new;
return $this->field;
}

public function toCriteriaArray(): array
public function getValue(): float|DateTimeInterface|bool|int|string
{
return [static::getOperator(), $this->field, $this->value];
return $this->value;
}

private function setValue(mixed $value): void
/**
* @param bool|DateTimeInterface|float|int|string $value Value to compare to.
*/
final public function withValue(bool|DateTimeInterface|float|int|string $value): static
{
FilterAssert::isScalarOrInstanceOfDateTimeInterface($value);
$this->value = $value;
$new = clone $this;
$new->value = $value;
return $new;
}
}
4 changes: 0 additions & 4 deletions src/Reader/Filter/Equals.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,4 @@
*/
final class Equals extends Compare
{
public static function getOperator(): string
{
return '=';
}
}
14 changes: 5 additions & 9 deletions src/Reader/Filter/EqualsNull.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,13 @@ final class EqualsNull implements FilterInterface
/**
* @param string $field Name of the field to check.
*/
public function __construct(private string $field)
{
}

public function toCriteriaArray(): array
{
return [self::getOperator(), $this->field];
public function __construct(
private readonly string $field,
) {
}

public static function getOperator(): string
public function getField(): string
{
return 'null';
return $this->field;
}
}
7 changes: 1 addition & 6 deletions src/Reader/Filter/GreaterThan.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,8 @@
namespace Yiisoft\Data\Reader\Filter;

/**
* `GreaterThan` filter defines a criteria for ensuring field value
* is greater than a given value.
* `GreaterThan` filter defines a criteria for ensuring field value is greater than a given value.
*/
final class GreaterThan extends Compare
{
public static function getOperator(): string
{
return '>';
}
}
7 changes: 1 addition & 6 deletions src/Reader/Filter/GreaterThanOrEqual.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,8 @@
namespace Yiisoft\Data\Reader\Filter;

/**
* `GreaterThanOrEqual` filter defines a criteria for ensuring field value
* is greater than or equal to a given value.
* `GreaterThanOrEqual` filter defines a criteria for ensuring field value is greater than or equal to a given value.
*/
final class GreaterThanOrEqual extends Compare
{
public static function getOperator(): string
{
return '>=';
}
}
75 changes: 7 additions & 68 deletions src/Reader/Filter/Group.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,92 +4,31 @@

namespace Yiisoft\Data\Reader\Filter;

use InvalidArgumentException;
use Yiisoft\Data\Reader\FilterInterface;

use function array_shift;
use function is_array;
use function is_string;
use function sprintf;

/**
* `Group` filter is an abstract class that allows combining multiple criteria or sub-filters.
* `Group` filter is an abstract class that allows combining multiple sub-filters.
*/
abstract class Group implements FilterInterface
{
/**
* @var array[]|FilterInterface[] Criteria and sub-filters to use.
* @var FilterInterface[] Sub-filters to use.
*/
private array $filtersAndCriteria;
private array $filters;

/**
* @param FilterInterface ...$filters Sub-filters to use.
*/
public function __construct(FilterInterface ...$filters)
{
$this->filtersAndCriteria = $filters;
}

/**
* Get criteria array based on current filters and criteria.
*
* @return array Criteria array.
*/
public function toCriteriaArray(): array
{
$criteriaArray = [];

foreach ($this->filtersAndCriteria as $filterOrCriteria) {
if ($filterOrCriteria instanceof FilterInterface) {
$filterOrCriteria = $filterOrCriteria->toCriteriaArray();
}

$criteriaArray[] = $filterOrCriteria;
}

return [static::getOperator(), $criteriaArray];
$this->filters = $filters;
}

/**
* Get a new instance with filters set from criteria array provided.
*
* ```php
* $dataReader->withFilter((new All())->withCriteriaArray(
* [
* ['>', 'id', 88],
* ['or', [
* ['=', 'state', 2],
* ['like', 'name', 'eva'],
* ],
* ]
* ));
* ```
*
* @param array[] $criteriaArray Criteria array to use.
* Instances of FilterInterface are ignored.
*
* @throws InvalidArgumentException If criteria array is not valid.
*
* @return static New instance.
*
* @psalm-suppress DocblockTypeContradiction Needed to allow to validation of `$criteriaArray`
* @return FilterInterface[]
*/
public function withCriteriaArray(array $criteriaArray): static
public function getFilters(): array
{
foreach ($criteriaArray as $key => $item) {
if (!is_array($item)) {
throw new InvalidArgumentException(sprintf('Invalid filter on "%s" key.', $key));
}

$operator = array_shift($item);

if (!is_string($operator) || $operator === '') {
throw new InvalidArgumentException(sprintf('Invalid filter operator on "%s" key.', $key));
}
}

$new = clone $this;
$new->filtersAndCriteria = $criteriaArray;
return $new;
return $this->filters;
}
}
29 changes: 21 additions & 8 deletions src/Reader/Filter/In.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace Yiisoft\Data\Reader\Filter;

use Yiisoft\Data\Reader\FilterAssert;
use InvalidArgumentException;
use Yiisoft\Data\Reader\FilterInterface;

/**
Expand All @@ -21,21 +21,34 @@ final class In implements FilterInterface
* @param string $field Name of the field to compare.
* @param bool[]|float[]|int[]|string[] $values Values to check against.
*/
public function __construct(private string $field, array $values)
{
public function __construct(
private readonly string $field,
array $values
) {
foreach ($values as $value) {
FilterAssert::isScalar($value);
/** @psalm-suppress DocblockTypeContradiction */
if (!is_scalar($value)) {
throw new InvalidArgumentException(
sprintf(
'The value should be scalar. "%s" is received.',
get_debug_type($value),
)
);
}
}
$this->values = $values;
}

public function toCriteriaArray(): array
public function getField(): string
{
return [self::getOperator(), $this->field, $this->values];
return $this->field;
}

public static function getOperator(): string
/**
* @return bool[]|float[]|int[]|string[]
*/
public function getValues(): array
{
return 'in';
return $this->values;
}
}
Loading