Completed
Pull Request — master (#337)
by Luc
16:16 queued 11:48
created

getDescriptionTranslatedClassName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace CultuurNet\UDB3\Event\ReadModel\JSONLD;
4
5
use Broadway\Domain\DomainMessage;
6
use Broadway\Domain\Metadata;
7
use Broadway\EventHandling\EventListenerInterface;
8
use CultuurNet\UDB3\Cdb\EventItemFactory;
9
use CultuurNet\UDB3\EntityNotFoundException;
10
use CultuurNet\UDB3\Event\Events\AudienceUpdated;
11
use CultuurNet\UDB3\Event\Events\BookingInfoUpdated;
12
use CultuurNet\UDB3\Event\Events\CalendarUpdated;
13
use CultuurNet\UDB3\Event\Events\ContactPointUpdated;
14
use CultuurNet\UDB3\Event\Events\DescriptionTranslated;
15
use CultuurNet\UDB3\Event\Events\DescriptionUpdated;
16
use CultuurNet\UDB3\Event\Events\EventCopied;
17
use CultuurNet\UDB3\Event\Events\EventCreated;
18
use CultuurNet\UDB3\Event\Events\EventDeleted;
19
use CultuurNet\UDB3\Event\Events\EventImportedFromUDB2;
20
use CultuurNet\UDB3\Event\Events\EventUpdatedFromUDB2;
21
use CultuurNet\UDB3\Event\Events\FacilitiesUpdated;
22
use CultuurNet\UDB3\Event\Events\ImageAdded;
23
use CultuurNet\UDB3\Event\Events\ImageRemoved;
24
use CultuurNet\UDB3\Event\Events\Image\ImagesImportedFromUDB2;
25
use CultuurNet\UDB3\Event\Events\Image\ImagesUpdatedFromUDB2;
26
use CultuurNet\UDB3\Event\Events\ImageUpdated;
27
use CultuurNet\UDB3\Event\Events\LabelAdded;
28
use CultuurNet\UDB3\Event\Events\LabelRemoved;
29
use CultuurNet\UDB3\Event\Events\LocationUpdated;
30
use CultuurNet\UDB3\Event\Events\MainImageSelected;
31
use CultuurNet\UDB3\Event\Events\MajorInfoUpdated;
32
use CultuurNet\UDB3\Event\Events\Moderation\Approved;
33
use CultuurNet\UDB3\Event\Events\Moderation\FlaggedAsDuplicate;
34
use CultuurNet\UDB3\Event\Events\Moderation\FlaggedAsInappropriate;
35
use CultuurNet\UDB3\Event\Events\Moderation\Published;
36
use CultuurNet\UDB3\Event\Events\Moderation\Rejected;
37
use CultuurNet\UDB3\Event\Events\OrganizerDeleted;
38
use CultuurNet\UDB3\Event\Events\OrganizerUpdated;
39
use CultuurNet\UDB3\Event\Events\PriceInfoUpdated;
40
use CultuurNet\UDB3\Event\Events\ThemeUpdated;
41
use CultuurNet\UDB3\Event\Events\TitleTranslated;
42
use CultuurNet\UDB3\Event\Events\TitleUpdated;
43
use CultuurNet\UDB3\Event\Events\TypeUpdated;
44
use CultuurNet\UDB3\Event\Events\TypicalAgeRangeDeleted;
45
use CultuurNet\UDB3\Event\Events\TypicalAgeRangeUpdated;
46
use CultuurNet\UDB3\Event\EventType;
47
use CultuurNet\UDB3\Event\ReadModel\DocumentGoneException;
48
use CultuurNet\UDB3\Event\ReadModel\DocumentRepositoryInterface;
49
use CultuurNet\UDB3\Event\EventServiceInterface;
50
use CultuurNet\UDB3\Event\ValueObjects\Audience;
51
use CultuurNet\UDB3\Event\ValueObjects\AudienceType;
52
use CultuurNet\UDB3\Iri\IriGeneratorInterface;
53
use CultuurNet\UDB3\Language;
54
use CultuurNet\UDB3\Offer\AvailableTo;
55
use CultuurNet\UDB3\Offer\IriOfferIdentifierFactoryInterface;
56
use CultuurNet\UDB3\Offer\ReadModel\JSONLD\OfferLDProjector;
57
use CultuurNet\UDB3\Offer\ReadModel\JSONLD\OfferUpdate;
58
use CultuurNet\UDB3\Offer\WorkflowStatus;
59
use CultuurNet\UDB3\Organizer\OrganizerProjectedToJSONLD;
60
use CultuurNet\UDB3\OrganizerService;
61
use CultuurNet\UDB3\Place\Events\PlaceProjectedToJSONLD;
62
use CultuurNet\UDB3\PlaceService;
63
use CultuurNet\UDB3\ReadModel\JsonDocument;
64
use CultuurNet\UDB3\ReadModel\JsonDocumentMetaDataEnricherInterface;
65
use CultuurNet\UDB3\RecordedOn;
66
use CultuurNet\UDB3\Theme;
67
use Symfony\Component\Serializer\SerializerInterface;
68
use ValueObjects\StringLiteral\StringLiteral;
69
use ValueObjects\Web\Url;
70
71
/**
72
 * Projects state changes on Event entities to a JSON-LD read model in a
73
 * document repository.
74
 *
75
 * Implements PlaceServiceInterface and OrganizerServiceInterface to do a double
76
 * dispatch with CdbXMLImporter.
77
 */
78
class EventLDProjector extends OfferLDProjector implements
79
    EventListenerInterface,
80
    PlaceServiceInterface,
81
    OrganizerServiceInterface
82
{
83
    /**
84
     * @var PlaceService
85
     */
86
    protected $placeService;
87
88
    /**
89
     * @var EventServiceInterface
90
     */
91
    protected $eventService;
92
93
    /**
94
     * @var IriOfferIdentifierFactoryInterface
95
     */
96
    protected $iriOfferIdentifierFactory;
97
98
    /**
99
     * @var CdbXMLImporter
100
     */
101
    protected $cdbXMLImporter;
102
103
    /**
104
     * @param DocumentRepositoryInterface $repository
105
     * @param IriGeneratorInterface $iriGenerator
106
     * @param EventServiceInterface $eventService
107
     * @param PlaceService $placeService
108
     * @param OrganizerService $organizerService
109
     * @param SerializerInterface $mediaObjectSerializer
110
     * @param IriOfferIdentifierFactoryInterface $iriOfferIdentifierFactory
111
     * @param CdbXMLImporter $cdbXMLImporter
112
     * @param JsonDocumentMetaDataEnricherInterface $jsonDocumentMetaDataEnricher
113
     */
114
    public function __construct(
115
        DocumentRepositoryInterface $repository,
116
        IriGeneratorInterface $iriGenerator,
117
        EventServiceInterface $eventService,
118
        PlaceService $placeService,
119
        OrganizerService $organizerService,
120
        SerializerInterface $mediaObjectSerializer,
121
        IriOfferIdentifierFactoryInterface $iriOfferIdentifierFactory,
122
        CdbXMLImporter $cdbXMLImporter,
123
        JsonDocumentMetaDataEnricherInterface $jsonDocumentMetaDataEnricher
124
    ) {
125
        parent::__construct(
126
            $repository,
127
            $iriGenerator,
128
            $organizerService,
129
            $mediaObjectSerializer,
130
            $jsonDocumentMetaDataEnricher
131
        );
132
133
        $this->placeService = $placeService;
134
        $this->eventService = $eventService;
135
        $this->cdbXMLImporter = $cdbXMLImporter;
136
137
        $this->iriOfferIdentifierFactory = $iriOfferIdentifierFactory;
138
    }
139
140
    /**
141
     * @param string $id
142
     * @return JsonDocument
143
     */
144 View Code Duplication
    protected function newDocument($id)
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...
145
    {
146
        $document = new JsonDocument($id);
147
148
        $offerLd = $document->getBody();
149
        $offerLd->{'@id'} = $this->iriGenerator->iri($id);
150
        $offerLd->{'@context'} = '/contexts/event';
151
152
        return $document->withBody($offerLd);
153
    }
154
155
    protected function applyOrganizerProjectedToJSONLD(OrganizerProjectedToJSONLD $organizerProjectedToJSONLD)
156
    {
157
        $eventIds = $this->eventsOrganizedByOrganizer(
158
            $organizerProjectedToJSONLD->getId()
159
        );
160
161
        $organizer = $this->organizerService->getEntity(
162
            $organizerProjectedToJSONLD->getId()
163
        );
164
165
        $documents = [];
166
167 View Code Duplication
        foreach ($eventIds as $eventId) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
168
            $document = $this->loadDocumentFromRepositoryByItemId(
169
                $eventId
170
            );
171
            $eventLD = $document->getBody();
172
173
            $newEventLD = clone $eventLD;
174
            $newEventLD->organizer = json_decode($organizer);
175
176
            if ($newEventLD != $eventLD) {
177
                $documents[] = $document->withBody($newEventLD);
178
            }
179
        }
180
181
        return $documents;
182
    }
183
184
    protected function applyPlaceProjectedToJSONLD(
185
        PlaceProjectedToJSONLD $placeProjectedToJSONLD
186
    ) {
187
        $identifier = $this->iriOfferIdentifierFactory->fromIri(
188
            Url::fromNative($placeProjectedToJSONLD->getIri())
189
        );
190
191
        $eventsLocatedAtPlace = $this->eventsLocatedAtPlace(
192
            $identifier->getId()
193
        );
194
195
        $placeJSONLD = $this->placeService->getEntity(
196
            $identifier->getId()
197
        );
198
199
        $documents = [];
200
201 View Code Duplication
        foreach ($eventsLocatedAtPlace as $eventId) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
202
            $document = $this->loadDocumentFromRepositoryByItemId(
203
                $eventId
204
            );
205
            $eventLD = $document->getBody();
206
207
            $newEventLD = clone $eventLD;
208
            $newEventLD->location = json_decode($placeJSONLD);
209
210
            if ($newEventLD != $eventLD) {
211
                $documents[] = $document->withBody($newEventLD);
212
            }
213
        }
214
215
        return $documents;
216
    }
