-
Notifications
You must be signed in to change notification settings - Fork 62
Expand file tree
/
Copy pathInMemoryRepository.php
More file actions
121 lines (96 loc) · 2.84 KB
/
InMemoryRepository.php
File metadata and controls
121 lines (96 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
declare(strict_types=1);
namespace App\Shared\Infrastructure\InMemory;
use App\Shared\Domain\Repository\PaginatorInterface;
use App\Shared\Domain\Repository\RepositoryInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Webmozart\Assert\Assert;
/**
* @template T of object
*
* @implements RepositoryInterface<T>
*/
abstract class InMemoryRepository implements RepositoryInterface
{
/**
* @var array<string, T>
*/
protected array $entities = [];
protected ?int $page = null;
protected ?int $itemsPerPage = null;
public function getIterator(): \Iterator
{
if (null !== $paginator = $this->paginator()) {
yield from $paginator;
return;
}
yield from $this->entities;
}
public function withPagination(int $page, int $itemsPerPage): static
{
Assert::positiveInteger($page);
Assert::positiveInteger($itemsPerPage);
$cloned = clone $this;
$cloned->page = $page;
$cloned->itemsPerPage = $itemsPerPage;
return $cloned;
}
public function withoutPagination(): static
{
$cloned = clone $this;
$cloned->page = null;
$cloned->itemsPerPage = null;
return $cloned;
}
public function paginator(): ?PaginatorInterface
{
if (null === $this->page || null === $this->itemsPerPage) {
return null;
}
return new InMemoryPaginator(
new \ArrayIterator($this->entities),
count($this->entities),
$this->page,
$this->itemsPerPage,
);
}
public function count(): int
{
if (null !== $paginator = $this->paginator()) {
return count($paginator);
}
return count($this->entities);
}
/**
* @param callable(mixed, mixed=): bool $filter
*
* @return static<T>
*/
protected function filter(callable $filter): static
{
$cloned = clone $this;
$cloned->entities = array_filter($cloned->entities, $filter);
return $cloned;
}
/**
* @param array<string, string> $criteria
* @return $this
*/
protected function sort(array $criteria): static
{
$cloned = clone $this;
$accessor = PropertyAccess::createPropertyAccessor();
uasort($cloned->entities, function (object $a, object $b) use ($criteria, $accessor): int {
foreach ($criteria as $field => $direction) {
$aValue = $accessor->getValue($a, $field);
$bValue = $accessor->getValue($b, $field);
$comparison = $aValue <=> $bValue;
if (0 !== $comparison) {
return 'asc' === $direction ? $comparison : -$comparison;
}
}
return 0;
});
return $cloned;
}
}