Passed
Push — master ( cbefbc...3619f4 )
by Frank
16:49 queued 06:49
created

AggregateRootWithAggregates   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 54
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
eloc 18
c 3
b 0
f 1
dl 0
loc 54
rs 10
wmc 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A apply() 0 7 2
A unregisterAggregate() 0 4 2
A registerAggregate() 0 4 2
A eventRecorder() 0 7 2
A aggregatesInsideRoot() 0 7 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace EventSauce\EventSourcing;
6
7
use SplObjectStorage;
8
9
/**
10
 * @template T of EventSourcedAggregate
11
 */
12
trait AggregateRootWithAggregates
13
{
14
    use AggregateRootBehaviour, AggregateAppliesKnownEvents {
15
        AggregateAppliesKnownEvents::apply as applyOnAggregateRoot;
16
    }
17
18
    /**
19
     * @var ?SplObjectStorage<T>
20
     */
21
    private ?SplObjectStorage $aggregatesInsideRoot = null;
22
    private ?EventRecorder $eventRecorder = null;
23
24
    protected function eventRecorder(): EventRecorder
25
    {
26
        if (null === $this->eventRecorder) {
27
            $this->eventRecorder = new EventRecorder(fn (object $event) => $this->recordThat($event));
28
        }
29
30
        return $this->eventRecorder;
31
    }
32
33
    /**
34
     * @return SplObjectStorage<T>
35
     */
36
    private function aggregatesInsideRoot(): SplObjectStorage
37
    {
38
        if (null === $this->aggregatesInsideRoot) {
39
            $this->aggregatesInsideRoot = new SplObjectStorage();
40
        }
41
42
        return $this->aggregatesInsideRoot;
43
    }
44
45
    private function registerAggregate(?EventSourcedAggregate $aggregate): void
46
    {
47
        if ($aggregate instanceof EventSourcedAggregate) {
48
            $this->aggregatesInsideRoot()->attach($aggregate);
49
        }
50
    }
51
52
    private function unregisterAggregate(?EventSourcedAggregate $aggregate): void
53
    {
54
        if ($aggregate instanceof EventSourcedAggregate) {
55
            $this->aggregatesInsideRoot()->detach($aggregate);
56
        }
57
    }
58
59
    protected function apply(object $event): void
60
    {
61
        $this->applyOnAggregateRoot($event);
62
63
        /** @var EventSourcedAggregate $aggregate */
64
        foreach ($this->aggregatesInsideRoot() as $aggregate) {
65
            $aggregate->apply($event);
66
        }
67
    }
68
}
69