Skip to content

Commit

Permalink
Fix #75: Improve Sort, finalize processors (#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
rustamwin committed Apr 13, 2022
1 parent 474c127 commit 0c0121e
Show file tree
Hide file tree
Showing 16 changed files with 90 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/All.php
Expand Up @@ -6,7 +6,7 @@

use function in_array;

class All extends GroupProcessor
final class All extends GroupProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/Any.php
Expand Up @@ -6,7 +6,7 @@

use function in_array;

class Any extends GroupProcessor
final class Any extends GroupProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/Between.php
Expand Up @@ -12,7 +12,7 @@
use function array_key_exists;
use function count;

class Between implements IterableProcessorInterface, FilterProcessorInterface
final class Between implements IterableProcessorInterface, FilterProcessorInterface
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/Equals.php
Expand Up @@ -6,7 +6,7 @@

use DateTimeInterface;

class Equals extends CompareProcessor
final class Equals extends CompareProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/EqualsEmpty.php
Expand Up @@ -10,7 +10,7 @@

use function count;

class EqualsEmpty implements IterableProcessorInterface, FilterProcessorInterface
final class EqualsEmpty implements IterableProcessorInterface, FilterProcessorInterface
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/EqualsNull.php
Expand Up @@ -11,7 +11,7 @@
use function array_key_exists;
use function count;

class EqualsNull implements IterableProcessorInterface, FilterProcessorInterface
final class EqualsNull implements IterableProcessorInterface, FilterProcessorInterface
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/GreaterThan.php
Expand Up @@ -6,7 +6,7 @@

use DateTimeInterface;

class GreaterThan extends CompareProcessor
final class GreaterThan extends CompareProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/GreaterThanOrEqual.php
Expand Up @@ -6,7 +6,7 @@

use DateTimeInterface;

class GreaterThanOrEqual extends CompareProcessor
final class GreaterThanOrEqual extends CompareProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/In.php
Expand Up @@ -7,7 +7,7 @@
use function in_array;
use function is_array;

class In extends CompareProcessor
final class In extends CompareProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/LessThan.php
Expand Up @@ -6,7 +6,7 @@

use DateTimeInterface;

class LessThan extends CompareProcessor
final class LessThan extends CompareProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/LessThanOrEqual.php
Expand Up @@ -6,7 +6,7 @@

use DateTimeInterface;

class LessThanOrEqual extends CompareProcessor
final class LessThanOrEqual extends CompareProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/Like.php
Expand Up @@ -7,7 +7,7 @@
use function is_string;
use function stripos;

