Completed
Push — master ( c23520...211db0 )
by
unknown
14s queued 11s
created

applyDescriptionTranslated()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.7998
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
namespace CultuurNet\UDB3\Offer\ReadModel\History;
4
5
use Broadway\Domain\DateTime;
6
use Broadway\Domain\DomainMessage;
7
use Broadway\Domain\Metadata;
8
use CultuurNet\UDB3\Event\ReadModel\DocumentRepositoryInterface;
9
use CultuurNet\UDB3\Event\ReadModel\History\Log;
10
use CultuurNet\UDB3\EventHandling\DelegateEventHandlingToSpecificMethodTrait;
11
use CultuurNet\UDB3\Offer\Events\AbstractDescriptionTranslated;
12
use CultuurNet\UDB3\Offer\Events\AbstractLabelAdded;
13
use CultuurNet\UDB3\Offer\Events\AbstractLabelRemoved;
14
use CultuurNet\UDB3\Offer\Events\AbstractTitleTranslated;
15
use CultuurNet\UDB3\ReadModel\JsonDocument;
16
use ValueObjects\StringLiteral\StringLiteral;
17
18
abstract class OfferHistoryProjector
19
{
20
    use DelegateEventHandlingToSpecificMethodTrait {
21
        DelegateEventHandlingToSpecificMethodTrait::handle as handleUnknownEvents;
22
    }
23
24
    /**
25
     * @var DocumentRepositoryInterface
26
     */
27
    private $documentRepository;
28
29
    public function __construct(DocumentRepositoryInterface $documentRepository)
30
    {
31
        $this->documentRepository = $documentRepository;
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function handle(DomainMessage $domainMessage)
38
    {
39
        $event = $domainMessage->getPayload();
40
41
        $eventName = get_class($event);
42
        $eventHandlers = $this->getEventHandlers();
43
44
        if (isset($eventHandlers[$eventName])) {
45
            $handler = $eventHandlers[$eventName];
46
            call_user_func(array($this, $handler), $event, $domainMessage);
47
        } else {
48
            $this->handleUnknownEvents($domainMessage);
49
        }
50
    }
51
52
    /**
53
     * @return string[]
54
     *   An associative array of commands and their handler methods.
55
     */
56
    protected function getEventHandlers()
57
    {
58
        $events = [];
59
60
        foreach (get_class_methods($this) as $method) {
61
            $matches = [];
62
63
            if (preg_match('/^apply(.+)$/', $method, $matches)) {
64
                $event = $matches[1];
65
                $classNameMethod = 'get' . $event . 'ClassName';
66
67
                if (method_exists($this, $classNameMethod)) {
68
                    $eventFullClassName = call_user_func(array($this, $classNameMethod));
69
                    $events[$eventFullClassName] = $method;
70
                }
71
            }
72
        }
73
74
        return $events;
75
    }
76
77
    /**
78
     * @return string
79
     */
80
    abstract protected function getLabelAddedClassName();
81
82
    /**
83
     * @return string
84
     */
85
    abstract protected function getLabelRemovedClassName();
86
87
    /**
88
     * @return string
89
     */
90
    abstract protected function getTitleTranslatedClassName();
91
92
    /**
93
     * @return string
94
     */
95
    abstract protected function getDescriptionTranslatedClassName();
96
97
    /**
98
     * @param AbstractLabelAdded $labelAdded
99
     * @param DomainMessage $domainMessage
100
     */
101
    protected function applyLabelAdded(
102
        AbstractLabelAdded $labelAdded,
103
        DomainMessage $domainMessage
104
    ) {
105
        $this->writeHistory(
106
            $labelAdded->getItemId(),
107
            new Log(
108
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
109
                new StringLiteral("Label '{$labelAdded->getLabel()}' toegepast"),
110
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
111
                $this->getApiKeyFromMetadata($domainMessage->getMetadata())
112
            )
113
        );
114
    }
115
116
    /**
117
     * @param AbstractLabelRemoved $labelRemoved
118
     * @param DomainMessage $domainMessage
119
     */
120
    protected function applyLabelRemoved(
121
        AbstractLabelRemoved $labelRemoved,
122
        DomainMessage $domainMessage
123
    ) {
124
        $this->writeHistory(
125
            $labelRemoved->getItemId(),
126
            new Log(
127
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
128
                new StringLiteral("Label '{$labelRemoved->getLabel()}' verwijderd"),
129
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
130
                $this->getApiKeyFromMetadata($domainMessage->getMetadata())
131
            )
132
        );
133
    }
134
135
    protected function applyTitleTranslated(
136
        AbstractTitleTranslated $titleTranslated,
137
        DomainMessage $domainMessage
138
    ) {
139
        $this->writeHistory(
140
            $titleTranslated->getItemId(),
141
            new Log(
142
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
143
                new StringLiteral("Titel vertaald ({$titleTranslated->getLanguage()})"),
144
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
145
                $this->getApiKeyFromMetadata($domainMessage->getMetadata())
146
            )
147
        );
148
    }
149
150
    protected function applyDescriptionTranslated(
151
        AbstractDescriptionTranslated $descriptionTranslated,
152
        DomainMessage $domainMessage
153
    ) {
154
        $this->writeHistory(
155
            $descriptionTranslated->getItemId(),
156
            new Log(
157
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
158
                new StringLiteral("Beschrijving vertaald ({$descriptionTranslated->getLanguage()})"),
159
                $this->getAuthorFromMetadata($domainMessage->getMetadata()),
160
                $this->getApiKeyFromMetadata($domainMessage->getMetadata())
161
            )
162
        );
163
    }
164
165
    /**
166
     * @param DateTime $date
167
     * @return \DateTime
168
     */
169
    protected function domainMessageDateToNativeDate(DateTime $date)
170
    {
171
        $dateString = $date->toString();
172
        return \DateTime::createFromFormat(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFor...T_STRING, $dateString); of type DateTime|false adds false to the return on line 172 which is incompatible with the return type documented by CultuurNet\UDB3\Offer\Re...MessageDateToNativeDate of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
173
            DateTime::FORMAT_STRING,
174
            $dateString
175
        );
176
    }
177
178
    /**
179
     * @param $dateString
180
     * @return \DateTime
181
     */
182
    protected function dateFromUdb2DateString($dateString)
183
    {
184
        return \DateTime::createFromFormat(
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression \DateTime::createFromFor...ne('Europe/Brussels')); of type DateTime|false adds false to the return on line 184 which is incompatible with the return type documented by CultuurNet\UDB3\Offer\Re...:dateFromUdb2DateString of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
185
            'Y-m-d?H:i:s',
186
            $dateString,
187
            new \DateTimeZone('Europe/Brussels')
188
        );
189
    }
