Completed
Pull Request — master (#103)
by Kristof
08:16
created

HistoryProjector::applyCollaborationDataAdded()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 22
rs 9.2
cc 1
eloc 15
nc 1
nop 2
1
<?php
2
/**
3
 * @file
4
 */
5
6
namespace CultuurNet\UDB3\Event\ReadModel\History;
7
8
use Broadway\Domain\DateTime;
9
use Broadway\Domain\DomainMessage;
10
use Broadway\Domain\Metadata;
11
use Broadway\EventHandling\EventListenerInterface;
12
use CultuurNet\UDB3\Cdb\EventItemFactory;
13
use CultuurNet\UDB3\Event\DescriptionTranslated;
14
use CultuurNet\UDB3\Event\Events\CollaborationDataAdded;
15
use CultuurNet\UDB3\Event\Events\EventCreatedFromCdbXml;
16
use CultuurNet\UDB3\Event\Events\EventImportedFromUDB2;
17
use CultuurNet\UDB3\Event\Events\EventUpdatedFromCdbXml;
18
use CultuurNet\UDB3\Event\Events\EventUpdatedFromUDB2;
19
use CultuurNet\UDB3\Event\Events\EventWasLabelled;
20
use CultuurNet\UDB3\Event\Events\TranslationApplied;
21
use CultuurNet\UDB3\Event\Events\LabelsMerged;
22
use CultuurNet\UDB3\Event\Events\TranslationDeleted;
23
use CultuurNet\UDB3\Event\Events\Unlabelled;
24
use CultuurNet\UDB3\Event\ReadModel\DocumentRepositoryInterface;
25
use CultuurNet\UDB3\Event\TitleTranslated;
26
use CultuurNet\UDB3\EventHandling\DelegateEventHandlingToSpecificMethodTrait;
27
use CultuurNet\UDB3\ReadModel\JsonDocument;
28
use ValueObjects\String\String;
29
30
class HistoryProjector implements EventListenerInterface
31
{
32
    use DelegateEventHandlingToSpecificMethodTrait;
33
34
    /**
35
     * @var DocumentRepositoryInterface
36
     */
37
    private $documentRepository;
38
39
    public function __construct(DocumentRepositoryInterface $documentRepository)
40
    {
41
        $this->documentRepository = $documentRepository;
42
    }
43
44
    private function applyEventImportedFromUDB2(
45
        EventImportedFromUDB2 $eventImportedFromUDB2,
46
        DomainMessage $domainMessage
47
    ) {
48
        $udb2Event = EventItemFactory::createEventFromCdbXml(
49
            $eventImportedFromUDB2->getCdbXmlNamespaceUri(),
50
            $eventImportedFromUDB2->getCdbXml()
51
        );
52
53
        $this->writeHistory(
54
            $eventImportedFromUDB2->getEventId(),
55
            new Log(
56
                $this->dateFromUdb2DateString(
57
                    $udb2Event->getCreationDate()
58
                ),
59
                new String('Aangemaakt in UDB2'),
60
                new String($udb2Event->getCreatedBy())
61
            )
62
        );
63
64
        $this->writeHistory(
65
            $eventImportedFromUDB2->getEventId(),
66
            new Log(
67
                $this->domainMessageDateToNativeDate(
68
                    $domainMessage->getRecordedOn()
69
                ),
70
                new String('Geïmporteerd vanuit UDB2')
71
            )
72
        );
73
    }
74
75 View Code Duplication
    private function applyEventCreatedFromCdbXml(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
76
        EventCreatedFromCdbXml $eventCreatedFromCdbXml,
77
        DomainMessage $domainMessage
78
    ) {
79
        $consumerName = $this->getConsumerFromMetadata($domainMessage->getMetadata());
80
81
        $this->writeHistory(
82
            $eventCreatedFromCdbXml->getEventId()->toNative(),
83
            new Log(
84
                $this->domainMessageDateToNativeDate(
85
                    $domainMessage->getRecordedOn()
86
                ),
87
                new String(
88
                    'Aangemaakt via EntryAPI door consumer "' . $consumerName . '"'
89
                ),
90
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
91
            )
92
        );
93
    }
94
95 View Code Duplication
    private function applyEventUpdatedFromCdbXml(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
        EventUpdatedFromCdbXml $eventUpdatedFromCdbXml,
97
        DomainMessage $domainMessage
98
    ) {
99
        $consumerName = $this->getConsumerFromMetadata($domainMessage->getMetadata());
100
101
        $this->writeHistory(
102
            $eventUpdatedFromCdbXml->getEventId()->toNative(),
103
            new Log(
104
                $this->domainMessageDateToNativeDate(
105
                    $domainMessage->getRecordedOn()
106
                ),
107
                new String(
108
                    'Geüpdatet via EntryAPI door consumer "' . $consumerName . '"'
109
                ),
110
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
111
            )
112
        );
113
    }
114
115
    /**
116
     * @param DateTime $date
117
     * @return \DateTime
118
     */
119
    private function domainMessageDateToNativeDate(DateTime $date)
120
    {
121
        $dateString = $date->toString();
122
        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 122 which is incompatible with the return type documented by CultuurNet\UDB3\Event\Re...MessageDateToNativeDate of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
123
            DateTime::FORMAT_STRING,
124
            $dateString
125
        );
126
    }
127
128
    /**
129
     * @param $dateString
130
     * @return \DateTime
131
     */
132
    private function dateFromUdb2DateString($dateString)
133
    {
134
        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 134 which is incompatible with the return type documented by CultuurNet\UDB3\Event\Re...:dateFromUdb2DateString of type DateTime. It seems like you forgot to handle an error condition.
Loading history...
135
            'Y-m-d?H:i:s',
136
            $dateString,
137
            new \DateTimeZone('Europe/Brussels')
138
        );
139
    }
