Completed
Push — master ( 5cda60...2b6dac )
by Constantin
06:34
created

ReadModelRecreator::setTaskProgressReporter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
/******************************************************************************
3
 * Copyright (c) 2016 Constantin Galbenu <[email protected]>             *
4
 ******************************************************************************/
5
6
namespace Gica\Cqrs\ReadModel;
7
8
9
use Gica\CodeAnalysis\MethodListenerDiscovery;
10
use Gica\CodeAnalysis\MethodListenerDiscovery\ListenerClassValidator\AnyPhpClassIsAccepted;
11
use Gica\CodeAnalysis\MethodListenerDiscovery\ListenerMethod;
12
use Gica\CodeAnalysis\Shared\ClassSorter\ByConstructorDependencySorter;
13
use Gica\Cqrs\Command\CodeAnalysis\ReadModelEventHandlerDetector;
14
use Gica\Cqrs\Event\EventWithMetaData;
15
use Gica\Cqrs\EventStore;
16
use Gica\Cqrs\ReadModel\ReadModelRecreator\TaskProgressCalculator;
17
use Gica\Cqrs\ReadModel\ReadModelRecreator\TaskProgressReporter;
18
use Psr\Log\LoggerInterface;
19
20
class ReadModelRecreator
21
{
22
23
    /**
24
     * @var EventStore
25
     */
26
    private $eventStore;
27
    /**
28
     * @var LoggerInterface
29
     */
30
    private $logger;
31
    /**
32
     * @var TaskProgressReporter|null
33
     */
34
    private $taskProgressReporter;
35
36 1
    public function __construct(
37
        EventStore $eventStore,
38
        LoggerInterface $logger
39
    )
40
    {
41 1
        $this->eventStore = $eventStore;
42 1
        $this->logger = $logger;
43 1
    }
44
45 1
    public function setTaskProgressReporter(?TaskProgressReporter $taskProgressReporter)
46
    {
47 1
        $this->taskProgressReporter = $taskProgressReporter;
48 1
    }
49
50 1
    public function recreateRead(ReadModelInterface $readModel)
51
    {
52 1
        $discoverer = new MethodListenerDiscovery(
53 1
            new ReadModelEventHandlerDetector(),
54 1
            new AnyPhpClassIsAccepted(),
55 1
            new ByConstructorDependencySorter()
56
        );
57
58 1
        $allMethods = $discoverer->findListenerMethodsInClass(get_class($readModel));
59
60 1
        $eventClasses = $this->getEventClassesFromMethods($allMethods);
61
62 1
        $this->logger->info(print_r($eventClasses, true));
63 1
        $this->logger->info("loading events...");
64
65 1
        $allEvents = $this->eventStore->loadEventsByClassNames($eventClasses);
66
67 1
        $this->logger->info("applying events...");
68
69 1
        $taskProgress = null;
70
71 1
        if ($this->taskProgressReporter) {
72 1
            $taskProgress = new TaskProgressCalculator($allEvents->countCommits());
73
        }
74
75 1
        foreach ($allEvents->fetchCommits() as $eventsCommit) {
76
77 1
            $eventsCommit = $eventsCommit->filterEventsByClass($eventClasses);
78
79 1
            foreach ($eventsCommit->getEventsWithMetadata() as $eventWithMetadata) {
80
                /** @var EventWithMetaData $eventWithMetadata */
81 1
                $methods = $this->findMethodsByEventClass(get_class($eventWithMetadata->getEvent()), $allMethods);
82
83 1
                foreach ($methods as $method) {
84 1
                    call_user_func([$readModel, $method->getMethodName()], $eventWithMetadata->getEvent(), $eventWithMetadata->getMetaData());
85
                }
86
            }
87
88 1
            if ($this->taskProgressReporter) {
89 1
                $taskProgress->increment();
90 1
                $this->taskProgressReporter->reportProgressUpdate($taskProgress->getStep(), $taskProgress->getTotalSteps(), $taskProgress->calculateSpeed(), $taskProgress->calculateEta());
91
            }
92
        }
93 1
    }
94
95
    /**
96
     * @param ListenerMethod[] $methods
97
     * @return array
98
     */
99 1
    private function getEventClassesFromMethods($methods)
100
    {
101 1
        $eventClasses = [];
102 1
        foreach ($methods as $listenerMethod) {
103 1
            $eventClasses[] = $listenerMethod->getEventClassName();
104
        }
105
106 1
        return $eventClasses;
107
    }
108
109
    /**
110
     * @param string $eventClass
111
     * @param ListenerMethod[] $allMethods
112
     * @return ListenerMethod[]
113
     */
114 1
    private function findMethodsByEventClass(string $eventClass, $allMethods)
115
    {
116 1
        $result = [];
117
118 1
        foreach ($allMethods as $listenerMethod) {
119 1
            if ($listenerMethod->getEventClassName() == $eventClass) {
120 1
                $result[] = $listenerMethod;
121
            }
122
        }
123
124 1
        return $result;
125
    }
126
}