Skip to content

Commit 6abd60e

Browse files
committed
feat: Implement ArrayAccess for in-memory paginator.
This allows to use this paginator as a regular array.
1 parent 6e0c0a9 commit 6abd60e

File tree

3 files changed

+122
-1
lines changed

3 files changed

+122
-1
lines changed

src/Infrastructure/InMemory/Paginator.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44

55
namespace GeekCell\Ddd\Infrastructure\InMemory;
66

7+
use ArrayAccess;
78
use EmptyIterator;
89
use GeekCell\Ddd\Contracts\Domain\Paginator as PaginatorInterface;
910
use GeekCell\Ddd\Domain\Collection;
1011
use LimitIterator;
1112
use Traversable;
1213

13-
class Paginator implements PaginatorInterface
14+
class Paginator implements PaginatorInterface, ArrayAccess
1415
{
1516
public function __construct(
1617
private readonly Collection $collection,
@@ -52,6 +53,57 @@ public function getTotalItems(): int
5253
return count($this->collection);
5354
}
5455

56+
/**
57+
* @inheritDoc
58+
*/
59+
public function offsetExists(mixed $offset): bool
60+
{
61+
if (!is_int($offset)) {
62+
return false;
63+
}
64+
65+
return $offset >= 0 && $offset < $this->count();
66+
}
67+
68+
/**
69+
* @inheritDoc
70+
*/
71+
public function offsetGet(mixed $offset): mixed
72+
{
73+
if (!$this->offsetExists($offset)) {
74+
return null;
75+
}
76+
77+
$realOffset = $offset + $this->getCurrentPage();
78+
foreach ($this->getIterator() as $index => $item) {
79+
if ($index === $realOffset) {
80+
return $item;
81+
}
82+
}
83+
84+
return null;
85+
}
86+
87+
/**
88+
* This method is not supported since it is not appropriate for a paginator.
89+
*
90+
* @inheritDoc
91+
*/
92+
public function offsetSet(mixed $offset, mixed $value): void
93+
{
94+
// Unsupported since it is not appropriate for a paginator.
95+
}
96+
97+
/**
98+
* This method is not supported since it is not appropriate for a paginator.
99+
*
100+
* @inheritDoc
101+
*/
102+
public function offsetUnset(mixed $offset): void
103+
{
104+
// Unsupported since it is not appropriate for a paginator.
105+
}
106+
55107
/**
56108
* @inheritDoc
57109
*/

tests/Fixtures/Counter.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,9 @@ class Counter
99
public function __construct(private int $value)
1010
{
1111
}
12+
13+
public function getValue(): int
14+
{
15+
return $this->value;
16+
}
1217
}

tests/Infrastructure/InMemory/PaginatorTest.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,70 @@ public function testGetTotalItems(): void
9090
$this->assertEquals(10, $result);
9191
}
9292

93+
public function testArrayAccess(): void
94+
{
95+
// Given
96+
$items = [
97+
new Counter(1),
98+
new Counter(2),
99+
new Counter(3),
100+
new Counter(4),
101+
new Counter(5),
102+
];
103+
104+
/** @var Mockery\MockInterface $collection */
105+
$collection = Mockery::mock(Collection::class);
106+
$collection
107+
->shouldReceive('getIterator')
108+
->andReturn(new ArrayIterator($items));
109+
$collection
110+
->shouldReceive('count')
111+
->andReturn(count($items));
112+
113+
// When
114+
115+
/** @var Collection $collection */
116+
$paginator = new InMemoryPaginator($collection, 2, 2);
117+
$result1 = $paginator[0];
118+
$result2 = $paginator[4];
119+
120+
// Then
121+
$this->assertInstanceOf(Counter::class, $result1);
122+
$this->assertEquals(3, $result1->getValue());
123+
$this->assertNull($result2);
124+
}
125+
126+
public function testArrayAccessWithInvalidOffset(): void
127+
{
128+
// Given
129+
$items = [
130+
new Counter(1),
131+
new Counter(2),
132+
new Counter(3),
133+
new Counter(4),
134+
new Counter(5),
135+
];
136+
137+
/** @var Mockery\MockInterface $collection */
138+
$collection = Mockery::mock(Collection::class);
139+
$collection
140+
->shouldReceive('getIterator')
141+
->andReturn(new ArrayIterator($items));
142+
$collection
143+
->shouldReceive('count')
144+
->andReturn(count($items));
145+
146+
// When
147+
148+
/** @var Collection $collection */
149+
$paginator = new InMemoryPaginator($collection, 2, 2);
150+
151+
// Then
152+
$this->assertNull($paginator[-1]);
153+
$this->assertNull($paginator[0.5]);
154+
$this->assertNull($paginator['invalid']);
155+
}
156+
93157
/**
94158
* @covers \GeekCell\Ddd\Infrastructure\InMemoryPaginator::getIterator
95159
* @covers \GeekCell\Ddd\Infrastructure\InMemoryPaginator::count

0 commit comments

Comments
 (0)