Skip to content

Commit 5b8be8a

Browse files
authored
feat(storage): support multiple storage configurations (#1187)
1 parent 3209379 commit 5b8be8a

23 files changed

+427
-192
lines changed

packages/container/src/Container.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ interface Container
1212
{
1313
public function register(string $className, callable $definition): self;
1414

15-
public function unregister(string $className): self;
15+
public function unregister(string $className, bool $tagged = false): self;
1616

1717
public function singleton(string $className, mixed $definition, ?string $tag = null): self;
1818

packages/container/src/GenericContainer.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ public function setDefinitions(array $definitions): self
4444
return $this;
4545
}
4646

47+
public function setSingletons(array $singletons): self
48+
{
49+
$this->singletons = new ArrayIterator($singletons);
50+
51+
return $this;
52+
}
53+
4754
public function setInitializers(array $initializers): self
4855
{
4956
$this->initializers = new ArrayIterator($initializers);
@@ -85,10 +92,20 @@ public function register(string $className, callable $definition): self
8592
return $this;
8693
}
8794

88-
public function unregister(string $className): self
95+
public function unregister(string $className, bool $tagged = false): self
8996
{
9097
unset($this->definitions[$className], $this->singletons[$className]);
9198

99+
if ($tagged) {
100+
$singletons = array_filter(
101+
array: $this->getSingletons(),
102+
callback: static fn (mixed $_, string $key) => ! str_starts_with($key, "{$className}#"),
103+
mode: \ARRAY_FILTER_USE_BOTH,
104+
);
105+
106+
$this->setSingletons($singletons);
107+
}
108+
92109
return $this;
93110
}
94111

@@ -241,6 +258,28 @@ public function addInitializer(ClassReflector|string $initializerClass): Contain
241258
return $this;
242259
}
243260

261+
public function removeInitializer(ClassReflector|string $initializerClass): Container
262+
{
263+
if (! ($initializerClass instanceof ClassReflector)) {
264+
$initializerClass = new ClassReflector($initializerClass);
265+
}
266+
267+
if ($initializerClass->getType()->matches(DynamicInitializer::class)) {
268+
$index = array_find_key(
269+
array: $this->dynamicInitializers->getArrayCopy(),
270+
callback: static fn (string $className) => $className === $initializerClass->getName(),
271+
);
272+
273+
unset($this->dynamicInitializers[$index]);
274+
275+
return $this;
276+
}
277+
278+
unset($this->initializers[$initializerClass->getName()]);
279+
280+
return $this;
281+
}
282+
244283
private function resolve(string $className, ?string $tag = null, mixed ...$params): ?object
245284
{
246285
$class = new ClassReflector($className);

packages/container/tests/ContainerTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,25 @@ public function test_unregister_singleton(): void
443443
$container->get(InterfaceA::class);
444444
}
445445

