1 | <?php |
||
14 | trait HandlesEvents |
||
15 | { |
||
16 | public function handles(): array |
||
17 | { |
||
18 | return $this->getEventHandlingMethods()->keys()->toArray(); |
||
19 | } |
||
20 | |||
21 | public function handle(StoredEvent $storedEvent) |
||
22 | { |
||
23 | $eventClass = $storedEvent->event_class; |
||
24 | |||
25 | $handlerClassOrMethod = $this->getEventHandlingMethods()->get($eventClass); |
||
26 | |||
27 | $parameters = [ |
||
28 | 'event' => $storedEvent->event, |
||
29 | 'storedEvent' => $storedEvent, |
||
30 | 'aggregateUuid' => $storedEvent->aggregate_uuid, |
||
31 | ]; |
||
32 | |||
33 | if (class_exists($handlerClassOrMethod)) { |
||
34 | return app()->call([app($handlerClassOrMethod), '__invoke'], $parameters); |
||
35 | } |
||
36 | |||
37 | if (! method_exists($this, $handlerClassOrMethod)) { |
||
38 | throw InvalidEventHandler::eventHandlingMethodDoesNotExist($this, $storedEvent->event, $handlerClassOrMethod); |
||
39 | } |
||
40 | |||
41 | app()->call([$this, $handlerClassOrMethod], $parameters); |
||
42 | } |
||
43 | |||
44 | public function handleException(Exception $exception): void |
||
45 | { |
||
46 | report($exception); |
||
47 | } |
||
48 | |||
49 | public function getEventHandlingMethods(): Collection |
||
50 | { |
||
51 | if (! isset($this->handlesEvents) && ! isset($this->handleEvent)) { |
||
52 | return $this->autoDetectHandlesEvents(); |
||
53 | } |
||
54 | |||
55 | $handlesEvents = collect($this->handlesEvents ?? []) |
||
56 | ->mapWithKeys(function (string $handlerMethod, $eventClass) { |
||
57 | if (is_numeric($eventClass)) { |
||
58 | return [$handlerMethod => 'on'.ucfirst(class_basename($handlerMethod))]; |
||
59 | } |
||
60 | |||
61 | return [$eventClass => $handlerMethod]; |
||
62 | }); |
||
63 | |||
64 | if ($this->handleEvent ?? false) { |
||
65 | $handlesEvents->put($this->handleEvent, get_class($this)); |
||
66 | } |
||
67 | |||
68 | return $handlesEvents; |
||
69 | } |
||
70 | |||
71 | private function autoDetectHandlesEvents(): Collection |
||
72 | { |
||
73 | return collect((new ReflectionClass($this))->getMethods()) |
||
74 | ->flatMap(function (ReflectionMethod $method) { |
||
75 | $method = new ReflectionMethod($this, $method->name); |
||
76 | if (! $method->isPublic()) { |
||
77 | return; |
||
78 | } |
||
79 | |||
80 | $eventClass = collect($method->getParameters()) |
||
81 | ->map(fn(ReflectionParameter $parameter) => optional($parameter->getType())->getName()) |
||
|
|||
82 | ->first(fn($typeHint) => is_subclass_of($typeHint, ShouldBeStored::class)); |
||
83 | |||
84 | if (! $eventClass) { |
||
85 | return; |
||
86 | } |
||
87 | |||
88 | return [$eventClass => $method->name]; |
||
89 | }) |
||
90 | ->filter(); |
||
91 | } |
||
92 | } |
||
93 |