Skip to content

Commit ca932e8

Browse files
committed
Add new #[SubscriptionId] attribute to replace SubscritionUtil trait
1 parent 6dc8a9f commit ca932e8

20 files changed

Lines changed: 284 additions & 122 deletions

infection.json.dist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
"mutators": {
1717
"@default": true
1818
},
19-
"minMsi": 72,
19+
"minMsi": 87,
2020
"minCoveredMsi": 87,
2121
"testFrameworkOptions": "--testsuite=unit"
2222
}

phpstan-baseline.neon

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,18 +156,18 @@ parameters:
156156
count: 1
157157
path: src/Subscription/Store/DoctrineSubscriptionStore.php
158158

159+
-
160+
message: '#^Trait Patchlevel\\EventSourcing\\Subscription\\Subscriber\\SubscriberUtil is used zero times and is not analysed\.$#'
161+
identifier: trait.unused
162+
count: 1
163+
path: src/Subscription/Subscriber/SubscriberUtil.php
164+
159165
-
160166
message: '#^Cannot cast mixed to string\.$#'
161167
identifier: cast.string
162168
count: 3
163169
path: src/Subscription/ThrowableToErrorContextTransformer.php
164170

165-
-
166-
message: '#^Property Patchlevel\\EventSourcing\\Tests\\Benchmark\\BasicImplementation\\ProfileWithCommands\:\:\$id is never read, only written\.$#'
167-
identifier: property.onlyWritten
168-
count: 1
169-
path: tests/Benchmark/BasicImplementation/ProfileWithCommands.php
170-
171171
-
172172
message: '#^Cannot access offset ''name'' on array\<string, mixed\>\|false\.$#'
173173
identifier: offsetAccess.nonOffsetAccessible
@@ -463,7 +463,7 @@ parameters:
463463
path: tests/Unit/Message/Translator/ReplaceEventTranslatorTest.php
464464

465465
-
466-
message: '#^Method class@anonymous/tests/Unit/Metadata/Subscriber/AttributeSubscriberMetadataFactoryTest\.php\:212\:\:profileVisited\(\) has parameter \$message with no type specified\.$#'
466+
message: '#^Method class@anonymous/tests/Unit/Metadata/Subscriber/AttributeSubscriberMetadataFactoryTest\.php\:290\:\:profileVisited\(\) has parameter \$message with no type specified\.$#'
467467
identifier: missingType.parameter
468468
count: 1
469469
path: tests/Unit/Metadata/Subscriber/AttributeSubscriberMetadataFactoryTest.php

