Passed
Push — master ( eaff52...7bdb3a )
by Mr
02:17
created

StandardProjector::handle()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 11
nc 4
nop 1
dl 0
loc 24
ccs 0
cts 15
cp 0
crap 12
rs 9.9
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
/**
3
 * This file is part of the daikon-cqrs/boot project.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Daikon\Boot\ReadModel;
10
11
use Daikon\EventSourcing\Aggregate\Event\DomainEventInterface;
12
use Daikon\EventSourcing\EventStore\Commit\CommitInterface;
13
use Daikon\Interop\Assertion;
14
use Daikon\MessageBus\EnvelopeInterface;
15
use Daikon\ReadModel\Projection\ProjectionInterface;
16
use Daikon\ReadModel\Projector\ProjectorInterface;
17
use Daikon\ReadModel\Repository\RepositoryInterface;
18
19
final class StandardProjector implements ProjectorInterface
20
{
21
    private RepositoryInterface $repository;
22
23
    public function __construct(RepositoryInterface $repository)
24
    {
25
        $this->repository = $repository;
26
    }
27
28
    public function handle(EnvelopeInterface $envelope): void
29
    {
30
        /** @var CommitInterface $commit */
31
        $commit = $envelope->getMessage();
32
        Assertion::implementsInterface($commit, CommitInterface::class);
33
34
        if ($commit->getSequence()->isInitial()) {
35
            $projection = $this->repository->makeProjection();
36
        } else {
37
            $aggregateId = (string)$commit->getAggregateId();
38
            $projection = $this->repository->findById($aggregateId)->getFirst();
39
        }
40
41
        Assertion::implementsInterface($projection, ProjectionInterface::class);
42
43
        /**
44
         * @var ProjectionInterface $projection
45
         * @var DomainEventInterface $event
46
         */
47
        foreach ($commit->getEventLog() as $event) {
48
            $projection = $projection->applyEvent($event);
49
        }
50
51
        $this->repository->persist($projection);
52
    }
53
}
54