Completed
Push — master ( 00f04e...1d93d6 )
by Freek
03:46
created

HandlesEvents::autoDetectHandlesEvents()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
cc 3
nc 1
nop 0
1
<?php
2
3
namespace Spatie\EventSourcing\EventHandlers;
4
5
use Exception;
6
use Illuminate\Support\Collection;
7
use ReflectionClass;
8
use ReflectionMethod;
9
use ReflectionParameter;
10
use Spatie\EventSourcing\Exceptions\InvalidEventHandler;
11
use Spatie\EventSourcing\ShouldBeStored;
12
use Spatie\EventSourcing\StoredEvent;
13
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())
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_VARIABLE, expecting ',' or ')'
Loading history...
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