src/Attribute/Processor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
final class Processor extends Subscriber
1212
{
1313
public function __construct(
14-
string $id,
14+
string|null $id = null,
1515
string $group = 'processor',
1616
RunMode $runMode = RunMode::FromNow,
1717
) {

src/Attribute/Projector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
final class Projector extends Subscriber
1212
{
1313
public function __construct(
14-
string $id,
14+
string|null $id = null,
1515
string $group = 'projector',
1616
RunMode $runMode = RunMode::FromBeginning,
1717
) {

src/Attribute/Subscriber.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
class Subscriber
1212
{
1313
public function __construct(
14-
public readonly string $id,
14+
public readonly string|null $id,
1515
public readonly RunMode $runMode,
1616
public readonly string $group = 'default',
1717
) {

src/Attribute/SubscriptionId.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Patchlevel\EventSourcing\Attribute;
6+
7+
use Attribute;
8+
9+
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
10+
final class SubscriptionId
11+
{
12+
}

src/Metadata/Subscriber/AttributeSubscriberMetadataFactory.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Patchlevel\EventSourcing\Attribute\Setup;
1010
use Patchlevel\EventSourcing\Attribute\Subscribe;
1111
use Patchlevel\EventSourcing\Attribute\Subscriber;
12+
use Patchlevel\EventSourcing\Attribute\SubscriptionId;
1213
use Patchlevel\EventSourcing\Attribute\Teardown;
1314
use ReflectionAttribute;
1415
use ReflectionClass;
@@ -17,6 +18,7 @@
1718

1819
use function array_key_exists;
1920
use function count;
21+
use function is_string;
2022

2123
final class AttributeSubscriberMetadataFactory implements SubscriberMetadataFactory
2224
{
@@ -38,6 +40,7 @@ public function metadata(string $subscriber): SubscriberMetadata
3840
throw new ClassIsNotASubscriber($subscriber);
3941
}
4042

43+
/** @var Subscriber $subscriberInfo */
4144
$subscriberInfo = $attributes[0]->newInstance();
4245

4346
$methods = $reflector->getMethods();
@@ -109,8 +112,35 @@ public function metadata(string $subscriber): SubscriberMetadata
109112
throw DuplicateSubscribeMethod::mixedWithAll($subscriber);
110113
}
111114

115+
$subscriptionId = $subscriberInfo->id;
116+
117+
foreach ($reflector->getReflectionConstants() as $constant) {
118+
if (!$constant->getAttributes(SubscriptionId::class)) {
119+
continue;
120+
}
121+
122+
$subscriptionIdValue = $constant->getValue();
123+
124+
if (!is_string($subscriptionIdValue)) {
125+
throw new SubscriptionIdWrongType($subscriber, $subscriptionIdValue);
126+
}
127+
128+
if ($subscriptionId !== null) {
129+
throw new SubscriberHasMultipleSubscriptionIds(
130+
$subscriber,
131+
[$subscriptionId, $subscriptionIdValue],
132+
);
133+
}
134+
135+
$subscriptionId = $subscriptionIdValue;
136+
}
137+
138+
if ($subscriptionId === null) {
139+
throw new SubscriptionIdMissing($subscriber);
140+
}
141+
112142
$metadata = new SubscriberMetadata(
113-
$subscriberInfo->id,
143+
$subscriptionId,
114144
$subscriberInfo->group,
115145
$subscriberInfo->runMode,
116146
$subscribeMethods,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Patchlevel\EventSourcing\Metadata\Subscriber;
6+
7+
use Patchlevel\EventSourcing\Metadata\MetadataException;
8+
9+
use function implode;
10+
use function sprintf;
11+
12+
final class SubscriberHasMultipleSubscriptionIds extends MetadataException
13+
{
14+
/**
15+
* @param class-string $subscriberClass
16+
* @param list<string> $ids
17+
*/
18+
public function __construct(string $subscriberClass, array $ids)
19+
{
20+
parent::__construct(
21+
sprintf(
22+
'There are multiple subscription ids (%s) defined for the subscriber "%s".',
23+
$subscriberClass,
24+
implode(', ', $ids),
25+
),
26+
);
27+
}
28+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Patchlevel\EventSourcing\Metadata\Subscriber;
6+
7+
use Patchlevel\EventSourcing\Metadata\MetadataException;
8+
9+
use function sprintf;
10+
11+
final class SubscriptionIdMissing extends MetadataException
12+
{
13+
/** @param class-string $subscriberClass */
14+
public function __construct(string $subscriberClass)
15+
{
16+
parent::__construct(
17+
sprintf(
18+
'There is no subscription id defined for the subscriber "%s". Define it via #[Subscriber] or #[SubscriptionId] attribute.',
19+
$subscriberClass,
20+
),
21+
);
22+
}
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Patchlevel\EventSourcing\Metadata\Subscriber;
6+
7+
use Patchlevel\EventSourcing\Metadata\MetadataException;
8+
9+
use function get_debug_type;
10+
use function sprintf;
11+
12+
final class SubscriptionIdWrongType extends MetadataException
13+
{
14+
/** @param class-string $subscriberClass */
15+
public function __construct(string $subscriberClass, mixed $subscriptionId)
16+
{
17+
parent::__construct(
18+
sprintf(
19+
'The subscription id defined for the subscriber "%s" has a wrong type. The Id needs to be a string, "%s" given.',
20+
$subscriberClass,
21+
get_debug_type($subscriptionId)
22+
),
23+
);
24+
}
25+
}

0 commit comments

Comments
 (0)