Skip to content

Commit 5eef59f

Browse files
committed
Sync: review provider context handling
- Add provider to `IProviderContext` - Add `getContext()` to `IProvider` - Simplify context propagation in `TProvidable`, `Introspector`, `SyncEntity`, `SyncProvider`, `SyncEntityProvider`, `SyncIntrospector` - Remove unused `set()` and `get()` methods from `IProviderContext` Also: - Fix `SyncStore` issue where `IFacade::unload()` is not always called on `close()` - Rename `SyncSerializeLinkType` to `SyncEntityLinkType`
1 parent a4f0eca commit 5eef59f

18 files changed

+207
-171
lines changed

phpstan-baseline.neon

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -100,31 +100,6 @@ parameters:
100100
count: 1
101101
path: src/Contract/IProvider.php
102102

103-
-
104-
message: "#^Interface Lkrms\\\\Contract\\\\IProviderContext extends generic interface Lkrms\\\\Contract\\\\ReturnsContainer but does not specify its types\\: T$#"
105-
count: 1
106-
path: src/Contract/IProviderContext.php
107-
108-
-
109-
message: "#^Method Lkrms\\\\Contract\\\\IProviderContext\\:\\:get\\(\\) has no return type specified\\.$#"
110-
count: 1
111-
path: src/Contract/IProviderContext.php
112-
113-
-
114-
message: "#^Method Lkrms\\\\Contract\\\\IProviderContext\\:\\:getStack\\(\\) return type with generic interface Lkrms\\\\Contract\\\\IProvidable does not specify its types\\: TProvider, TProviderContext$#"
115-
count: 1
116-
path: src/Contract/IProviderContext.php
117-
118-
-
119-
message: "#^Method Lkrms\\\\Contract\\\\IProviderContext\\:\\:push\\(\\) has parameter \\$entity with generic interface Lkrms\\\\Contract\\\\IProvidable but does not specify its types\\: TProvider, TProviderContext$#"
120-
count: 1
121-
path: src/Contract/IProviderContext.php
122-
123-
-
124-
message: "#^Method Lkrms\\\\Contract\\\\IProviderContext\\:\\:set\\(\\) has parameter \\$value with no type specified\\.$#"
125-
count: 1
126-
path: src/Contract/IProviderContext.php
127-
128103
-
129104
message: "#^Method Lkrms\\\\Contract\\\\IReadable\\:\\:__get\\(\\) has no return type specified\\.$#"
130105
count: 1
@@ -350,31 +325,6 @@ parameters:
350325
count: 1
351326
path: src/Store/TrashStore.php
352327

353-
-
354-
message: "#^Method Lkrms\\\\Support\\\\ProviderContext\\:\\:get\\(\\) has no return type specified\\.$#"
355-
count: 1
356-
path: src/Support/ProviderContext.php
357-
358-
-
359-
message: "#^Method Lkrms\\\\Support\\\\ProviderContext\\:\\:getStack\\(\\) return type with generic interface Lkrms\\\\Contract\\\\IProvidable does not specify its types\\: TProvider, TProviderContext$#"
360-
count: 1
361-
path: src/Support/ProviderContext.php
362-
363-
-
364-
message: "#^Method Lkrms\\\\Support\\\\ProviderContext\\:\\:push\\(\\) has parameter \\$entity with generic interface Lkrms\\\\Contract\\\\IProvidable but does not specify its types\\: TProvider, TProviderContext$#"
365-
count: 1
366-
path: src/Support/ProviderContext.php
367-
368-
-
369-
message: "#^Method Lkrms\\\\Support\\\\ProviderContext\\:\\:set\\(\\) has parameter \\$value with no type specified\\.$#"
370-
count: 1
371-
path: src/Support/ProviderContext.php
372-
373-
-
374-
message: "#^Property Lkrms\\\\Support\\\\ProviderContext\\:\\:\\$Stack with generic interface Lkrms\\\\Contract\\\\IProvidable does not specify its types\\: TProvider, TProviderContext$#"
375-
count: 1
376-
path: src/Support/ProviderContext.php
377-
378328
-
379329
message: "#^Property Lkrms\\\\Sync\\\\Support\\\\SyncEntityProvider\\:\\:\\$Offline is never read, only written\\.$#"
380330
count: 1