190
191
    /**
192
     * @param Metadata $metadata
193
     * @return String|null
194
     */
195
    protected function getAuthorFromMetadata(Metadata $metadata)
196
    {
197
        $properties = $metadata->serialize();
198
199
        if (isset($properties['user_nick'])) {
200
            return new StringLiteral($properties['user_nick']);
201
        }
202
    }
203
204
    /**
205
     * @param Metadata $metadata
206
     * @return String|null
207
     */
208
    protected function getConsumerFromMetadata(Metadata $metadata)
209
    {
210
        $properties = $metadata->serialize();
211
212
        if (isset($properties['consumer']['name'])) {
213
            return new StringLiteral($properties['consumer']['name']);
214
        }
215
    }
216
217
    /**
218
     * @param string $eventId
219
     * @return JsonDocument
220
     */
221
    protected function loadDocumentFromRepositoryByEventId($eventId)
222
    {
223
        $historyDocument = $this->documentRepository->get($eventId);
224
225
        if (!$historyDocument) {
226
            $historyDocument = new JsonDocument($eventId, '[]');
227
        }
228
229
        return $historyDocument;
230
    }
231
232
    /**
233
     * @param string $eventId
234
     * @param Log[]|Log $logs
235
     */
236
    protected function writeHistory($eventId, $logs)
237
    {
238
        $historyDocument = $this->loadDocumentFromRepositoryByEventId($eventId);
239
240
        $history = $historyDocument->getBody();
241
242
        if (!is_array($logs)) {
243
            $logs = [$logs];
244
        }
245
246
        // Append most recent one to the top.
247
        foreach ($logs as $log) {
248
            array_unshift($history, $log);
249
        }
250
251
        $this->documentRepository->save(
252
            $historyDocument->withBody($history)
253
        );
254
    }
255
256
    protected function getApiKeyFromMetadata(Metadata $metadata): ?string
257
    {
258
        $properties = $metadata->serialize();
259
260
        if (isset($properties['auth_api_key'])) {
261
            return $properties['auth_api_key'];
262
        }
263
264
        return null;
265
    }
266
}
267