Completed
Push — master ( c52105...217c2e )
by Constantin
12:35
created

InMemoryEventStore::constructKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
4
namespace Gica\Cqrs\EventStore\InMemory;
5
6
7
use Gica\Cqrs\Event;
8
use Gica\Cqrs\Event\EventWithMetaData;
9
use Gica\Cqrs\Event\MetaData;
10
use Gica\Cqrs\EventStore;
11
use Gica\Cqrs\EventStore\AggregateEventStream;
12
use Gica\Cqrs\EventStore\EventsCommit;
13
use Gica\Cqrs\EventStore\EventStreamGroupedByCommit;
14
use Gica\Cqrs\EventStore\Exception\ConcurrentModificationException;
15
use Gica\Iterator\IteratorTransformer\IteratorExpander;
16
17
class InMemoryEventStore implements EventStore
18
{
19
    /** @var EventsCommit[] */
20
    public $commitsByAggregate = [];
21
    private $versions = [];
22
    private $latestSequence = 0;
23
24 5
    public function loadEventsForAggregate(string $aggregateClass, $aggregateId): AggregateEventStream
25
    {
26 5
        return new InMemoryAggregateEventStream(
27 5
            $this->getEventsArrayForAggregate($aggregateClass, $aggregateId), $aggregateClass, $aggregateId, $this->latestSequence);
28
    }
29
30
    /**
31
     * @inheritdoc
32
     */
33 5
    public function appendEventsForAggregate($aggregateId, string $aggregateClass, $eventsWithMetaData, int $expectedVersion, int $expectedSequence)
34
    {
35 5
        if ($this->getAggregateVersion($aggregateClass, $aggregateId) != $expectedVersion) {
36 1
            throw new ConcurrentModificationException();
37
        }
38
39 5
        $this->appendEventsForAggregateWithoutChecking($aggregateId, $aggregateClass, $eventsWithMetaData, $expectedVersion, $expectedSequence);
40 5
    }
41
42 6
    public function appendEventsForAggregateWithoutChecking($aggregateId, $aggregateClass, $newEvents, int $expectedVersion, int $expectedSequence)
43
    {
44 6
        $this->addEventsToArrayForAggregate(
45
            $aggregateId,
46
            $aggregateClass,
47 6
            $this->decorateEventsWithMetadata($aggregateClass, $aggregateId, $newEvents),
48
            $expectedVersion,
49
            $expectedSequence
50
        );
51
52 6
        $constructKey = $this->constructKey($aggregateClass, $aggregateId);
53
54 6
        if (!isset($this->versions[$constructKey])) {
55 6
            $this->versions[$constructKey] = 0;
56
        }
57
58 6
        $this->versions[$constructKey]++;
59 6
        $this->latestSequence++;
60 6
    }
61
62 5
    private function getEventsArrayForAggregate(string $aggregateClass, $aggregateId)
63
    {
64 5
        $aggregateKey = $this->constructKey($aggregateClass, $aggregateId);
65
66 5
        return isset($this->commitsByAggregate[$aggregateKey])
67 3
            ? $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...
68 5
            : [];
69
    }
70
71 6
    private function addEventsToArrayForAggregate($aggregateId, $aggregateClass, $newEvents, int $expectedVersion, int $expectedSequence)
72
    {
73 6
        $this->commitsByAggregate[$this->constructKey($aggregateClass, $aggregateId)][] = new EventsCommit(
74
            $expectedSequence, $expectedVersion, $newEvents
75
        );
76 6
    }
77
78 1
    public function loadEventsByClassNames(array $eventClasses): EventStreamGroupedByCommit
79
    {
80
        $commits = iterator_to_array((new IteratorExpander(function ($aggregateCommits) {
81 1
            yield from $aggregateCommits;
82 1
        }))($this->commitsByAggregate));
83
84 1
        return new FilteredRawEventStreamGroupedByCommit($commits, $eventClasses);
85
    }
86
87 3
    private function extractEventsFromCommits(array $commits = [])
88
    {
89
        $eventsExtracter = new IteratorExpander(function (EventsCommit $commit) {
90 3
            yield from $commit->getEventsWithMetadata();
91 3
        });
92
93 3
        return iterator_to_array($eventsExtracter($commits));
94
    }
95
96 6
    public function getAggregateVersion(string $aggregateClass, $aggregateId)
97
    {
98 6
        $key = $this->constructKey($aggregateClass, $aggregateId);
99
100 6
        return isset($this->versions[$key]) ? $this->versions[$key] : 0;
101
    }
102
103
    /**
104
     * @param $aggregateClass
105
     * @param $aggregateId
106
     * @param Event[] $priorEvents
107
     * @return EventWithMetaData[]
108
     */
109
    public function decorateEventsWithMetadata($aggregateClass, $aggregateId, array $priorEvents)
110
    {
111 6
        return array_map(function ($event) use ($aggregateClass, $aggregateId) {
112 6
            if ($event instanceof EventWithMetaData) {
113 5
                return $event;
114
            }
115
116 2
            return new EventWithMetaData($event, new MetaData(
117 2
                $aggregateId, $aggregateClass, new \DateTimeImmutable(), null
118
            ));
119 6
        }, $priorEvents);
120
    }
121
122 3
    public function fetchLatestSequence(): int
123
    {
124 3
        return $this->latestSequence;
125
    }
126
127 8
    private function constructKey(string $aggregateClass, $aggregateId): string
128
    {
129 8
        return $aggregateClass . '_' . (string)$aggregateId;
130
    }
131
}