InMemoryEventStore::getEventsArrayForAggregate()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 2
crap 2
1
<?php
2
3
4
namespace Gica\Cqrs\EventStore\InMemory;
5
6
7
use Gica\Cqrs\Event\EventWithMetaData;
8
use Gica\Cqrs\Event\MetaData;
9
use Gica\Cqrs\EventStore;
10
use Gica\Cqrs\EventStore\AggregateEventStream;
11
use Gica\Cqrs\EventStore\EventsCommit;
12
use Gica\Cqrs\EventStore\EventStreamGroupedByCommit;
13
use Gica\Cqrs\EventStore\Exception\ConcurrentModificationException;
14
use Gica\Iterator\IteratorTransformer\IteratorExpander;
15
16
class InMemoryEventStore implements EventStore
17
{
18
    /** @var EventsCommit[] */
19
    public $commitsByAggregate = [];
20
    private $versions = [];
21
    private $latestSequence = 0;
22
23 10
    public function loadEventsForAggregate(string $aggregateClass, $aggregateId): AggregateEventStream
24
    {
25 10
        return new InMemoryAggregateEventStream(
26 10
            $this->getEventsArrayForAggregate($aggregateClass, $aggregateId), $aggregateClass, $aggregateId, $this->latestSequence);
27
    }
28
29
    /**
30
     * @inheritdoc
31
     */
32 10
    public function appendEventsForAggregate($aggregateId, string $aggregateClass, $eventsWithMetaData, int $expectedVersion, int $expectedSequence)
33
    {
34 10
        if ($this->getAggregateVersion($aggregateClass, $aggregateId) != $expectedVersion) {
35 1
            throw new ConcurrentModificationException();
36
        }
37
38 10
        $this->appendEventsForAggregateWithoutChecking($aggregateId, $aggregateClass, $eventsWithMetaData, $expectedVersion, $expectedSequence);
39 10
    }
40
41 11
    public function appendEventsForAggregateWithoutChecking($aggregateId, $aggregateClass, $newEvents, int $expectedVersion, int $expectedSequence)
42
    {
43 11
        $this->addEventsToArrayForAggregate(
44 11
            $aggregateId,
45 11
            $aggregateClass,
46 11
            $this->decorateEventsWithMetadata($aggregateClass, $aggregateId, $newEvents),
47 11
            $expectedVersion,
48 11
            $expectedSequence
49
        );
50
51 11
        $constructKey = $this->constructKey($aggregateClass, $aggregateId);
52
53 11
        if (!isset($this->versions[$constructKey])) {
54 11
            $this->versions[$constructKey] = 0;
55
        }
56
57 11
        $this->versions[$constructKey]++;
58 11
        $this->latestSequence++;
59 11
    }
60
61 10
    private function getEventsArrayForAggregate(string $aggregateClass, $aggregateId)
62
    {
63 10
        $aggregateKey = $this->constructKey($aggregateClass, $aggregateId);
64
65 10
        return isset($this->commitsByAggregate[$aggregateKey])
66 6
            ? $this->extractEventsFromCommits($this->commitsByAggregate[$aggregateKey])
0 ignored issues
show
Documentation introduced by
$this->commitsByAggregate[$aggregateKey] is of type object<Gica\Cqrs\EventStore\EventsCommit>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
67 10
            : [];
68
    }
69
70 11
    private function addEventsToArrayForAggregate($aggregateId, $aggregateClass, $newEvents, int $expectedVersion, int $expectedSequence)
71
    {
72 11
        $this->commitsByAggregate[$this->constructKey($aggregateClass, $aggregateId)][] = new EventsCommit(
73 11
            $expectedSequence, $expectedVersion, $newEvents
74
        );
75 11
    }
76
77
    public function loadEventsByClassNames(array $eventClasses): EventStreamGroupedByCommit
78
    {
79 1
        $commits = iterator_to_array((new IteratorExpander(function ($aggregateCommits) {
80 1
            yield from $aggregateCommits;
81 1
        }))($this->commitsByAggregate));
82
83 1
        return new FilteredRawEventStreamGroupedByCommit($commits, $eventClasses);
84
    }
85
86
    private function extractEventsFromCommits(array $commits = [])
87
    {
88 6
        $eventsExtracter = new IteratorExpander(function (EventsCommit $commit) {
89 6
            yield from $commit->getEventsWithMetadata();
90 6
        });
91
92 6
        return iterator_to_array($eventsExtracter($commits));
93
    }
94
95 11
    public function getAggregateVersion(string $aggregateClass, $aggregateId)
96
    {
97 11
        $key = $this->constructKey($aggregateClass, $aggregateId);
98
99 11
        return isset($this->versions[$key]) ? $this->versions[$key] : 0;
100
    }
101
102
    /**
103
     * @param $aggregateClass
104
     * @param $aggregateId
105
     * @param $priorEvents
106
     * @return EventWithMetaData[]
107
     */
108
    public function decorateEventsWithMetadata($aggregateClass, $aggregateId, array $priorEvents)
109
    {
110 11
        return array_map(function ($event) use ($aggregateClass, $aggregateId) {
111 11
            if ($event instanceof EventWithMetaData) {
112 10
                return $event;
113
            }
114
115 5
            return new EventWithMetaData($event, new MetaData(
116 5
                $aggregateId,
117 5
                    $aggregateClass,
118 5
                    new \DateTimeImmutable(),
119 5
                    null
120
            ));
121 11
        }, $priorEvents);
122
    }
123
124 3
    public function fetchLatestSequence(): int
125
    {
126 3
        return $this->latestSequence;
127
    }
128
129 14
    private function constructKey(string $aggregateClass, $aggregateId): string
130
    {
131 14
        return $aggregateClass . '_' . (string)$aggregateId;
132
    }
133
134 1
    public function findEventById(string $eventId): ?EventWithMetaData
135
    {
136 1
        foreach($this->commitsByAggregate as $commits)
137
        {
138 1
            foreach($commits as $commit)
0 ignored issues
show
Bug introduced by
The expression $commits of type object<Gica\Cqrs\EventStore\EventsCommit> is not traversable.
Loading history...
139
            {
140
                /** @var \Gica\Cqrs\EventStore\EventsCommit $commit */
141
142 1
                foreach($commit->getEventsWithMetadata() as $eventWithMetadata)
143
                {
144 1
                    if($eventWithMetadata->getMetaData()->getEventId() === $eventId)
145
                    {
146 1
                        return $eventWithMetadata;
147
                    }
148
                }
149
            }
150
151
        }
152
153 1
        return null;
154
    }
155
}