Skip to content

Commit 5a3e1e0

Browse files
committed
Rename Collection to Scope, remove dead code, simplify API
- Rename Collection to Scope, CollectionIterator to ScopeIterator, move out of Collections sub-namespace - Make Scope::$name non-null, remove all null-name guards - Remove registerScope, __isset, derive (unused after simplification) - Remove unused Stylable methods: realName, remoteFromIdentifier, isRelationProperty - Simplify __call to a one-liner Scope factory - Extract applyFirstMatch helper in Plural to deduplicate loops
1 parent 0b1c694 commit 5a3e1e0

20 files changed

Lines changed: 186 additions & 473 deletions

phpstan.neon.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ parameters:
44
- src/
55
- tests/
66
ignoreErrors:
7-
- message: '/Call to an undefined (static )?method Respect\\Data\\(AbstractMapper|InMemoryMapper|Collections\\Collection)::\w+\(\)\./'
7+
- message: '/Call to an undefined (static )?method Respect\\Data\\(AbstractMapper|InMemoryMapper|Scope)::\w+\(\)\./'
88
- message: '/Unsafe usage of new static\(\)\./'
99
-
1010
message: '/Property .+ is never read, only written\./'

src/AbstractMapper.php

Lines changed: 36 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Respect\Data;
66

7-
use Respect\Data\Collections\Collection;
87
use SplObjectStorage;
98

109
use function count;
@@ -15,7 +14,7 @@
1514

