Skip to content
This repository has been archived by the owner on Sep 20, 2019. It is now read-only.

Add event_class_map for event class aliases #178

Merged
merged 6 commits into from
Jul 18, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

All notable changes to `laravel-event-projector` will be documented in this file

## x.x.x - 2019-xx-xx
- Added `event_class_map` to alias your event classes which allows for refactoring after events have been fired

## 2.6.3 - 2019-06-14

- fix warnings in console commands
Expand Down
7 changes: 7 additions & 0 deletions config/event-projector.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
*/
'stored_event_job' => \Spatie\EventProjector\HandleStoredEventJob::class,

/*
* Similar to Relation::morphMap() you can define which alias responds to which
* event class. This allows you to change the namespace or classnames
* of your events but still handle older events correctly.
*/
'event_class_map' => [],

/*
* This class is responsible for serializing events. By default an event will be serialized
* and stored as json. You can customize the class name. A valid serializer
Expand Down
7 changes: 7 additions & 0 deletions docs/installation-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ return [
* it should extend \Spatie\EventProjector\HandleDomainEventJob.
*/
'stored_event_job' => \Spatie\EventProjector\HandleStoredEventJob::class,

/*
* Similar to Relation::morphMap() you can define which alias responds to which
* event class. This allows you to change the namespace or classnames
* of your events but still handle older events correctly.
*/
'event_class_map' => [],

/*
* This class is responsible for serializing events. By default an event will be serialized
Expand Down
24 changes: 23 additions & 1 deletion src/Models/StoredEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Exception;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Spatie\EventProjector\ShouldBeStored;
Expand All @@ -27,7 +28,7 @@ public static function createForEvent(ShouldBeStored $event, string $uuid = null
{
$storedEvent = new static();
$storedEvent->aggregate_uuid = $uuid;
$storedEvent->event_class = get_class($event);
$storedEvent->event_class = self::getEventClass(get_class($event));
riasvdv marked this conversation as resolved.
Show resolved Hide resolved
$storedEvent->attributes['event_properties'] = app(EventSerializer::class)->serialize(clone $event);
$storedEvent->meta_data = [];
$storedEvent->created_at = Carbon::now();
Expand All @@ -37,6 +38,11 @@ public static function createForEvent(ShouldBeStored $event, string $uuid = null
return $storedEvent;
}

public function getEventClassAttribute(string $value): string
{
return self::getActualClassForEvent($value);
riasvdv marked this conversation as resolved.
Show resolved Hide resolved
}

public function getEventAttribute(): ShouldBeStored
{
try {
Expand Down Expand Up @@ -100,4 +106,20 @@ public static function store(ShouldBeStored $event, string $uuid = null): void
{
static::storeMany([$event], $uuid);
}

private static function getEventClass(string $class): string
riasvdv marked this conversation as resolved.
Show resolved Hide resolved
{
$map = config('event-projector.event_class_map', []);

if (! empty($map) && in_array($class, $map)) {
return array_search($class, $map, true);
}

return $class;
}

private static function getActualClassForEvent(string $class): string
riasvdv marked this conversation as resolved.
Show resolved Hide resolved
{
return Arr::get(config('event-projector.event_class_map', []), $class, $class);
}
}
21 changes: 21 additions & 0 deletions tests/EventSubscriberTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,27 @@ public function it_will_log_events_that_implement_ShouldBeStored()
$this->assertEquals($this->account->id, $storedEvent->event->account->id);
}

/** @test * */
public function it_will_log_events_that_implement_ShouldBeStored_with_a_map()
{
$this->setConfig('event-projector.event_class_map', [
'money_added' => MoneyAddedEvent::class,
]);

event(new MoneyAddedEvent($this->account, 1234));

$this->assertCount(1, StoredEvent::get());

$storedEvent = StoredEvent::first();

$this->assertEquals(MoneyAddedEvent::class, $storedEvent->event_class);
$this->assertEquals('money_added', $storedEvent->getAttributes()['event_class']);

$this->assertInstanceOf(MoneyAddedEvent::class, $storedEvent->event);
$this->assertEquals(1234, $storedEvent->event->amount);
$this->assertEquals($this->account->id, $storedEvent->event->account->id);
}

/** @test */
public function it_will_not_store_events_without_the_ShouldBeStored_interface()
{
Expand Down
13 changes: 13 additions & 0 deletions tests/Models/StoredEventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ public function it_will_throw_a_human_readable_exception_when_the_event_couldnt_
StoredEvent::first()->event;
}

/** @test * */
public function it_will_store_the_alias_when_a_classname_is_found_in_the_event_class_map()
{
$this->setConfig('event-projector.event_class_map', [
'money_added' => MoneyAddedEvent::class,
]);

$this->fireEvents();

$this->assertEquals(MoneyAddedEvent::class, StoredEvent::first()->event_class);
$this->assertEquals('money_added', StoredEvent::first()->getAttributes()['event_class']);
}

public function fireEvents(int $number = 1, string $className = MoneyAddedEvent::class)
{
foreach (range(1, $number) as $i) {
Expand Down