1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Spatie\EventSourcing; |
4
|
|
|
|
5
|
|
|
use Exception; |
6
|
|
|
use Illuminate\Contracts\Support\Arrayable; |
7
|
|
|
use Illuminate\Support\Arr; |
8
|
|
|
use Spatie\EventSourcing\EventSerializers\EventSerializer; |
9
|
|
|
use Spatie\EventSourcing\Exceptions\InvalidStoredEvent; |
10
|
|
|
use Spatie\EventSourcing\Facades\Projectionist; |
11
|
|
|
use Spatie\SchemalessAttributes\SchemalessAttributes; |
12
|
|
|
|
13
|
|
|
class StoredEvent implements Arrayable |
14
|
|
|
{ |
15
|
|
|
public ?int $id; |
|
|
|
|
16
|
|
|
|
17
|
|
|
/** @var array|string */ |
18
|
|
|
public $event_properties; |
19
|
|
|
|
20
|
|
|
public string $aggregate_uuid; |
21
|
|
|
|
22
|
|
|
public string $event_class; |
23
|
|
|
|
24
|
|
|
public SchemalessAttributes $meta_data; |
25
|
|
|
|
26
|
|
|
public string $created_at; |
27
|
|
|
|
28
|
|
|
public ?ShouldBeStored $event; |
29
|
|
|
|
30
|
|
|
public function __construct(array $data) |
31
|
|
|
{ |
32
|
|
|
$this->id = $data['id'] ?? null; |
33
|
|
|
$this->event_properties = $data['event_properties']; |
34
|
|
|
$this->aggregate_uuid = $data['aggregate_uuid']; |
35
|
|
|
$this->event_class = self::getActualClassForEvent($data['event_class']); |
36
|
|
|
$this->meta_data = $data['meta_data']; |
37
|
|
|
$this->created_at = $data['created_at']; |
38
|
|
|
|
39
|
|
|
try { |
40
|
|
|
$this->event = app(EventSerializer::class)->deserialize( |
41
|
|
|
self::getActualClassForEvent($this->event_class), |
42
|
|
|
is_string($this->event_properties) |
43
|
|
|
? $this->event_properties |
44
|
|
|
: json_encode($this->event_properties) |
45
|
|
|
); |
46
|
|
|
} catch (Exception $exception) { |
47
|
|
|
throw InvalidStoredEvent::couldNotUnserializeEvent($this, $exception); |
48
|
|
|
} |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
public function toArray() |
52
|
|
|
{ |
53
|
|
|
return [ |
54
|
|
|
'id' => $this->id, |
55
|
|
|
'event_properties' => $this->event_properties, |
56
|
|
|
'aggregate_uuid' => $this->aggregate_uuid, |
57
|
|
|
'event_class' => self::getEventClass($this->event_class), |
58
|
|
|
'meta_data' => $this->meta_data instanceof Arrayable ? $this->meta_data->toArray() : (array) $this->meta_data, |
59
|
|
|
'created_at' => $this->created_at, |
60
|
|
|
]; |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
public function handle() |
64
|
|
|
{ |
65
|
|
|
Projectionist::handleWithSyncProjectors($this); |
66
|
|
|
|
67
|
|
|
if (method_exists($this->event, 'tags')) { |
68
|
|
|
$tags = $this->event->tags(); |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
if (! $this->shouldDispatchJob()) { |
72
|
|
|
return; |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
$storedEventJob = call_user_func( |
76
|
|
|
[config('event-sourcing.stored_event_job'), 'createForEvent'], |
77
|
|
|
$this, |
78
|
|
|
$tags ?? [] |
79
|
|
|
); |
80
|
|
|
|
81
|
|
|
dispatch($storedEventJob->onQueue($this->event->queue ?? config('event-sourcing.queue'))); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
protected function shouldDispatchJob(): bool |
85
|
|
|
{ |
86
|
|
|
if (Projectionist::getAsyncProjectorsFor($this)->isNotEmpty()) { |
87
|
|
|
return true; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
if (Projectionist::getReactorsFor($this)->isNotEmpty()) { |
91
|
|
|
return true; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
return false; |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
protected static function getActualClassForEvent(string $class): string |
98
|
|
|
{ |
99
|
|
|
return Arr::get(config('event-sourcing.event_class_map', []), $class, $class); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
protected static function getEventClass(string $class): string |
103
|
|
|
{ |
104
|
|
|
$map = config('event-sourcing.event_class_map', []); |
105
|
|
|
|
106
|
|
|
if (! empty($map) && in_array($class, $map)) { |
107
|
|
|
return array_search($class, $map, true); |
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
return $class; |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
|