Skip to content

Commit

Permalink
add event aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBadura committed Oct 5, 2024
1 parent 62fb244 commit 0810d4f
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 6 deletions.
25 changes: 25 additions & 0 deletions docs/pages/events.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,31 @@ final class ProfileCreated
* `profile.name_changed`
* `hotel.guest_checked_out`

## Alias

You also have the option to set aliases for the events.
This can be useful when you want to rename events but still need to process the old ones.

```php
use Patchlevel\EventSourcing\Attribute\Event;

#[Event(name: 'profile.registered', aliases: ['profile.created'])]
final class ProfileRegistered
{
}
```
When saving, the name will always be used. However, when loading, aliases will also be taken into account.

!!! note

In the database, the name of the event is always stored,
allowing the class to be renamed without encountering any issues.

!!! tip

If you want to make significant changes to an event,
you can take a look at the [Upcaster](upcasting.md).

## Serializer

So that the events can be saved in the database, they must be serialized and deserialized.
Expand Down
4 changes: 4 additions & 0 deletions docs/pages/upcasting.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ final class EventNameRenameUpcaster implements Upcaster
}
}
```
!!! tip

Events can also have [aliases](./events.md#alias). This is usually sufficient.

## Configure

After we have defined the upcasting rules, we also have to pass the whole thing to the serializer.
Expand Down
2 changes: 2 additions & 0 deletions src/Attribute/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ final class Event
{
public function __construct(
public readonly string $name,
/** @var list<string> */
public readonly array $aliases = [],
) {
}
}
1 change: 1 addition & 0 deletions src/Metadata/Event/AttributeEventMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public function metadata(string $event): EventMetadata
$this->eventMetadata[$event] = new EventMetadata(
$eventAttribute->name,
$this->splitStream($reflectionClass),
$eventAttribute->aliases,
);

return $this->eventMetadata[$event];
Expand Down
16 changes: 12 additions & 4 deletions src/Metadata/Event/AttributeEventRegistryFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,21 @@ public function create(array $paths): EventRegistry
continue;
}

$eventName = $attributes[0]->newInstance()->name;
$attribute = $attributes[0]->newInstance();

if (array_key_exists($eventName, $result)) {
throw new EventAlreadyInRegistry($eventName);
if (array_key_exists($attribute->name, $result)) {
throw new EventAlreadyInRegistry($attribute->name);
}

$result[$eventName] = $class;
$result[$attribute->name] = $class;

foreach ($attribute->aliases as $alias) {
if (array_key_exists($alias, $result)) {
throw new EventAlreadyInRegistry($alias);
}

$result[$alias] = $class;
}
}

return new EventRegistry($result);
Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/Event/EventMetadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ final class EventMetadata
public function __construct(
public readonly string $name,
public readonly bool $splitStream = false,
/** @var list<string> */
public readonly array $aliases = [],
) {
}
}
3 changes: 2 additions & 1 deletion src/Metadata/Event/EventRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use function array_flip;
use function array_key_exists;
use function array_reverse;

final class EventRegistry
{
Expand All @@ -19,7 +20,7 @@ final class EventRegistry
public function __construct(array $eventNameToClassMap)
{
$this->nameToClassMap = $eventNameToClassMap;
$this->classToNameMap = array_flip($eventNameToClassMap);
$this->classToNameMap = array_flip(array_reverse($eventNameToClassMap));
}

/** @param class-string $eventClass */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use Patchlevel\EventSourcing\Attribute\Event;
use Patchlevel\EventSourcing\Tests\Integration\BasicImplementation\ProfileId;

#[Event('profile.created')]
#[Event('profile.created', aliases: ['profile_was_created'])]
final class ProfileCreated
{
public function __construct(
Expand Down
19 changes: 19 additions & 0 deletions tests/Unit/Metadata/Event/EventRegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,25 @@ public function testMapping(): void
self::assertEquals([ProfileCreated::class => 'profile.created'], $registry->eventNames());
}

public function testMappingWithAliases(): void
{
$registry = new EventRegistry([
'profile.created' => ProfileCreated::class,
'profile.created_alias' => ProfileCreated::class,
]);

self::assertTrue($registry->hasEventClass(ProfileCreated::class));
self::assertTrue($registry->hasEventName('profile.created'));
self::assertEquals('profile.created', $registry->eventName(ProfileCreated::class));
self::assertEquals(ProfileCreated::class, $registry->eventClass('profile.created'));
self::assertEquals(ProfileCreated::class, $registry->eventClass('profile.created_alias'));
self::assertEquals([
'profile.created' => ProfileCreated::class,
'profile.created_alias' => ProfileCreated::class,
], $registry->eventClasses());
self::assertEquals([ProfileCreated::class => 'profile.created'], $registry->eventNames());
}

public function testEventClassNotRegistered(): void
{
$this->expectException(EventClassNotRegistered::class);
Expand Down

0 comments on commit 0810d4f

Please sign in to comment.