217
218
    /**
219
     * @param string $organizerId
220
     * @return string[]
221
     */
222
    protected function eventsOrganizedByOrganizer($organizerId)
223
    {
224
        return $this->eventService->eventsOrganizedByOrganizer(
225
            $organizerId
226
        );
227
    }
228
229
    /**
230
     * @param string $placeId
231
     * @return string[]
232
     */
233
    protected function eventsLocatedAtPlace($placeId)
234
    {
235
        return $this->eventService->eventsLocatedAtPlace(
236
            $placeId
237
        );
238
    }
239
240
    /**
241
     * @param EventImportedFromUDB2 $eventImportedFromUDB2
242
     * @return JsonDocument
243
     */
244
    protected function applyEventImportedFromUDB2(
245
        EventImportedFromUDB2 $eventImportedFromUDB2
246
    ) {
247
        return $this->applyEventCdbXmlFromUDB2(
248
            $eventImportedFromUDB2->getEventId(),
249
            $eventImportedFromUDB2->getCdbXmlNamespaceUri(),
250
            $eventImportedFromUDB2->getCdbXml()
251
        );
252
    }
253
254
    /**
255
     * @param EventUpdatedFromUDB2 $eventUpdatedFromUDB2
256
     * @return JsonDocument
257
     */
258
    protected function applyEventUpdatedFromUDB2(
259
        EventUpdatedFromUDB2 $eventUpdatedFromUDB2
260
    ) {
261
        return $this->applyEventCdbXmlFromUDB2(
262
            $eventUpdatedFromUDB2->getEventId(),
263
            $eventUpdatedFromUDB2->getCdbXmlNamespaceUri(),
264
            $eventUpdatedFromUDB2->getCdbXml()
265
        );
266
    }
