Completed
Pull Request — master (#137)
by Sebastian
04:40
created

AggregateRoot::persist()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Spatie\EventProjector;
4
5
use Illuminate\Support\Str;
6
use Illuminate\Database\Eloquent\Model;
7
use Spatie\EventProjector\Models\StoredEvent;
8
9
abstract class AggregateRoot
10
{
11
    /** @var string */
12
    private $aggregate_uuid;
13
14
    /** @var array */
15
    private $recordedEvents = [];
16
17
    public static function retrieve(string $uuid): AggregateRoot
18
    {
19
        $aggregateRoot = (new static());
20
21
        $aggregateRoot->aggregate_uuid = $uuid;
22
23
        return $aggregateRoot->reconstituteFromEvents();
24
    }
25
26
    public function recordThat(ShouldBeStored $domainEvent): AggregateRoot
27
    {
28
        $this->recordedEvents[] = $domainEvent;
29
30
        $this->apply($domainEvent);
31
32
        return $this;
33
    }
34
35
    public function persist(): AggregateRoot
36
    {
37
        call_user_func(
38
            [config('event-projector.stored_event_model'), 'storeMany'],
39
            $this->getAndClearRecoredEvents(),
40
            $this->aggregate_uuid
41
        );
42
43
        return $this;
44
    }
45
46
    private function getAndClearRecoredEvents(): array
47
    {
48
        $recordedEvents = $this->recordedEvents;
49
50
        $this->recordedEvents = [];
51
52
        return $recordedEvents;
53
    }
54
55
    private function reconstituteFromEvents(): AggregateRoot
56
    {
57
        StoredEvent::uuid($this->aggregate_uuid)->each(function (StoredEvent $storedEvent) {
58
            $this->apply($storedEvent->event);
59
        });
60
61
        return $this;
62
    }
63
64
    private function apply(ShouldBeStored $event): void
65
    {
66
        $classBaseName = class_basename($event);
67
68
        $camelCasedBaseName = ucfirst(Str::camel($classBaseName));
69
70
        $applyingMethodName = "apply{$camelCasedBaseName}";
71
72
        if (method_exists($this, $applyingMethodName)) {
73
            $this->$applyingMethodName($event);
74
        }
75
    }
76
}
77