446+
public function test_unregister_tagged(): void
447+
{
448+
$container = new GenericContainer();
449+
450+
$container->singleton(
451+
TaggedDependency::class,
452+
new TaggedDependency('web'),
453+
tag: 'web',
454+
);
455+
456+
$this->assertInstanceOf(TaggedDependency::class, $container->get(TaggedDependency::class, 'web'));
457+
458+
$container->unregister(TaggedDependency::class, tagged: true);
459+
460+
$this->expectException(CannotResolveTaggedDependency::class);
461+
462+
$container->get(TaggedDependency::class, 'web');
463+
}
464+
446465
public function test_has(): void
447466
{
448467
$container = new GenericContainer();

packages/storage/composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"minimum-stability": "dev",
66
"require": {
77
"php": "^8.4",
8-
"league/flysystem": "^3.29.1"
8+
"league/flysystem": "^3.29.1",
9+
"tempest/container": "dev-main"
910
},
1011
"require-dev": {
1112
"league/flysystem-aws-s3-v3": "^3.0",

packages/storage/src/Config/AzureStorageConfig.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use League\Flysystem\AzureBlobStorage\AzureBlobStorageAdapter;
66
use League\Flysystem\FilesystemAdapter;
77
use MicrosoftAzure\Storage\Blob\BlobRestProxy;
8+
use UnitEnum;
89

910
final class AzureStorageConfig implements StorageConfig
1011
{
@@ -30,6 +31,11 @@ public function __construct(
3031
* Whether the storage is read-only.
3132
*/
3233
public bool $readonly = false,
34+
35+
/**
36+
* Identifier for this storage configuration.
37+
*/
38+
public null|string|UnitEnum $tag = null,
3339
) {}
3440

3541
public function createAdapter(): FilesystemAdapter

packages/storage/src/Config/CustomStorageConfig.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Tempest\Storage\Config;
44

55
use League\Flysystem\FilesystemAdapter;
6+
use UnitEnum;
67

78
use function Tempest\get;
89

@@ -20,6 +21,11 @@ public function __construct(
2021
* Whether the storage is read-only.
2122
*/
2223
public bool $readonly = false,
24+
25+
/**
26+
* Identifier for this storage configuration.
27+
*/
28+
public null|string|UnitEnum $tag = null,
2329
) {}
2430

2531
public function createAdapter(): FilesystemAdapter

packages/storage/src/Config/FTPStorageConfig.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use League\Flysystem\FilesystemAdapter;
66
use League\Flysystem\Ftp\FtpAdapter;
77
use League\Flysystem\Ftp\FtpConnectionOptions;
8+
use UnitEnum;
89

910
final class FTPStorageConfig implements StorageConfig
1011
{
@@ -29,7 +30,16 @@ public function __construct(
2930
public ?bool $ignorePassiveAddress = null,
3031
public bool $recurseManually = true,
3132
public bool $timestampsOnUnixListingsEnabled = false,
33+
34+
/**
35+
* Whether the storage is read-only.
36+
*/
3237
public bool $readonly = false,
38+
39+
/**
40+
* Identifier for this storage configuration.
41+
*/
42+
public null|string|UnitEnum $tag = null,
3343
) {}
3444

3545
public function createAdapter(): FilesystemAdapter

packages/storage/src/Config/GoogleCloudStorageConfig.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Google\Cloud\Storage\StorageClient;
66
use League\Flysystem\FilesystemAdapter;
77
use League\Flysystem\GoogleCloudStorage\GoogleCloudStorageAdapter;
8+
use UnitEnum;
89

910
final class GoogleCloudStorageConfig implements StorageConfig
1011
{
@@ -45,6 +46,11 @@ public function __construct(
4546
* Whether the storage is read-only.
4647
*/
4748
public bool $readonly = false,
49+
50+
/**
51+
* Identifier for this storage configuration.
52+
*/
53+
public null|string|UnitEnum $tag = null,
4854
) {}
4955

5056
public function createAdapter(): FilesystemAdapter

packages/storage/src/Config/InMemoryStorageConfig.php

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

55
use League\Flysystem\FilesystemAdapter;
66
use League\Flysystem\InMemory\InMemoryFilesystemAdapter;
7+
use UnitEnum;
78

89
final class InMemoryStorageConfig implements StorageConfig
910
{
@@ -14,6 +15,11 @@ public function __construct(
1415
* Whether the storage is read-only.
1516
*/
1617
public bool $readonly = false,
18+
19+
/**
20+
* Identifier for this storage configuration.
21+
*/
22+
public null|string|UnitEnum $tag = null,
1723
) {}
1824

1925
public function createAdapter(): FilesystemAdapter

packages/storage/src/Config/LocalStorageConfig.php

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

55
use League\Flysystem\FilesystemAdapter;
66
use League\Flysystem\Local\LocalFilesystemAdapter;
7+
use UnitEnum;
78

89
final class LocalStorageConfig implements StorageConfig
910
{
@@ -19,6 +20,11 @@ public function __construct(
1920
* Whether the storage is read-only.
2021
*/
2122
public bool $readonly = false,
23+
24+
/**
25+
* Identifier for this storage configuration.
26+
*/
27+
public null|string|UnitEnum $tag = null,
2228
) {}
2329

2430
public function createAdapter(): FilesystemAdapter

0 commit comments

Comments
 (0)