267
268
    /**
269
     * Helper function to save JSONLD document from entryapi cdbxml.
270
     *
271
     * @param string $eventId
272
     * @param string $cdbXmlNamespaceUri
273
     * @param string $cdbXml
274
     * @param DomainMessage $domainMessage
275
     * @return JsonDocument
276
     */
277
    protected function applyEventFromCdbXml(
278
        $eventId,
279
        $cdbXmlNamespaceUri,
280
        $cdbXml,
281
        $domainMessage
282
    ) {
283
        $document = $this->newDocument($eventId);
284
285
        $eventLd = $this->projectEventCdbXmlToObject(
286
            $document->getBody(),
287
            $eventId,
288
            $cdbXmlNamespaceUri,
289
            $cdbXml
290
        );
291
292
        // Add creation date and update date from domain message.
293
        $created = RecordedOn::fromDomainMessage($domainMessage);
294
        $eventLd->created = $created->toString();
295
        $eventLd->modified = $created->toString();
296
297
        // Add creator.
298
        $eventLd->creator = $this->getAuthorFromMetadata($domainMessage->getMetadata())->toNative();
299
300
        // Add publisher, which is the consumer name.
301
        $eventLd->publisher = $this->getConsumerFromMetadata($domainMessage->getMetadata())->toNative();
302
303
        return $document->withBody($eventLd);
304
    }