class Like extends CompareProcessor
final class Like extends CompareProcessor
{
public function getOperator(): string
{
Expand Down
2 changes: 1 addition & 1 deletion src/Reader/Iterable/Processor/Not.php
Expand Up @@ -14,7 +14,7 @@
use function is_string;
use function sprintf;

class Not implements IterableProcessorInterface, FilterProcessorInterface
final class Not implements IterableProcessorInterface, FilterProcessorInterface
{
public function getOperator(): string
{
Expand Down
31 changes: 25 additions & 6 deletions src/Reader/Sort.php
Expand Up @@ -58,6 +58,11 @@ final class Sort
*/
private bool $ignoreExtraFields;

/**
* @var bool Whether to add default sorting when forming criteria.
*/
private bool $withDefaultSorting = true;

/**
* @var array Logical fields to order by in form of [name => direction].
* @psalm-var TOrder
Expand Down Expand Up @@ -128,7 +133,7 @@ private function __construct(bool $ignoreExtraFields, array $config)
* ]
* ```
*
* The name field is a virtual field name that consists of two real fields, `first_name` amd `last_name`. Virtual
* The name field is a virtual field name that consists of two real fields, `first_name` and `last_name`. Virtual
* field name is used in order string or order array while real fields are used in final sorting criteria.
*
* Each configuration has the following options:
Expand Down Expand Up @@ -172,7 +177,7 @@ public static function only(array $config): self
* ]
* ```
*
* The name field is a virtual field name that consists of two real fields, `first_name` amd `last_name`. Virtual
* The name field is a virtual field name that consists of two real fields, `first_name` and `last_name`. Virtual
* field name is used in order string or order array while real fields are used in final sorting criteria.
*
* Each configuration has the following options:
Expand All @@ -193,7 +198,7 @@ public static function any(array $config = []): self
*
* The string consists of comma-separated field names.
* If the name is prefixed with `-`, field order is descending.
* Otherwise the order is ascending.
* Otherwise, the order is ascending.
*
* @param string $orderString Logical fields order as comma-separated string.
*
Expand Down Expand Up @@ -230,6 +235,18 @@ public function withOrder(array $order): self
return $new;
}

/**
* Formation of criteria without default sorting.
*
* @return self
*/
public function withoutDefaultSorting(): self
{
$new = clone $this;
$new->withDefaultSorting = false;
return $new;
}

/**
* @psalm-return TOrder
*/
Expand All @@ -243,7 +260,7 @@ public function getOrder(): array
*
* The string consists of comma-separated field names.
* If the name is prefixed with `-`, field order is descending.
* Otherwise the order is ascending.
* Otherwise, the order is ascending.
*
* @return string An order string.
*/
Expand Down Expand Up @@ -284,8 +301,10 @@ public function getCriteria(): array
}
}

foreach ($config as $fieldConfig) {
$criteria += $fieldConfig[$fieldConfig['default']];
if ($this->withDefaultSorting) {
foreach ($config as $fieldConfig) {
$criteria += $fieldConfig[$fieldConfig['default']];
}
}

return $criteria;
Expand Down
30 changes: 27 additions & 3 deletions tests/Reader/Iterable/IterableDataReaderTest.php
Expand Up @@ -5,6 +5,7 @@
namespace Yiisoft\Data\Tests\Reader\Iterable;

use ArrayIterator;
use DateTimeInterface;
use Generator;
use InvalidArgumentException;
use RuntimeException;
Expand Down Expand Up @@ -392,14 +393,37 @@ public function testCustomEqualsProcessor(): void

$dataReader = (new IterableDataReader(self::DEFAULT_DATASET))
->withSort($sort)
->withFilterProcessors(new class () extends \Yiisoft\Data\Reader\Iterable\Processor\Equals {
->withFilterProcessors(new class () extends \Yiisoft\Data\Reader\Iterable\Processor\CompareProcessor {
public function getOperator(): string
{
return \Yiisoft\Data\Reader\Filter\Equals::getOperator();
}

protected function compare($itemValue, $argumentValue): bool
{
if (!$itemValue instanceof DateTimeInterface) {
return $itemValue == $argumentValue;
}

return $argumentValue instanceof DateTimeInterface
&& $itemValue->getTimestamp() === $argumentValue->getTimestamp();
}

public function match(array $item, array $arguments, array $filterProcessors): bool
{
[$field,] = $arguments;
if (count($arguments) !== 2) {
throw new InvalidArgumentException('$arguments should contain exactly two elements.');
}

[$field, $value] = $arguments;
FilterDataValidationHelper::assertFieldIsString($field);

if ($item[$field] === 2) {
return true;
}
return parent::match($item, $arguments, $filterProcessors);

/** @var string $field */
return array_key_exists($field, $item) && $this->compare($item[$field], $value);
}
});

Expand Down
25 changes: 25 additions & 0 deletions tests/Reader/SortTest.php
Expand Up @@ -229,4 +229,29 @@ public function testGetCriteriaWithShortFieldSyntax(): void
'id' => SORT_ASC,
], $sort->getCriteria());
}

public function testWithoutDefaultSortingWhenFormingCriteria(): void
{
$sort = Sort::only([
'a',
'b' => [
'asc' => ['bee' => SORT_ASC],
'desc' => ['bee' => SORT_DESC],
'default' => 'asc',
],
])
->withOrder(
[
'b' => 'desc',
]
)
->withoutDefaultSorting();

$this->assertSame(
[
'bee' => SORT_DESC,
],
$sort->getCriteria()
);
}
}

0 comments on commit 0c0121e

Please sign in to comment.