140
141
    private function applyEventUpdatedFromUDB2(
142
        EventUpdatedFromUDB2 $eventUpdatedFromUDB2,
143
        DomainMessage $domainMessage
144
    ) {
145
        $this->writeHistory(
146
            $eventUpdatedFromUDB2->getEventId(),
147
            new Log(
148
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
149
                new String('Updatet vanuit UDB2')
150
            )
151
        );
152
    }
153
154
    /**
155
     * @param Metadata $metadata
156
     * @return String|null
157
     */
158 View Code Duplication
    private function getAuthorFromMetadata(Metadata $metadata)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
159
    {
160
        $properties = $metadata->serialize();
161
162
        if (isset($properties['user_nick'])) {
163
            return new String($properties['user_nick']);
164
        }
165
    }
166
167
    /**
168
     * @param Metadata $metadata
169
     * @return String|null
170
     */
171 View Code Duplication
    private function getConsumerFromMetadata(Metadata $metadata)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
172
    {
173
        $properties = $metadata->serialize();
174
175
        if (isset($properties['consumer']['name'])) {
176
            return new String($properties['consumer']['name']);
177
        }
178
    }
179
180 View Code Duplication
    private function applyEventWasLabelled(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
        EventWasLabelled $eventWasLabelled,
182
        DomainMessage $domainMessage
183
    ) {
184
        $this->writeHistory(
185
            $eventWasLabelled->getEventId(),
186
            new Log(
187
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
188
                new String("Label '{$eventWasLabelled->getLabel()}' toegepast"),
189
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
190
            )
191
        );
192
    }
193
194 View Code Duplication
    private function applyUnlabelled(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
195
        Unlabelled $unlabelled,
196
        DomainMessage $domainMessage
197
    ) {
198
        $this->writeHistory(
199
            $unlabelled->getEventId(),
200
            new Log(
201
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
202
                new String("Label '{$unlabelled->getLabel()}' verwijderd"),
203
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
204
            )
205
        );
206
    }
207
208
    /**
209
     * @param LabelsMerged $labelsMerged
210
     * @param DomainMessage $domainMessage
211
     */
212
    private function applyLabelsMerged(
213
        LabelsMerged $labelsMerged,
214
        DomainMessage $domainMessage
215
    ) {
216
        $labels = $labelsMerged->getLabels()->toStrings();
217
        // Quote labels.
218
        $quotedLabels = array_map(
219
            function ($label) {
220
                return "'{$label}'";
221
            },
222
            $labels
223
        );
224
        $quotedLabelsString = implode(', ', $quotedLabels);
225
226
        $message = "Labels {$quotedLabelsString} toegepast";
227
228
        $consumerName = $this->getConsumerFromMetadata($domainMessage->getMetadata());
229
230
        if ($consumerName) {
231
            $message .= ' via EntryAPI door consumer "' . $consumerName . '"';
232
        }
233
234
        $this->writeHistory(
235
            $labelsMerged->getEventId()->toNative(),
236
            new Log(
237
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
238
                new String($message),
239
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
240
            )
241
        );
242
    }
243
244 View Code Duplication
    private function applyTitleTranslated(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
245
        TitleTranslated $titleTranslated,
246
        DomainMessage $domainMessage
247
    ) {
248
        $this->writeHistory(
249
            $titleTranslated->getEventId(),
250
            new Log(
251
                $this->domainMessageDateToNativeDate($domainMessage->getRecordedOn()),
252
                new String("Titel vertaald ({$titleTranslated->getLanguage()})"),
253
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
254
            )
255
        );
256
    }
257
258 View Code Duplication
    private function applyDescriptionTranslated(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
259
        DescriptionTranslated $descriptionTranslated,
260
        DomainMessage $domainMessage
261
    ) {
262
        $this->writeHistory(
263
            $descriptionTranslated->getEventId(),
264
            new Log(
265
                $this->domainMessageDateToNativeDate(
266
                    $domainMessage->getRecordedOn()
267
                ),
268
                new String("Beschrijving vertaald ({$descriptionTranslated->getLanguage()})"),
269
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
270
            )
271
        );
272
    }