305
306
    /**
307
     * Helper function to save a JSON-LD document from cdbxml coming from UDB2.
308
     *
309
     * @param string $eventId
310
     * @param string $cdbXmlNamespaceUri
311
     * @param string $cdbXml
312
     *
313
     * @return JsonDocument
314
     */
315
    protected function applyEventCdbXmlFromUDB2(
316
        $eventId,
317
        $cdbXmlNamespaceUri,
318
        $cdbXml
319
    ) {
320
        $document = $this->newDocument($eventId);
321
322
        $eventLd = $this->projectEventCdbXmlToObject(
323
            $document->getBody(),
324
            $eventId,
325
            $cdbXmlNamespaceUri,
326
            $cdbXml
327
        );
328
329
        return $document->withBody($eventLd);
330
    }
331
332
    /**
333
     * @param \stdClass $jsonLd
334
     * @param string $eventId
335
     * @param string $cdbXmlNamespaceUri
336
     * @param string $cdbXml
337
     *
338
     * @return \stdClass
339
     */
340
    protected function projectEventCdbXmlToObject(
341
        \stdClass $jsonLd,
342
        $eventId,
343
        $cdbXmlNamespaceUri,
344
        $cdbXml
345
    ) {
346
        $udb2Event = EventItemFactory::createEventFromCdbXml(
347
            $cdbXmlNamespaceUri,
348
            $cdbXml
349
        );
350
351
        $jsonLd = $this->cdbXMLImporter->documentWithCdbXML(
352
            $jsonLd,
353
            $udb2Event,
354
            $this,
355
            $this,
356
            $this->slugger
357
        );
358
359
        $this->setMainLanguage($jsonLd, new Language('nl'));
360
361
        // Because we can not properly track media coming from UDB2 we simply
362
        // ignore it and give priority to content added through UDB3.
363
        // It's possible that an event has been deleted in udb3, but never
364
        // in udb2. If an update comes for that event from udb2, it should
365
        // be imported again. This is intended by design.
366
        // @see https://jira.uitdatabank.be/browse/III-1092
367
        try {
368
            $document = $this->loadDocumentFromRepositoryByItemId($eventId);
369
        } catch (DocumentGoneException $documentGoneException) {
370
            $document = $this->newDocument($eventId);
371
        }
372
373
        $media = $this->UDB3Media($document);
374
        if (!empty($media)) {
375
            $jsonLd->mediaObject = $media;
376
        }
377
378
        // Because UDB2 cannot keep track of UDB3 places as a location
379
        // ignore it and give priority to content added through UDB3.
380
        $location = $this->UDB3Location($document);
381
        if (!empty($location)) {
382
            $jsonLd->location = $location;
383
        }
384
385
        return $jsonLd;
386
    }
