Skip to content

Commit

Permalink
Refactor filter handling
Browse files Browse the repository at this point in the history
  • Loading branch information
mariusklocke committed Feb 2, 2025
1 parent e2e1a85 commit 87a0491
Show file tree
Hide file tree
Showing 24 changed files with 137 additions and 162 deletions.
6 changes: 3 additions & 3 deletions src/Infrastructure/API/GraphQL/EventType.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public function getQueries(): array

if (isset($args['start_date']) || isset($args['end_date'])) {
$filters[] = new RangeFilter(
'occurred_at',
$repo->getField('occurred_at'),
Filter::MODE_INCLUDE,
$args['start_date'] ?? null,
$args['end_date'] ?? null
Expand All @@ -74,15 +74,15 @@ public function getQueries(): array

if (isset($args['type'])) {
$filters[] = new EqualityFilter(
'type',
$repo->getField('type'),
Filter::MODE_INCLUDE,
[$args['type']]
);
}

return $repo->findMany(
$filters,
[new Sorting('occurred_at', Sorting::DIRECTION_DESCENDING)],
[new Sorting($repo->getField('occurred_at'), Sorting::DIRECTION_DESCENDING)],
new Pagination(50, 0)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ public function getBySeason(string $seasonId): array

if (count($seasonIds)) {
$filter = new EqualityFilter(
'season_id',
$this->matchDayRepository->getField('season_id'),
Filter::MODE_INCLUDE,
$seasonIds
);

$sorting = new Sorting(
'number',
$this->matchDayRepository->getField('number'),
Sorting::DIRECTION_ASCENDING
);

Expand Down Expand Up @@ -94,13 +94,13 @@ public function getByTournament(string $tournamentId): array

if (count($tournamentIds)) {
$filter = new EqualityFilter(
'tournament_id',
$this->matchDayRepository->getField('season_id'),
Filter::MODE_INCLUDE,
$tournamentIds
);

$sorting = new Sorting(
'number',
$this->matchDayRepository->getField('number'),
Sorting::DIRECTION_ASCENDING
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function getByMatchDay(string $matchDayId): array

if (count($matchDayIds)) {
$filter = new EqualityFilter(
'match_day_id',
$this->matchRepository->getField('match_day_id'),
Filter::MODE_INCLUDE,
$matchDayIds
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function getByPitch(string $pitchId): ?array

if (count($pitchIds)) {
$filter = new EqualityFilter(
'id',
$this->pitchRepository->getField('id'),
Filter::MODE_INCLUDE,
$pitchIds
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function getByTeam(string $teamId): ?array

if (count($teamIds)) {
$filter = new EqualityFilter(
'id',
$this->teamRepository->getField('id'),
Filter::MODE_INCLUDE,
$teamIds
);
Expand Down
4 changes: 2 additions & 2 deletions src/Infrastructure/API/GraphQL/MatchType.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public function getQueries(): array

if (isset($args['min_date']) || isset($args['max_date'])) {
$filters[] = new RangeFilter(
'kickoff',
$repo->getField('kickoff'),
Filter::MODE_INCLUDE,
$args['min_date'] ?? null,
$args['max_date'] ?? null
Expand All @@ -123,7 +123,7 @@ public function getQueries(): array

return $repo->findMany(
$filters,
[new Sorting('kickoff', Sorting::DIRECTION_ASCENDING)]
[new Sorting($repo->getField('kickoff'), Sorting::DIRECTION_ASCENDING)]
);
}
]
Expand Down
2 changes: 1 addition & 1 deletion src/Infrastructure/API/GraphQL/TeamType.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function getQueries(): array
$repo = $context->getContainer()->get(TeamRepository::class);

$filter = new PatternFilter(
'name',
$repo->getField('name'),
Filter::MODE_INCLUDE,
$args['pattern']
);
Expand Down
14 changes: 13 additions & 1 deletion src/Infrastructure/Persistence/Read/AbstractRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use HexagonalPlayground\Infrastructure\Persistence\Read\Criteria\Sorting;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\EmbeddedObjectField;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\Field;
use RuntimeException;

abstract class AbstractRepository
{
Expand Down Expand Up @@ -61,7 +62,7 @@ public function findById(string $id): ?array
$this->getTableName(),
$this->flattenedFieldDefinitions,
[],
[new EqualityFilter('id', Filter::MODE_INCLUDE, [$id])]
[new EqualityFilter($this->getField('id'), Filter::MODE_INCLUDE, [$id])]
));
}

Expand Down Expand Up @@ -93,4 +94,15 @@ abstract protected function getFieldDefinitions(): array;
* @return string
*/
abstract protected function getTableName(): string;

public function getField(string $name): Field
{
foreach ($this->getFieldDefinitions() as $field) {
if ($field->getName() === $name) {
return $field;
}
}

throw new RuntimeException(sprintf('Unknown field "%s" for table "%s"', $name, $this->getTableName()));
}
}
38 changes: 5 additions & 33 deletions src/Infrastructure/Persistence/Read/Criteria/EqualityFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@

use DateTimeInterface;
use HexagonalPlayground\Domain\Exception\InvalidInputException;
use HexagonalPlayground\Application\TypeAssert;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\DateTimeField;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\Field;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\IntegerField;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\StringField;

Expand All @@ -16,7 +14,7 @@ class EqualityFilter extends Filter
/** @var array|int[]|string[]|DateTimeInterface[] */
private array $values;

public function __construct(string $field, string $mode, array $values)
public function __construct(IntegerField|StringField|DateTimeField $field, string $mode, array $values)
{
if (count($values) === 0) {
throw new InvalidInputException('Invalid EqualityFilter: Array of values must not be empty');
Expand All @@ -25,6 +23,10 @@ public function __construct(string $field, string $mode, array $values)
$this->field = $field;
$this->mode = $mode;
$this->values = $values;

foreach ($this->values as $value) {
$this->field->validate($value);
}
}

/**
Expand All @@ -34,34 +36,4 @@ public function getValues(): array
{
return $this->values;
}

public function validate(Field $fieldDefinition): void
{
$inputName = 'EqualityFilter.' . $fieldDefinition->getName();

// Validate Field type
switch (get_class($fieldDefinition)) {
case IntegerField::class:
$validator = function ($value) use ($inputName): void {
TypeAssert::assertInteger($value, $inputName);
};
break;
case StringField::class:
$validator = function ($value) use ($inputName): void {
TypeAssert::assertString($value, $inputName);
};
break;
case DateTimeField::class:
$validator = function ($value) use ($inputName): void {
TypeAssert::assertInstanceOf($value, DateTimeInterface::class, $inputName);
};
break;
default:
throw new InvalidInputException('Invalid EqualityFilter: Unsupported field type');
}

foreach ($this->values as $value) {
$validator($value);
}
}
}
14 changes: 2 additions & 12 deletions src/Infrastructure/Persistence/Read/Criteria/Filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,17 @@ abstract class Filter
public const MODE_INCLUDE = 'include';
public const MODE_EXCLUDE = 'exclude';

/** @var string */
protected string $field;
protected Field $field;

/** @var string */
protected string $mode;

/**
* @return string
*/
public function getField(): string
public function getField(): Field
{
return $this->field;
}

/**
* @return string
*/
public function getMode(): string
{
return $this->mode;
}

abstract public function validate(Field $fieldDefinition): void;
}
15 changes: 1 addition & 14 deletions src/Infrastructure/Persistence/Read/Criteria/PatternFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,21 @@

namespace HexagonalPlayground\Infrastructure\Persistence\Read\Criteria;

use HexagonalPlayground\Domain\Exception\InvalidInputException;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\Field;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\StringField;

class PatternFilter extends Filter
{
/** @var string */
private string $pattern;

public function __construct(string $field, string $mode, string $pattern)
public function __construct(StringField $field, string $mode, string $pattern)
{
$this->field = $field;
$this->mode = $mode;
$this->pattern = $pattern;
}

/**
* @return string
*/
public function getPattern(): string
{
return $this->pattern;
}

public function validate(Field $fieldDefinition): void
{
if (!($fieldDefinition instanceof StringField)) {
throw new InvalidInputException('Invalid PatternFilter: Can only be used on string fields');
}
}
}
61 changes: 13 additions & 48 deletions src/Infrastructure/Persistence/Read/Criteria/RangeFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,17 @@

use DateTimeInterface;
use HexagonalPlayground\Domain\Exception\InvalidInputException;
use HexagonalPlayground\Application\TypeAssert;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\DateTimeField;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\Field;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\FloatField;
use HexagonalPlayground\Infrastructure\Persistence\Read\Field\IntegerField;

class RangeFilter extends Filter
{
/** @var null|int|float|DateTimeInterface */
private $minValue;
private null|int|float|DateTimeInterface $minValue;

/** @var null|int|float|DateTimeInterface */
private $maxValue;
private null|int|float|DateTimeInterface $maxValue;

public function __construct(string $field, string $mode, $minValue, $maxValue)
public function __construct(IntegerField|FloatField|DateTimeField $field, string $mode, null|int|float|DateTimeInterface $minValue, null|int|float|DateTimeInterface $maxValue)
{
if ($minValue === null && $maxValue === null) {
throw new InvalidInputException('Invalid RangeFilter: Neither minValue nor maxValue given');
Expand All @@ -29,54 +25,23 @@ public function __construct(string $field, string $mode, $minValue, $maxValue)
$this->mode = $mode;
$this->minValue = $minValue;
$this->maxValue = $maxValue;

if ($this->minValue !== null) {
$this->field->validate($this->minValue);
}

if ($this->maxValue !== null) {
$this->field->validate($this->maxValue);
}
}

/**
* @return null|int|float|DateTimeInterface
*/
public function getMinValue()
public function getMinValue(): null|int|float|DateTimeInterface
{
return $this->minValue;
}

/**
* @return null|int|float|DateTimeInterface
*/
public function getMaxValue()
public function getMaxValue(): null|int|float|DateTimeInterface
{
return $this->maxValue;
}

public function validate(Field $fieldDefinition): void
{
$inputName = 'RangeFilter.' . $fieldDefinition->getName();

switch (get_class($fieldDefinition)) {
case IntegerField::class:
$validator = function ($value) use ($inputName): void {
TypeAssert::assertInteger($value, $inputName);
};
break;
case FloatField::class:
$validator = function ($value) use ($inputName): void {
TypeAssert::assertNumber($value, $inputName);
};
break;
case DateTimeField::class:
$validator = function ($value) use ($inputName): void {
TypeAssert::assertInstanceOf($value, DateTimeInterface::class, $inputName);
};
break;
default:
throw new InvalidInputException('Invalid RangeFilter: Unsupported field type');
}

if ($this->minValue !== null) {
$validator($this->minValue);
}

if ($this->maxValue !== null) {
$validator($this->maxValue);
}
}
}
Loading

0 comments on commit 87a0491

Please sign in to comment.