273
274
    private function applyTranslationApplied(
275
        TranslationApplied $translationApplied,
276
        DomainMessage $domainMessage
277
    ) {
278
        $fields = [];
279
280
        if ($translationApplied->getTitle() !== null) {
281
            $fields[] = 'titel';
282
        }
283
        if ($translationApplied->getShortDescription() !== null) {
284
            $fields[] = 'korte beschrijving';
285
        }
286
        if ($translationApplied->getLongDescription() !== null) {
287
            $fields[] = 'lange beschrijving';
288
        }
289
        $fieldString = ucfirst(implode(', ', $fields));
290
291
        $logMessage = "{$fieldString} vertaald ({$translationApplied->getLanguage()->getCode()})";
292
293
        $consumerName = $this->getConsumerFromMetadata($domainMessage->getMetadata());
294
        if ($consumerName) {
295
            $logMessage .= " via EntryAPI door consumer \"{$consumerName}\"";
296
        }
297
298
        $this->writeHistory(
299
            $translationApplied->getEventId()->toNative(),
300
            new Log(
301
                $this->domainMessageDateToNativeDate(
302
                    $domainMessage->getRecordedOn()
303
                ),
304
                new String($logMessage),
305
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
306
            )
307
        );
308
    }
309
310
    /**
311
     * @param TranslationDeleted $translationDeleted
312
     * @param DomainMessage $domainMessage
313
     */
314
    private function applyTranslationDeleted(
315
        TranslationDeleted $translationDeleted,
316
        DomainMessage $domainMessage
317
    ) {
318
        $message = "Vertaling verwijderd ({$translationDeleted->getLanguage()})";
319
320
        $consumerName = $this->getConsumerFromMetadata($domainMessage->getMetadata());
321
322
        if ($consumerName) {
323
            $message .= ' via EntryAPI door consumer "' . $consumerName . '"';
324
        }
325
326
        $this->writeHistory(
327
            $translationDeleted->getEventId()->toNative(),
328
            new Log(
329
                $this->domainMessageDateToNativeDate(
330
                    $domainMessage->getRecordedOn()
331
                ),
332
                new String($message),
333
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
334
            )
335
        );
336
    }
337
338
    /**
339
     * @param CollaborationDataAdded $collaborationDataAdded
340
     * @param DomainMessage $domainMessage
341
     */
342
    private function applyCollaborationDataAdded(
343
        CollaborationDataAdded $collaborationDataAdded,
344
        DomainMessage $domainMessage
345
    ) {
346
        $message = sprintf(
347
            'Collaboration data toegevoegd (%s) voor sub brand "%s" via EntryAPI door consumer "%s"',
348
            $collaborationDataAdded->getLanguage(),
349
            $collaborationDataAdded->getCollaborationData()->getSubBrand(),
350
            $this->getConsumerFromMetadata($domainMessage->getMetadata())
351
        );
352
353
        $this->writeHistory(
354
            $collaborationDataAdded->getEventId()->toNative(),
355
            new Log(
356
                $this->domainMessageDateToNativeDate(
357
                    $domainMessage->getRecordedOn()
358
                ),
359
                new String($message),
360
                $this->getAuthorFromMetadata($domainMessage->getMetadata())
0 ignored issues
show
Bug introduced by
It seems like $this->getAuthorFromMeta...Message->getMetadata()) targeting CultuurNet\UDB3\Event\Re...getAuthorFromMetadata() can also be of type object<ValueObjects\String\String>; however, CultuurNet\UDB3\Event\Re...tory\Log::__construct() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
361
            )
362
        );
363
    }
364
365
    /**
366
     * @param string $eventId
367
     * @return JsonDocument
368
     */
369
    private function loadDocumentFromRepositoryByEventId($eventId)
370
    {
371
        $historyDocument = $this->documentRepository->get($eventId);
372
373
        if (!$historyDocument) {
374
            $historyDocument = new JsonDocument($eventId, '[]');
375
        }
376
377
        return $historyDocument;
378
    }
379
380
    /**
381
     * @param string $eventId
382
     * @param Log[]|Log $logs
383
     */
384
    protected function writeHistory($eventId, $logs)
385
    {
386
        $historyDocument = $this->loadDocumentFromRepositoryByEventId($eventId);
387
388
        $history = $historyDocument->getBody();
389
390
        if (!is_array($logs)) {
391
            $logs = [$logs];
392
        }
393
394
        // Append most recent one to the top.
395
        foreach ($logs as $log) {
396
            array_unshift($history, $log);
397
        }
398
399
        $this->documentRepository->save(
400
            $historyDocument->withBody($history)
401
        );
402
    }
403
}
404