Completed
Push — master ( 34c2b4...7f9f5c )
by David
02:05
created

EventStore::verifyEventExistsForKey()   A

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 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4286
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 EVENT_STORED = 'eidetic.eventstore.event_stored';
15
16
    // Implement these in your concretion
17
18
    /**
19
     * @param EventSourcedEntity $eventSourcedEntity
20
     *
21
     * @throws InvalidEventException
22
     */
23
    abstract protected function persist(EventSourcedEntity $eventSourcedEntity);
24
25
    /**
26
     * Return all event log entries for $entityIdentifier.
27
     *
28
     * @param string $entityIdentifier
29
     *
30
     * @return array
31
     */
32
    abstract protected function eventLog($entityIdentifier);
33
34
    abstract protected function startTransaction();
35
    abstract protected function abortTransaction();
36
    abstract protected function completeTransaction();
37
38
    abstract protected function countEntityEvents($entityIdentifier);
39
40
    /**
41
     * Returns the class associated with an entity identifier.
42
     *
43
     * @param string $entityIdentifier
44
     *
45
     * @return string
46
     */
47
    abstract protected function entityClass($entityIdentifier);
48
49
    /** @var array */
50
    protected $stagedEvents = [];
51
52
    /** @var Serializer */
53
    protected $serializer;
54
55
    /**
56
     * Store an EventSourcedEntity's staged events.
57
     *
58
     * @param EventSourcedEntity $eventSourcedEntity
59
     */
60 14
    public function store(EventSourcedEntity $eventSourcedEntity)
61
    {
62
        try {
63 14
            $this->startTransaction();
64 14
            $this->enforceEventIntegrity($eventSourcedEntity);
65 14
            $this->persist($eventSourcedEntity);
66 14
        } catch (\Exception $exception) {
67 2
            $this->abortTransaction();
68 2
            throw $exception;
69
        }
70
71 14
        $this->completeTransaction();
72 14
    }
73
74
    /**
75
     * @param EventSourcedEntity $eventSourcedEntity [description]
76
     *
77
     * @throws InvalidEventException
78
     */
79 14
    private function enforceEventIntegrity(EventSourcedEntity $eventSourcedEntity)
80
    {
81 14
        foreach ($eventSourcedEntity->stagedEvents() as $event) {
82 14
            $this->verifyEventIsAClass($event);
83 14
        }
84 14
    }
85
86
    /**
87
     * Returns all events for $entityIdentifier.
88
     *
89
     * @param string $entityIdentifier
90
     *
91
     * @return array
92
     */
93 4
    public function retrieve($entityIdentifier)
94
    {
95 4
        $eventLog = $this->eventLog($entityIdentifier);
96
97 2
        return array_map(function ($eventLogEntry) {
98 2
            return $eventLogEntry['event'];
99 2
        }, $eventLog);
100
    }
101
102
    /**
103
     * Returns all the log entries for $entityIdentifier.
104
     *
105
     * @param string $entityIdentifier
106
     *
107
     * @return array
108
     */
109 4
    public function retrieveLog($entityIdentifier)
110
    {
111 4
        return $this->eventLog($entityIdentifier);
112
    }
113
114
    /**
115
     * @param string $entityIdentifier
116
     *
117
     * @throws NoEventsFoundForKeyException
118
     */
119 8
    protected function verifyEventExistsForKey($entityIdentifier)
120
    {
121 8
        if (0 === $this->countEntityEvents($entityIdentifier)) {
122 3
            throw new NoEventsFoundForKeyException();
123
        }
124 5
    }
125
126
    /**
127
     * @param object $object
128
     *
129
     * @return string
130
     */
131 14
    public function serialize($object)
132
    {
133 14
        if (false === is_null($this->serializer)) {
134
            return $this->serializer->serialize($object);
135
        }
136
137 14
        return base64_encode(serialize($object));
138
    }
139
140
    /**
141
     * @param string $serializedObject
142
     *
143
     * @return object
144
     */
145 6
    public function unserialize($serializedObject)
146
    {
147 6
        if (false === is_null($this->serializer)) {
148
            return $this->serializer->serialize($serializedObject);
149
        }
150
151 6
        return unserialize(base64_decode($serializedObject));
152
    }
153
}
154