387
388
    /**
389
     * Return the media of an event if it already exists.
390
     *
391
     * @param JsonDocument $document The JsonDocument.
392
     *
393
     * @return array
394
     *  A list of media objects.
395
     */
396
    private function UDB3Media($document)
397
    {
398
        $media = [];
399
400
        if ($document) {
401
            $item = $document->getBody();
402
            // At the moment we do not include any media coming from UDB2.
403
            // If the mediaObject property contains data it's coming from UDB3.
404
            $item->mediaObject = isset($item->mediaObject) ? $item->mediaObject : [];
405
        }
406
407
        return $media;
408
    }
409
410
    /**
411
     * Return the location of an event if it already exists.
412
     *
413
     * @param JsonDocument $document The JsonDocument.
414
     *
415
     * @return array|null
416
     *  The location
417
     */
418
    private function UDB3Location($document)
419
    {
420
        $location = null;
421
422
        if ($document) {
423
            $item = $document->getBody();
424
            $location = isset($item->location) ? $item->location : null;
425
        }
426
427
        return $location;
428
    }
429
430
    /**
431
     * @param EventCreated $eventCreated
432
     * @param DomainMessage $domainMessage
433
     * @return JsonDocument
434
     */
435
    protected function applyEventCreated(
436
        EventCreated $eventCreated,
437
        DomainMessage $domainMessage
438
    ) {
439
        $document = $this->newDocument($eventCreated->getEventId());
440
        $jsonLD = $document->getBody();
441
442
        $jsonLD->{'@id'} = $this->iriGenerator->iri(
443
            $eventCreated->getEventId()
444
        );
445
446
        $this->setMainLanguage($jsonLD, new Language('nl'));
447
448
        $jsonLD->name['nl'] = $eventCreated->getTitle();
449
        $jsonLD->location = array(
450
                '@type' => 'Place',
451
            ) + (array)$this->placeJSONLD(
452
                $eventCreated->getLocation()->getCdbid()
453
            );
454
455
        $calendarJsonLD = $eventCreated->getCalendar()->toJsonLd();
456
        $jsonLD = (object)array_merge((array)$jsonLD, $calendarJsonLD);
457
458
        $availableTo = AvailableTo::createFromCalendar($eventCreated->getCalendar());
459
        $jsonLD->availableTo = (string)$availableTo;
460
461
        // Same as.
462
        $jsonLD->sameAs = $this->generateSameAs(
463
            $eventCreated->getEventId(),
464
            reset($jsonLD->name)
465
        );
466
467
        $eventType = $eventCreated->getEventType();
468
        $jsonLD->terms = [
469
            $eventType->toJsonLd(),
470
        ];
471
472
        $theme = $eventCreated->getTheme();
473
        if (!empty($theme)) {
474
            $jsonLD->terms[] = $theme->toJsonLd();
475
        }
476
477
        $created = RecordedOn::fromDomainMessage($domainMessage);
478
        $jsonLD->created = $created->toString();
479
        $jsonLD->modified = $created->toString();
480
481
        $metaData = $domainMessage->getMetadata()->serialize();
482 View Code Duplication
        if (isset($metaData['user_email'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
483
            $jsonLD->creator = $metaData['user_email'];
484
        } elseif (isset($metaData['user_nick'])) {
485
            $jsonLD->creator = $metaData['user_nick'];
486
        }
487
488
        $jsonLD->workflowStatus = WorkflowStatus::DRAFT()->getName();
489
490
        $defaultAudience = new Audience(AudienceType::EVERYONE());
491
        $jsonLD->audience = $defaultAudience->serialize();
492
493
        return $document->withBody($jsonLD);
494
    }
495
496
    /**
497
     * @param EventCopied $eventCopied
498
     * @param DomainMessage $domainMessage
499
     * @return JsonDocument
500
     */
501
    protected function applyEventCopied(
502
        EventCopied $eventCopied,
503
        DomainMessage $domainMessage
504
    ) {
505
        $originalDocument = $this->repository->get($eventCopied->getOriginalEventId());
506
        $eventJsonLD = $originalDocument->getBody();
507
508
        // Set the created and modified date.
509
        $created = RecordedOn::fromDomainMessage($domainMessage);
510
        $eventJsonLD->created = $created->toString();
511
        $eventJsonLD->modified = $created->toString();
512
513
        // Set the creator.
514
        $eventJsonLD->creator = $this->getAuthorFromMetadata($domainMessage->getMetadata())->toNative();
515
516
        // Set the id.
517
        $eventJsonLD->{'@id'} = $this->iriGenerator->iri($eventCopied->getItemId());
518
519
        // Set the new calendar.
520
        $eventJsonLD = (object) array_merge(
521
            (array) $eventJsonLD,
522
            $eventCopied->getCalendar()->toJsonLd()
523
        );
524
525
        // Set workflow status.
526
        $eventJsonLD->workflowStatus = WorkflowStatus::DRAFT()->getName();
527
528
        // Remove labels.
529
        unset($eventJsonLD->labels);
530
        unset($eventJsonLD->hiddenLabels);
531
532
        // Set available to and from.
533
        $availableTo = AvailableTo::createFromCalendar($eventCopied->getCalendar());
534
        $eventJsonLD->availableTo = (string) $availableTo;
535
        unset($eventJsonLD->availableFrom);
536
537
        $newDocument = new JsonDocument($eventCopied->getItemId());
538
        $newDocument = $newDocument->withBody($eventJsonLD);
539
        return $newDocument;
540
    }
541
542
    /**
543
     * @param EventDeleted $eventDeleted
544
     * @return null
545
     */
546 View Code Duplication
    protected function applyEventDeleted(EventDeleted $eventDeleted)
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...
547
    {
548
        $document = $this->loadDocumentFromRepository($eventDeleted);
549
550
        $jsonLD = $document->getBody();
551
552
        $jsonLD->workflowStatus = WorkflowStatus::DELETED()->getName();
553
554
        return $document->withBody($jsonLD);
555
    }
556
557
    /**
558
     * Apply the major info updated command to the projector.
559
     * @param MajorInfoUpdated $majorInfoUpdated
560
     * @return JsonDocument
561
     */
562
    protected function applyMajorInfoUpdated(MajorInfoUpdated $majorInfoUpdated)
563
    {
564
        $document = $this
565
            ->loadDocumentFromRepository($majorInfoUpdated)
566
            ->apply(OfferUpdate::calendar($majorInfoUpdated->getCalendar()));
0 ignored issues
show
Compatibility introduced by
$majorInfoUpdated->getCalendar() of type object<CultuurNet\UDB3\CalendarInterface> is not a sub-type of object<CultuurNet\UDB3\Calendar>. It seems like you assume a concrete implementation of the interface CultuurNet\UDB3\CalendarInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
567
568
        $jsonLD = $document->getBody();
569
570
        $jsonLD->name->nl = $majorInfoUpdated->getTitle();
571
        $jsonLD->location = array(
572
          '@type' => 'Place',
573
        ) + (array)$this->placeJSONLD($majorInfoUpdated->getLocation()->getCdbid());
574
575
        $availableTo = AvailableTo::createFromCalendar($majorInfoUpdated->getCalendar());
576
        $jsonLD->availableTo = (string)$availableTo;
577
578
        // Remove old theme and event type.
579
        $jsonLD->terms = array_filter($jsonLD->terms, function ($term) {
580
            return $term->domain !== EventType::DOMAIN &&  $term->domain !== Theme::DOMAIN;
581
        });
582
        $jsonLD->terms = array_values($jsonLD->terms);
583
584
        $eventType = $majorInfoUpdated->getEventType();
585
        $jsonLD->terms[] = $eventType->toJsonLd();
586
587
        $theme = $majorInfoUpdated->getTheme();
588
        if (!empty($theme)) {
589
            $jsonLD->terms[] = $theme->toJsonLd();
590
        }
591
592
        return $document->withBody($jsonLD);
593
    }
594
595
    /**
596
     * @param LocationUpdated $locationUpdated
597
     *
598
     * @return JsonDocument
599
     */
600
    public function applyLocationUpdated(LocationUpdated $locationUpdated)
601
    {
602
        $document = $this->loadDocumentFromRepository($locationUpdated);
603
604
        $jsonLD = $document->getBody();
605
606
        $jsonLD->location = [
607
            '@type' => 'Place',
608
         ] + (array) $this->placeJSONLD($locationUpdated->getLocationId()->toNative());
609
610
        return $document->withBody($jsonLD);
611
    }
612
613
    /**
614
     * @param AudienceUpdated $audienceUpdated
615
     * @return JsonDocument
616
     */
617
    protected function applyAudienceUpdated(AudienceUpdated $audienceUpdated)
618
    {
619
        $document = $this->loadDocumentFromRepository($audienceUpdated);
620
        $jsonLD = $document->getBody();
621
622
        $jsonLD->audience = $audienceUpdated->getAudience()->serialize();
623
624
        return $document->withBody($jsonLD);
625
    }
626
627
    /**
628
     * @inheritdoc
629
     */
630
    public function placeJSONLD($placeId)
631
    {
632
        if (empty($placeId)) {
633
            return array();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return array(); (array) is incompatible with the return type declared by the interface CultuurNet\UDB3\Event\Re...eInterface::placeJSONLD of type stdClass.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
634
        }
635
636
        try {
637
            $placeJSONLD = $this->placeService->getEntity(
638
                $placeId
639
            );
640
641
            return json_decode($placeJSONLD);
642
        } catch (EntityNotFoundException $e) {
643
            // In case the place can not be found at the moment, just add its ID
644
            return array(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return array('@id' => $t...ervice->iri($placeId)); (array<string,string>) is incompatible with the return type declared by the interface CultuurNet\UDB3\Event\Re...eInterface::placeJSONLD of type stdClass.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
645
                '@id' => $this->placeService->iri($placeId),
646
            );
647
        } catch (DocumentGoneException $e) {
648
            // In case the place can not be found at the moment, just add its ID
649
            return array(
0 ignored issues
show
Bug Best Practice introduced by
The return type of return array('@id' => $t...ervice->iri($placeId)); (array<string,string>) is incompatible with the return type declared by the interface CultuurNet\UDB3\Event\Re...eInterface::placeJSONLD of type stdClass.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
650
                '@id' => $this->placeService->iri($placeId),
651
            );
652
        }
653
    }
654
655
    private function generateSameAs($eventId, $name)
656
    {
657
        $eventSlug = $this->slugger->slug($name);
658
        return array(
659
            'http://www.uitinvlaanderen.be/agenda/e/' . $eventSlug . '/' . $eventId,
660
        );
661
    }
662
663 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...
664
    {
665
        $properties = $metadata->serialize();
666
667
        if (isset($properties['user_nick'])) {
668
            return new StringLiteral($properties['user_nick']);
669
        }
670
    }
671
672 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...
673
    {
674
        $properties = $metadata->serialize();
675
676
        if (isset($properties['consumer']['name'])) {
677
            return new StringLiteral($properties['consumer']['name']);
678
        }
679
    }
680
681
    /**
682
     * @return string
683
     */
684
    protected function getLabelAddedClassName()
685
    {
686
        return LabelAdded::class;
687
    }
688
689
    /**
690
     * @return string
691
     */
692
    protected function getLabelRemovedClassName()
693
    {
694
        return LabelRemoved::class;
695
    }
696
697
    /**
698
     * @return string
699
     */
700
    protected function getImageAddedClassName()
701
    {
702
        return ImageAdded::class;
703
    }
704
705
    /**
706
     * @return string
707
     */
708
    protected function getImageRemovedClassName()
709
    {
710
        return ImageRemoved::class;
711
    }
712
713
    /**
714
     * @return string
715
     */
716
    protected function getImageUpdatedClassName()
717
    {
718
        return ImageUpdated::class;
719
    }
720
721
    protected function getMainImageSelectedClassName()
722
    {
723
        return MainImageSelected::class;
724
    }
725
726
    /**
727
     * @return string
728
     */
729
    protected function getTitleTranslatedClassName()
730
    {
731
        return TitleTranslated::class;
732
    }
733
734
    /**
735
     * @return string
736
     */
737
    protected function getDescriptionTranslatedClassName()
738
    {
739
        return DescriptionTranslated::class;
740
    }
741
742
    /**
743
     * @return string
744
     */
745
    protected function getOrganizerUpdatedClassName()
746
    {
747
        return OrganizerUpdated::class;
748
    }
749
750
    /**
751
     * @return string
752
     */
753
    protected function getOrganizerDeletedClassName()
754
    {
755
        return OrganizerDeleted::class;
756
    }
757
758
    protected function getBookingInfoUpdatedClassName()
759
    {
760
        return BookingInfoUpdated::class;
761
    }
762
763
    /**
764
     * @return string
765
     */
766
    protected function getPriceInfoUpdatedClassName()
767
    {
768
        return PriceInfoUpdated::class;
769
    }
770
771
    protected function getContactPointUpdatedClassName()
772
    {
773
        return ContactPointUpdated::class;
774
    }
775
776
    protected function getDescriptionUpdatedClassName()
777
    {
778
        return DescriptionUpdated::class;
779
    }
780
781
    protected function getCalendarUpdatedClassName()
782
    {
783
        return CalendarUpdated::class;
784
    }
785
786
    protected function getTypicalAgeRangeUpdatedClassName()
787
    {
788
        return TypicalAgeRangeUpdated::class;
789
    }
790
791
    protected function getTypicalAgeRangeDeletedClassName()
792
    {
793
        return TypicalAgeRangeDeleted::class;
794
    }
795
796
    protected function getPublishedClassName()
797
    {
798
        return Published::class;
799
    }
800
801
    protected function getApprovedClassName()
802
    {
803
        return Approved::class;
804
    }
805
806
    protected function getRejectedClassName()
807
    {
808
        return Rejected::class;
809
    }
810
811
    protected function getFlaggedAsDuplicateClassName()
812
    {
813
        return FlaggedAsDuplicate::class;
814
    }
815
816
    protected function getFlaggedAsInappropriateClassName()
817
    {
818
        return FlaggedAsInappropriate::class;
819
    }
820
821
    protected function getImagesImportedFromUdb2ClassName()
822
    {
823
        return ImagesImportedFromUDB2::class;
824
    }
825
826
    protected function getImagesUpdatedFromUdb2ClassName()
827
    {
828
        return ImagesUpdatedFromUDB2::class;
829
    }
830
831
    protected function getTitleUpdatedClassName()
832
    {
833
        return TitleUpdated::class;
834
    }
835
836
    protected function getTypeUpdatedClassName()
837
    {
838
        return TypeUpdated::class;
839
    }
840
841
    protected function getThemeUpdatedClassName()
842
    {
843
        return ThemeUpdated::class;
844
    }
845
846
    protected function getFacilitiesUpdatedClassName()
847
    {
848
        return FacilitiesUpdated::class;
849
    }
850
}
851