src/Concept/Provider.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
use Lkrms\Contract\IContainer;
66
use Lkrms\Contract\IProvider;
7+
use Lkrms\Contract\IProviderContext;
78
use Lkrms\Exception\MethodNotImplementedException;
89
use Lkrms\Support\DateFormatter;
10+
use Lkrms\Support\ProviderContext;
911
use Lkrms\Utility\Env;
1012

1113
/**
@@ -46,6 +48,20 @@ public function description(): ?string
4648
return null;
4749
}
4850

51+
/**
52+
* @inheritDoc
53+
*/
54+
public function getContext(?IContainer $container = null): IProviderContext
55+
{
56+
if (!$container) {
57+
$container = $this->App;
58+
}
59+
60+
return $container
61+
->bindIf(IProviderContext::class, ProviderContext::class)
62+
->get(IProviderContext::class, [$this]);
63+
}
64+
4965
/**
5066
* @inheritDoc
5167
*/

src/Concern/TProvidable.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use Lkrms\Support\Iterator\Contract\FluentIteratorInterface;
1010
use Lkrms\Support\Iterator\IterableIterator;
1111
use Lkrms\Support\Introspector;
12-
use Lkrms\Support\ProviderContext;
1312
use Generator;
1413
use LogicException;
1514

@@ -151,9 +150,7 @@ final public static function provide(
151150

152151
$context = $context
153152
? $context->withContainer($container)
154-
: $container
155-
->bindIf(IProviderContext::class, ProviderContext::class)
156-
->get(IProviderContext::class);
153+
: $provider->getContext($container);
157154

158155
$closure = Introspector::getService(
159156
$container, static::class
@@ -206,9 +203,7 @@ private static function _provideList(
206203
/** @var IProviderContext */
207204
$context = $context
208205
? $context->withContainer($container)
209-
: $container
210-
->bindIf(IProviderContext::class, ProviderContext::class)
211-
->get(IProviderContext::class);
206+
: $provider->getContext($container);
212207
$context = $context->withConformity($conformity);
213208

214209
$introspector = Introspector::getService($container, static::class);

src/Contract/IProvider.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
*/
1212
interface IProvider extends ReturnsContainer, ReturnsEnvironment, ReturnsDescription
1313
{
14+
/**
15+
* Get a context for instantiation of objects on the provider's behalf
16+
*
17+
*/
18+
public function getContext(?IContainer $container = null): IProviderContext;
19+
1420
/**
1521
* Get a stable list of values that, together with the name of the class,
1622
* uniquely identifies the backend instance

src/Contract/IProviderContext.php

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,57 +5,50 @@
55
use Lkrms\Support\Catalog\ArrayKeyConformity;
66

77
/**
8-
* The context within which an IProvidable is instantiated
8+
* The context within which an entity is instantiated by a provider
99
*
10+
* @extends ReturnsContainer<IContainer>
11+
* @extends ReturnsProvider<IProvider>
1012
*/
11-
interface IProviderContext extends IImmutable, ReturnsContainer
13+
interface IProviderContext extends IImmutable, ReturnsContainer, ReturnsProvider
1214
{
1315
/**
14-
* Apply an arbitrary value to the context
16+
* Apply a container to the context
1517
*
1618
* @return $this
1719
*/
18-
public function set(string $key, $value);
20+
public function withContainer(IContainer $container);
1921

2022
/**
21-
* Push the entity propagating this context onto the stack
23+
* Push the entity propagating the context onto the stack
2224
*
2325
* Note that although the same entity may be passed to both
2426
* {@see IProviderContext::push()} and {@see IProviderContext::withParent()}
25-
* (e.g. when a hierarchy is being populated from a root entity), they have
26-
* completely different purposes.
27-
*
28-
* A `Post` object, for example, would `push()` itself onto the entity stack
29-
* to retrieve a `User` instance for its `Author` property. The `Post` has a
30-
* reference to a `User`, but is not its parent because the reference is not
31-
* hierarchical. (Also, only a `User` entity can be the parent or child of
32-
* another `User` entity.)
27+
* (e.g. when a hierarchy is being populated from a root entity), they serve
28+
* different purposes.
3329
*
34-
* A `Staff` object, however, would `push()` itself onto the entity stack to
35-
* retrieve `Staff` instances for its `DirectReports` property, **and** pass
36-
* itself to `withParent()` as the parent (a.k.a. manager) of those `Staff`.
30+
* Example: a `Post` object would `push()` itself onto the entity stack to
31+
* retrieve a `User` instance for its `Author` property, but a `Staff`
32+
* object would `push()` itself onto the entity stack to retrieve `Staff`
33+
* instances for its `DirectReports` property, **and** pass itself to
34+
* `withParent()` as the parent (a.k.a. manager) of those `Staff`.
3735
*
36+
* @param IProvidable<IProvider,IProviderContext> $entity
3837
* @return $this
3938
*/
4039
public function push(IProvidable $entity);
4140

4241
/**
43-
* Set the context's container
44-
*
45-
* @return $this
46-
*/
47-
public function withContainer(IContainer $container);
48-
49-
/**
50-
* Set the parent of ITreeable entities instantiated within the context
42+
* Apply a parent entity to the context
5143
*
5244
* @see IProviderContext::push()
45+
*
5346
* @return $this
5447
*/
5548
public function withParent(?ITreeable $parent);
5649

5750
/**
58-
* Propagate the current payload's array key conformity
51+
* Apply the current payload's array key conformity to the context
5952
*
6053
* @param ArrayKeyConformity::* $conformity Use
6154
* {@see ArrayKeyConformity::COMPLETE} wherever possible to improve
@@ -65,20 +58,19 @@ public function withParent(?ITreeable $parent);
6558
public function withConformity($conformity);
6659

6760
/**
68-
* Get the value most recently passed to set($key)
69-
*
61+
* @inheritDoc
7062
*/
71-
public function get(string $key);
63+
public function provider(): IProvider;
7264

7365
/**
7466
* Get the entities responsible for propagating this context
7567
*
76-
* @return IProvidable[]
68+
* @return IProvidable<IProvider,IProviderContext>[]
7769
*/
78-
public function getStack(): array;
70+
public function stack(): array;
7971

8072
/**
81-
* Get the value most recently passed to withParent()
73+
* Get the parent entity applied to the context
8274
*
8375
*/
8476
public function getParent(): ?ITreeable;

src/Support/Introspector.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -206,19 +206,23 @@ final public function getCreateProvidableFromSignatureClosure(array $keys, bool
206206

207207
return
208208
static function (array $array, IProvider $provider, $context = null) use ($closure, $service) {
209-
[$container, $parent] =
210-
$context instanceof IProviderContext
211-
? [$context->container(), $context->getParent()]
212-
: [$context ?: $provider->container(), null];
209+
if ($context instanceof IProviderContext) {
210+
$container = $context->container();
211+
$parent = $context->getParent();
212+
} else {
213+
/** @var IContainer */
214+
$container = $context ?? $provider->container();
215+
$context = $provider->getContext($container);
216+
}
213217

214218
return $closure(
215219
$array,
216220
$service,
217221
$container,
218222
$provider,
219-
$context ?: new ProviderContext($container, $parent),
223+
$context,
220224
$provider->dateFormatter(),
221-
$parent,
225+
$parent ?? null,
222226
);
223227
};
224228
}

0 commit comments

Comments
 (0)