diff --git a/README.md b/README.md index d820075..0b5176f 100755 --- a/README.md +++ b/README.md @@ -12,6 +12,74 @@ You can install the package via composer: composer require digitalrisks/laravel-eventstore ``` +Add the base service provider for the package. + +``` php +getType();. + EventStore::eventToClass(); + + // You can customise this by doing the following. + EventStore::eventToClass(function ($event) { + return 'App\Events\\' . Str::studly($event->getType()); + }); + } + + /** + * Register the application services. + */ + public function register() + { + parent::register(); + } +} + +``` + +In your `config/app.php` file, add the following to the `providers` array. + +``` php + /* + |-------------------------------------------------------------------------- + | Autoloaded Service Providers + |-------------------------------------------------------------------------- + | + | The service providers listed here will be automatically loaded on the + | request to your application. Feel free to add your own services to + | this array to grant expanded functionality to your applications. + | + */ + + 'providers' => [ + ... + App\Providers\EventStoreServiceProvider::class, + ], +``` + ## Example Event ``` php @@ -92,6 +160,7 @@ Metadata can help trace events around your system. You can include any of the fo * `AddsHerokuMetadata` * `AddsLaravelMetadata` +* `AddsUserMetaData` Or you can define your own methods to collect metadata. Any method with the `@metadata` annotation will be called: @@ -225,23 +294,6 @@ return [ 'group' => 'account-email-subscription', 'volatile_streams' => ['quotes', 'accounts'], 'subscription_streams' => ['quotes', 'accounts'], - 'event_to_class' => function ($event) { - return 'App\Events\\' . $event->getType(); - } -]; -``` - -### Mapping events to Laravel Event Classes - -By default the event type will be used to create and fire a Laravel Event class. If your event types are named differently to your Laravel Event -Class names, you may specify a `event_to_class` callback in your configuration to return the appropriate class name. - -``` php -return [ - 'event_to_class' => function ($event) { - // map account_created to AccountCreated - return Str::studly($event->getType()); - } ]; ``` @@ -265,7 +317,9 @@ If you discover any security related issues, please email pawel.trauth@digitalri ## Credits -- [Pawel Trauth](https://github.com/digitalrisks) +- [Pawel Trauth](https://github.com/eithed) +- [Craig Morris](https://github.com/morrislaptop) +- [Kani Robinson](https://github.com/kanirobinson) - [All Contributors](../../contributors) ## License diff --git a/config/eventstore.php b/config/eventstore.php index 6daba20..f168546 100755 --- a/config/eventstore.php +++ b/config/eventstore.php @@ -6,7 +6,4 @@ 'subscription_streams' => array_filter(explode(',', env('EVENTSTORE_SUBSCRIPTION_STREAMS'))), 'volatile_streams' => array_filter(explode(',', env('EVENTSTORE_VOLATILE_STREAMS'))), 'group' => env('EVENTSTORE_SUBSCRIPTION_GROUP', env('APP_NAME', 'laravel')), - 'event_to_class' => function ($event) { - return 'App\Events\\' . $event->getType(); - } ]; diff --git a/src/Console/Commands/EventStoreWorker.php b/src/Console/Commands/EventStoreWorker.php index 73e554a..325afd7 100644 --- a/src/Console/Commands/EventStoreWorker.php +++ b/src/Console/Commands/EventStoreWorker.php @@ -3,15 +3,14 @@ namespace DigitalRisks\LaravelEventStore\Console\Commands; use DigitalRisks\LaravelEventStore\Contracts\CouldBeReceived; -use Illuminate\Console\Command; - -use Carbon\Carbon; +use DigitalRisks\LaravelEventStore\EventStore as LaravelEventStore; use EventLoop\EventLoop; +use Illuminate\Console\Command; use Illuminate\Support\Facades\Log; use ReflectionClass; use ReflectionProperty; -use Rxnet\EventStore\EventStore; use Rxnet\EventStore\Data\EventRecord as EventData; +use Rxnet\EventStore\EventStore; use Rxnet\EventStore\Record\AcknowledgeableEventRecord; use Rxnet\EventStore\Record\EventRecord; use Rxnet\EventStore\Record\JsonEventRecord; @@ -135,8 +134,7 @@ protected function safeGetMetadata(EventRecord $event) { try { return $event->getMetadata(); - } - catch (TypeError $e) { + } catch (TypeError $e) { return []; } } @@ -147,8 +145,7 @@ public function dispatch(EventRecord $eventRecord): void if ($localEvent = $this->mapToLocalEvent($event)) { event($localEvent); - } - else { + } else { event($event->getType(), $event); } } @@ -167,14 +164,18 @@ private function makeSerializableEvent(EventRecord $event): JsonEventRecord protected function mapToLocalEvent($event) { - $eventToClass = config('eventstore.event_to_class'); + $eventToClass = LaravelEventStore::$eventToClass; $className = $eventToClass ? $eventToClass($event) : 'App\Events\\' . $event->getType(); - if (! class_exists($className)) return; + if (!class_exists($className)) { + return; + } $reflection = new ReflectionClass($className); - if (! $reflection->implementsInterface(CouldBeReceived::class)) return; + if (!$reflection->implementsInterface(CouldBeReceived::class)) { + return; + } $localEvent = new $className(); $props = $reflection->getProperties(ReflectionProperty::IS_PUBLIC); diff --git a/src/EventStore.php b/src/EventStore.php new file mode 100644 index 0000000..bca3279 --- /dev/null +++ b/src/EventStore.php @@ -0,0 +1,28 @@ +getType(); + }; + + static::$eventToClass = $callback; + } +} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index bbb5acf..c2b9d73 100755 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -5,9 +5,10 @@ use DigitalRisks\LaravelEventStore\Console\Commands\EventStoreReset; use DigitalRisks\LaravelEventStore\Console\Commands\EventStoreWorker; use DigitalRisks\LaravelEventStore\Contracts\ShouldBeStored; +use DigitalRisks\LaravelEventStore\EventStore; use DigitalRisks\LaravelEventStore\Listeners\SendToEventStoreListener; -use Illuminate\Support\ServiceProvider as LaravelServiceProvider; use Illuminate\Support\Facades\Event; +use Illuminate\Support\ServiceProvider as LaravelServiceProvider; class ServiceProvider extends LaravelServiceProvider { @@ -16,9 +17,10 @@ class ServiceProvider extends LaravelServiceProvider */ public function boot() { + $this->eventClasses(); if ($this->app->runningInConsole()) { $this->publishes([ - __DIR__.'/../config/eventstore.php' => config_path('eventstore.php'), + __DIR__ . '/../config/eventstore.php' => config_path('eventstore.php'), ], 'config'); $this->commands([ @@ -30,12 +32,26 @@ public function boot() Event::listen(ShouldBeStored::class, SendToEventStoreListener::class); } + /** + * Set the eventToClass method. + * + * @return void + */ + public function eventClasses() + { + EventStore::eventToClass(); + } + /** * Register the application services. */ public function register() { // Automatically apply the package configuration - $this->mergeConfigFrom(__DIR__.'/../config/eventstore.php', 'eventstore'); + $this->mergeConfigFrom(__DIR__ . '/../config/eventstore.php', 'eventstore'); + + $this->app->singleton(EventStore::class, function () { + return new EventStore; + }); } } diff --git a/src/Traits/AddsUserMetaData.php b/src/Traits/AddsUserMetaData.php new file mode 100644 index 0000000..5ec4626 --- /dev/null +++ b/src/Traits/AddsUserMetaData.php @@ -0,0 +1,22 @@ +user(); + + if (!$user) { + return []; + } + + return [ + 'user' => $user->toArray() + ]; + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index cd53997..70effd0 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -2,13 +2,16 @@ namespace DigitalRisks\LaravelEventStore\Tests; -use Orchestra\Testbench\TestCase as Orchestra; +use DigitalRisks\LaravelEventStore\EventStore; use DigitalRisks\LaravelEventStore\ServiceProvider; +use Orchestra\Testbench\TestCase as Orchestra; class TestCase extends Orchestra { protected function getPackageProviders($app) { + EventStore::eventToClass(); + return [ ServiceProvider::class, ]; diff --git a/tests/WorkerTest.php b/tests/WorkerTest.php index 3ddf8dd..75f28b0 100644 --- a/tests/WorkerTest.php +++ b/tests/WorkerTest.php @@ -3,11 +3,12 @@ namespace DigitalRisks\LaravelEventStore\Tests; use DigitalRisks\LaravelEventStore\Console\Commands\EventStoreWorker; +use DigitalRisks\LaravelEventStore\EventStore; +use DigitalRisks\LaravelEventStore\Tests\Fixtures\TestEvent; use DigitalRisks\LaravelEventStore\Tests\Traits\InteractsWithEventStore; use DigitalRisks\LaravelEventStore\Tests\Traits\MakesEventRecords; use Illuminate\Support\Facades\Event; use Rxnet\EventStore\Record\EventRecord; -use DigitalRisks\LaravelEventStore\Tests\Fixtures\TestEvent; class WorkerTest extends TestCase { @@ -37,11 +38,10 @@ public function test_it_dispatches_a_classed_event_from_a_subscribed_event() Event::fake(); $worker = resolve(EventStoreWorker::class); $event = $this->makeEventRecord('test_event', ['hello' => 'world']); - config([ - 'eventstore.event_to_class' => function ($event) { - return 'DigitalRisks\LaravelEventStore\Tests\Fixtures\TestEvent'; - } - ]); + + EventStore::eventToClass(function ($event) { + return 'DigitalRisks\LaravelEventStore\Tests\Fixtures\TestEvent'; + }); // Act. $worker->dispatch($event);