1615
abstract class AbstractMapper
1716
{
18-
/** @var SplObjectStorage<object, Collection> Maps entity → source Collection */
17+
/** @var SplObjectStorage<object, Scope> Maps entity → source Scope */
1918
protected SplObjectStorage $tracked;
2019

2120
/** @var SplObjectStorage<object, string> Maps entity → 'insert'|'update'|'delete' */
@@ -24,9 +23,6 @@ abstract class AbstractMapper
2423
/** @var array<string, array<int|string, object>> Identity-indexed map: [collectionName][idValue] → entity */
2524
protected array $identityMap = [];
2625

27-
/** @var array<string, Collection> */
28-
private array $collections = [];
29-
3026
public EntityFactory $entityFactory { get => $this->hydrator->entityFactory; }
3127

3228
public Styles\Stylable $style { get => $this->entityFactory->style; }
@@ -40,10 +36,10 @@ public function __construct(
4036

4137
abstract public function flush(): void;
4238

43-
abstract public function fetch(Collection $collection, mixed $extra = null): mixed;
39+
abstract public function fetch(Scope $collection, mixed $extra = null): mixed;
4440

4541
/** @return array<int, mixed> */
46-
abstract public function fetchAll(Collection $collection, mixed $extra = null): array;
42+
abstract public function fetchAll(Scope $collection, mixed $extra = null): array;
4743

4844
public function reset(): void
4945
{
@@ -55,29 +51,7 @@ public function clearIdentityMap(): void
5551
$this->identityMap = [];
5652
}
5753

58-
public function trackedCount(): int
59-
{
60-
return count($this->tracked);
61-
}
62-
63-
public function identityMapCount(): int
64-
{
65-
$total = 0;
66-
foreach ($this->identityMap as $entries) {
67-
$total += count($entries);
68-
}
69-
70-
return $total;
71-
}
72-
73-
public function markTracked(object $entity, Collection $collection): bool
74-
{
75-
$this->tracked[$entity] = $collection;
76-
77-
return true;
78-
}
79-
80-
public function persist(object $object, Collection $onCollection): object
54+
public function persist(object $object, Scope $onScope): object
8155
{
8256
if ($this->isTracked($object)) {
8357
$currentOp = $this->pending[$object] ?? null;
@@ -88,45 +62,56 @@ public function persist(object $object, Collection $onCollection): object
8862
return $object;
8963
}
9064

91-
$merged = $this->tryMergeWithIdentityMap($object, $onCollection);
65+
$merged = $this->tryMergeWithIdentityMap($object, $onScope);
9266
if ($merged !== null) {
9367
return $merged;
9468
}
9569

9670
$this->pending[$object] = 'insert';
97-
$this->markTracked($object, $onCollection);
98-
$this->registerInIdentityMap($object, $onCollection);
71+
$this->markTracked($object, $onScope);
72+
$this->registerInIdentityMap($object, $onScope);
9973

10074
return $object;
10175
}
10276

103-
public function remove(object $object, Collection $fromCollection): bool
77+
public function remove(object $object, Scope $fromScope): void
10478
{
10579
$this->pending[$object] = 'delete';
10680

107-
if (!$this->isTracked($object)) {
108-
$this->markTracked($object, $fromCollection);
81+
if ($this->isTracked($object)) {
82+
return;
10983
}
11084

111-
return true;
85+
$this->markTracked($object, $fromScope);
11286
}
11387

114-
public function isTracked(object $entity): bool
88+
public function trackedCount(): int
11589
{
116-
return $this->tracked->offsetExists($entity);
90+
return count($this->tracked);
11791
}
11892

119-
public function registerCollection(string $alias, Collection $collection): void
93+
public function identityMapCount(): int
12094
{
121-
$this->collections[$alias] = $collection;
95+
$total = 0;
96+
foreach ($this->identityMap as $entries) {
97+
$total += count($entries);
98+
}
99+
100+
return $total;
122101
}
123102

124-
protected function registerInIdentityMap(object $entity, Collection $coll): void
103+
public function markTracked(object $entity, Scope $collection): void
125104
{
126-
if ($coll->name === null) {
127-
return;
128-
}
105+
$this->tracked[$entity] = $collection;
106+
}
107+
108+
public function isTracked(object $entity): bool
109+
{
110+
return $this->tracked->offsetExists($entity);
111+
}
129112

113+
protected function registerInIdentityMap(object $entity, Scope $coll): void
114+
{
130115
$idValue = $this->entityIdValue($entity, $coll->name);
131116
if ($idValue === null) {
132117
return;
@@ -135,12 +120,8 @@ protected function registerInIdentityMap(object $entity, Collection $coll): void
135120
$this->identityMap[$coll->name][$idValue] = $entity;
136121
}
137122

138-
protected function evictFromIdentityMap(object $entity, Collection $coll): void
123+
protected function evictFromIdentityMap(object $entity, Scope $coll): void
139124
{
140-
if ($coll->name === null) {
141-
return;
142-
}
143-
144125
$idValue = $this->entityIdValue($entity, $coll->name);
145126
if ($idValue === null) {
146127
return;
@@ -149,9 +130,9 @@ protected function evictFromIdentityMap(object $entity, Collection $coll): void
149130
unset($this->identityMap[$coll->name][$idValue]);
150131
}
151132

152-
protected function findInIdentityMap(Collection $collection): object|null
133+
protected function findInIdentityMap(Scope $collection): object|null
153134
{
154-
if ($collection->name === null || !is_scalar($collection->filter) || $collection->hasChildren) {
135+
if (!is_scalar($collection->filter) || $collection->hasChildren) {
155136
return null;
156137
}
157138

@@ -163,12 +144,8 @@ protected function findInIdentityMap(Collection $collection): object|null
163144
return $this->identityMap[$collection->name][$condition] ?? null;
164145
}
165146

166-
private function tryMergeWithIdentityMap(object $entity, Collection $coll): object|null
147+
private function tryMergeWithIdentityMap(object $entity, Scope $coll): object|null
167148
{
168-
if ($coll->name === null) {
169-
return null;
170-
}
171-
172149
$entityId = $this->entityIdValue($entity, $coll->name);
173150
$idValue = $entityId ?? $this->normalizeIdValue($coll->filter);
174151

@@ -237,22 +214,9 @@ private function normalizeIdValue(mixed $value): int|string|null
237214
return null;
238215
}
239216

240-
public function __isset(string $alias): bool
241-
{
242-
return isset($this->collections[$alias]);
243-
}
244-
245217
/** @param list<mixed> $arguments */
246-
public function __call(string $name, array $arguments): Collection
218+
public function __call(string $name, array $arguments): Scope
247219
{
248-
if (isset($this->collections[$name])) {
249-
if (empty($arguments)) {
250-
return clone $this->collections[$name];
251-
}
252-
253-
return $this->collections[$name]->derive(...$arguments); // @phpstan-ignore argument.type
254-
}
255-
256-
return new Collection($name, ...$arguments); // @phpstan-ignore argument.type
220+
return new Scope($name, ...$arguments); // @phpstan-ignore argument.type
257221
}
258222
}

src/Hydrator.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Respect\Data;
66

7-
use Respect\Data\Collections\Collection;
87
use SplObjectStorage;
98

109
/** Transforms raw backend data into entity instances mapped to their collections */
@@ -15,12 +14,12 @@ interface Hydrator
1514
/** Returns just the root entity */
1615
public function hydrate(
1716
mixed $raw,
18-
Collection $collection,
17+
Scope $collection,
1918
): object|false;
2019

21-
/** @return SplObjectStorage<object, Collection>|false */
20+
/** @return SplObjectStorage<object, Scope>|false */
2221
public function hydrateAll(
2322
mixed $raw,
24-
Collection $collection,
23+
Scope $collection,
2524
): SplObjectStorage|false;
2625
}

src/Hydrators/Base.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
namespace Respect\Data\Hydrators;
66

77
use DomainException;
8-
use Respect\Data\Collections\Collection;
98
use Respect\Data\EntityFactory;
109
use Respect\Data\Hydrator;
10+
use Respect\Data\Scope;
1111
use SplObjectStorage;
1212

1313
/** Base hydrator providing collection-tree entity wiring */
@@ -20,7 +20,7 @@ public function __construct(
2020

2121
public function hydrate(
2222
mixed $raw,
23-
Collection $collection,
23+
Scope $collection,
2424
): object|false {
2525
$entities = $this->hydrateAll($raw, $collection);
2626
if ($entities === false) {
@@ -38,7 +38,7 @@ public function hydrate(
3838
);
3939
}
4040

41-
/** @param SplObjectStorage<object, Collection> $entities */
41+
/** @param SplObjectStorage<object, Scope> $entities */
4242
protected function wireRelationships(SplObjectStorage $entities): void
4343
{
4444
$style = $this->entityFactory->style;
@@ -53,7 +53,7 @@ protected function wireRelationships(SplObjectStorage $entities): void
5353
}
5454

5555
$otherColl = $others[$other];
56-
if ($otherColl->parent !== $coll || $otherColl->name === null) {
56+
if ($otherColl->parent !== $coll) {
5757
continue;
5858
}
5959

src/Hydrators/Nested.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,24 @@
44

55
namespace Respect\Data\Hydrators;
66

7-
use Respect\Data\Collections\Collection;
7+
use Respect\Data\Scope;
88
use SplObjectStorage;
99

1010
use function is_array;
1111

1212
/** Hydrates entities from a nested associative array keyed by collection name */
1313
final class Nested extends Base
1414
{
15-
/** @return SplObjectStorage<object, Collection>|false */
15+
/** @return SplObjectStorage<object, Scope>|false */
1616
public function hydrateAll(
1717
mixed $raw,
18-
Collection $collection,
18+
Scope $collection,
1919
): SplObjectStorage|false {
2020
if (!is_array($raw)) {
2121
return false;
2222
}
2323

24-
/** @var SplObjectStorage<object, Collection> $entities */
24+
/** @var SplObjectStorage<object, Scope> $entities */
2525
$entities = new SplObjectStorage();
2626

2727
$this->hydrateNode($raw, $collection, $entities);
@@ -35,11 +35,11 @@ public function hydrateAll(
3535

3636
/**
3737
* @param array<mixed, mixed> $data
38-
* @param SplObjectStorage<object, Collection> $entities
38+
* @param SplObjectStorage<object, Scope> $entities
3939
*/
4040
private function hydrateNode(
4141
array $data,
42-
Collection $collection,
42+
Scope $collection,
4343
SplObjectStorage $entities,
4444
): void {
4545
$entity = $this->entityFactory->create(
@@ -63,15 +63,15 @@ private function hydrateNode(
6363

6464
/**
6565
* @param array<string, mixed> $parentData
66-
* @param SplObjectStorage<object, Collection> $entities
66+
* @param SplObjectStorage<object, Scope> $entities
6767
*/
6868
private function hydrateChild(
6969
array $parentData,
70-
Collection $child,
70+
Scope $child,
7171
SplObjectStorage $entities,
7272
): void {
7373
$key = $child->name;
74-
if ($key === null || !isset($parentData[$key]) || !is_array($parentData[$key])) {
74+
if (!isset($parentData[$key]) || !is_array($parentData[$key])) {
7575
return;
7676
}
7777

0 commit comments

Comments
 (0)