EventStore::verifyEventExistsForKey()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
crap 2
1
<?php
2
3
namespace Rawkode\Eidetic\EventStore;
4
5
use Rawkode\Eidetic\EventSourcing\EventSourcedEntity;
6
use Rawkode\Eidetic\EventSourcing\VerifyEventIsAClassTrait;
7
8
abstract class EventStore implements Serializer
9
{
10
    use EventPublisherMixin;
11
    use VerifyEventIsAClassTrait;
12
13
    // Subscriber hooks
14
    const TRANSACTION_STARTED = 'eidetic.eventstore.transaction_started';
15
    const TRANSACTION_COMPLETED = 'eidetic.eventstore.transaction_completed';
16
    const EVENT_PRE_STORE = 'eidetic.eventstore.event_pre_store';
17
    const EVENT_STORED = 'eidetic.eventstore.event_stored';
18
19
    /**
20
     * @param EventSourcedEntity $eventSourcedEntity
21
     *
22
     * @throws InvalidEventException
23
     */
24
    abstract protected function persist(EventSourcedEntity $eventSourcedEntity, $event);
25
26
    /**
27
     * Return all event log entries for $entityIdentifier.
28
     *
29
     * @param string $entityIdentifier
30
     *
31
     * @return array
32
     */
33
    abstract protected function eventLog($entityIdentifier);
34
35
    /**
36
     * @param EventSourcedEntity $eventSourcedEntity
37
     */
38
    abstract protected function startTransaction(EventSourcedEntity $eventSourcedEntity);
39
40
    /**
41
     * @param EventSourcedEntity $eventSourcedEntity
42
     */
43
    abstract protected function abortTransaction(EventSourcedEntity $eventSourcedEntity);
44
45
    /**
46
     * @param EventSourcedEntity $eventSourcedEntity
47
     */
48
    abstract protected function completeTransaction(EventSourcedEntity $eventSourcedEntity);
49
50
    /**
51
     * @param string $entityIdentifier
52
     *
53
     * @return int
54
     */
55
    abstract protected function countEntityEvents($entityIdentifier);
56
57
    /**
58
     * Returns the class associated with an entity identifier.
59
     *
60
     * @param string $entityIdentifier
61
     *
62
     * @return string
63
     */
64
    abstract public function entityClass($entityIdentifier);
65
66
    /** @var array */
67
    protected $stagedEvents = [];
68
69
    /** @var Serializer */
70
    protected $serializer;
71
72
    /**
73
     * Store an EventSourcedEntity's staged events.
74
     *
75
     * @param EventSourcedEntity $eventSourcedEntity
76
     */
77 14
    public function store(EventSourcedEntity $eventSourcedEntity)
78
    {
79
        try {
80 14
            $this->startTransaction($eventSourcedEntity);
81 14
            $this->publishAll(self::TRANSACTION_STARTED, $eventSourcedEntity);
82
83 14
            $this->enforceEventIntegrity($eventSourcedEntity);
84
85 14
            foreach ($eventSourcedEntity->stagedEvents() as $event) {
86 14
                $this->publishAll(self::EVENT_PRE_STORE, $eventSourcedEntity);
87 14
                $this->persist($eventSourcedEntity, $event);
88 14
                $this->publishAll(self::EVENT_STORED, $eventSourcedEntity);
89 14
            }
90 14
        } catch (\Exception $exception) {
91 2
            $this->abortTransaction($eventSourcedEntity);
92 2
            throw $exception;
93
        }
94
95 14
        $this->completeTransaction($eventSourcedEntity);
96 14
        $this->publishAll(self::TRANSACTION_COMPLETED, $eventSourcedEntity);
97 14
    }
98
99
    /**
100
     * @param EventSourcedEntity $eventSourcedEntity [description]
101
     *
102
     * @throws InvalidEventException
103
     */
104 14
    private function enforceEventIntegrity(EventSourcedEntity $eventSourcedEntity)
105
    {
106 14
        foreach ($eventSourcedEntity->stagedEvents() as $event) {
107 14
            $this->verifyEventIsAClass($event);
108 14
        }
109 14
    }
110
111
    /**
112
     * Returns all events for $entityIdentifier.
113
     *
114
     * @param string $entityIdentifier
115
     *
116
     * @return array
117
     */
118 4
    public function retrieve($entityIdentifier)
119
    {
120 4
        $eventLog = $this->eventLog($entityIdentifier);
121
122 2
        return array_map(function ($eventLogEntry) {
123 2
            return $eventLogEntry['event'];
124 2
        }, $eventLog);
125
    }
126
127
    /**
128
     * Returns all the log entries for $entityIdentifier.
129
     *
130
     * @param string $entityIdentifier
131
     *
132
     * @return array
133
     */
134 4
    public function retrieveLog($entityIdentifier)
135
    {
136 4
        return $this->eventLog($entityIdentifier);
137
    }
138
139
    /**
140
     * @param string $entityIdentifier
141
     *
142
     * @throws NoEventsFoundForKeyException
143
     */
144 8
    protected function verifyEventExistsForKey($entityIdentifier)
145
    {
146 8
        if (0 === $this->countEntityEvents($entityIdentifier)) {
147 3
            throw new NoEventsFoundForKeyException();
148
        }
149 5
    }
150
151
    /**
152
     * @param object $object
153
     *
154
     * @return string
155
     */
156 14
    public function serialize($object)
157
    {
158 14
        if (false === is_null($this->serializer)) {
159
            return $this->serializer->serialize($object);
160
        }
161
162 14
        return base64_encode(serialize($object));
163
    }
164
165
    /**
166
     * @param string $serializedObject
167
     *
168
     * @return object
169
     */
170 6
    public function unserialize($serializedObject)
171
    {
172 6
        if (false === is_null($this->serializer)) {
173
            return $this->serializer->serialize($serializedObject);
174
        }
175
176 6
        return unserialize(base64_decode($serializedObject));
177
    }
178
}
179