Completed
Push — master ( 0681f1...8d8a61 )
by Julián
11:46
created

AbstractAggregateRoot::applyAggregateEvent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
/*
4
 * event-sourcing (https://github.com/phpgears/event-sourcing).
5
 * Event Sourcing base.
6
 *
7
 * @license MIT
8
 * @link https://github.com/phpgears/event-sourcing
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
declare(strict_types=1);
13
14
namespace Gears\EventSourcing\Aggregate;
15
16
use Gears\Aggregate\EventBehaviour;
17
use Gears\EventSourcing\Aggregate\Exception\AggregateException;
18
use Gears\EventSourcing\Event\AggregateEvent;
19
use Gears\EventSourcing\Event\AggregateEventArrayCollection;
20
use Gears\EventSourcing\Event\AggregateEventCollection;
21
use Gears\Identity\Identity;
22
23
/**
24
 * Abstract aggregate root class.
25
 */
26
abstract class AbstractAggregateRoot implements AggregateRoot
27
{
28
    use AggregateBehaviour, EventBehaviour;
29
30
    /**
31
     * @var AggregateEvent[]
32
     */
33
    private $recordedAggregateEvents = [];
34
35
    /**
36
     * Prevent aggregate root direct instantiation.
37
     */
38
    final protected function __construct()
39
    {
40
        $this->version = 0;
41
    }
42
43
    /**
44
     * Set aggregate identity.
45
     *
46
     * @param Identity $identity
47
     */
48
    final protected function setIdentity(Identity $identity): void
49
    {
50
        $this->identity = $identity;
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    final public static function reconstituteFromAggregateEvents(AggregateEventCollection $events): self
57
    {
58
        $instance = new static();
59
        $instance->replayAggregateEvents($events);
60
61
        return $instance;
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     *
67
     * @throws AggregateException
68
     */
69
    final public function replayAggregateEvents(AggregateEventCollection $events): void
70
    {
71
        foreach ($events as $event) {
72
            $this->version = $event->getAggregateVersion();
73
74
            $this->applyAggregateEvent($event);
75
        }
76
    }
77
78
    /**
79
     * Record aggregate event.
80
     *
81
     * @param AggregateEvent $event
82
     *
83
     * @throws AggregateException
84
     */
85
    final protected function recordAggregateEvent(AggregateEvent $event): void
86
    {
87
        $this->version++;
88
89
        $this->recordedAggregateEvents[] = $event->withAggregateVersion($this->version);
90
91
        $this->applyAggregateEvent($event);
92
    }
93
94
    /**
95
     * Apply aggregate event.
96
     *
97
     * @param AggregateEvent $event
98
     *
99
     * @throws AggregateException
100
     */
101
    protected function applyAggregateEvent(AggregateEvent $event): void
102
    {
103
        $eventParts = \explode('\\', \ucfirst(\get_class($event)));
104
        $method = 'apply' . \end($eventParts);
105
106
        if (!\method_exists($this, $method)) {
107
            throw new AggregateException(\sprintf(
108
                'Aggregate event handling method %s for event %s does not exist',
109
                $method,
110
                \get_class($event)
111
            ));
112
        }
113
114
        $this->$method($event);
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    final public function getRecordedAggregateEvents(): AggregateEventCollection
121
    {
122
        return new AggregateEventArrayCollection($this->recordedAggregateEvents);
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    final public function clearRecordedAggregateEvents(): void
129
    {
130
        $this->recordedAggregateEvents = [];
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    final public function collectRecordedAggregateEvents(): AggregateEventCollection
137
    {
138
        $recordedEvents = new AggregateEventArrayCollection($this->recordedAggregateEvents);
139
140
        $this->recordedAggregateEvents = [];
141
142
        return $recordedEvents;
143
    }
144
}
145