Completed
Push — master ( f36eb7...96a58d )
by
unknown
36s
created

EventLDProjector::getPriceInfoUpdatedClassName()   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\GeoCoordinatesUpdated;
23
use CultuurNet\UDB3\Event\Events\ImageAdded;
24
use CultuurNet\UDB3\Event\Events\ImageRemoved;
25
use CultuurNet\UDB3\Event\Events\Image\ImagesImportedFromUDB2;
26
use CultuurNet\UDB3\Event\Events\Image\ImagesUpdatedFromUDB2;
27
use CultuurNet\UDB3\Event\Events\ImageUpdated;
28
use CultuurNet\UDB3\Event\Events\LabelAdded;
29
use CultuurNet\UDB3\Event\Events\LabelRemoved;
30
use CultuurNet\UDB3\Event\Events\LocationUpdated;
31
use CultuurNet\UDB3\Event\Events\MainImageSelected;
32
use CultuurNet\UDB3\Event\Events\MajorInfoUpdated;
33
use CultuurNet\UDB3\Event\Events\Moderation\Approved;
34
use CultuurNet\UDB3\Event\Events\Moderation\FlaggedAsDuplicate;
35
use CultuurNet\UDB3\Event\Events\Moderation\FlaggedAsInappropriate;
36
use CultuurNet\UDB3\Event\Events\Moderation\Published;
37
use CultuurNet\UDB3\Event\Events\Moderation\Rejected;
38
use CultuurNet\UDB3\Event\Events\OrganizerDeleted;
39
use CultuurNet\UDB3\Event\Events\OrganizerUpdated;
40
use CultuurNet\UDB3\Event\Events\PriceInfoUpdated;
41
use CultuurNet\UDB3\Event\Events\ThemeUpdated;
42
use CultuurNet\UDB3\Event\Events\TitleTranslated;
43
use CultuurNet\UDB3\Event\Events\TitleUpdated;
44
use CultuurNet\UDB3\Event\Events\TypeUpdated;
45
use CultuurNet\UDB3\Event\Events\TypicalAgeRangeDeleted;
46
use CultuurNet\UDB3\Event\Events\TypicalAgeRangeUpdated;
47
use CultuurNet\UDB3\Event\EventType;
48
use CultuurNet\UDB3\Event\ReadModel\DocumentGoneException;
49
use CultuurNet\UDB3\Event\ReadModel\DocumentRepositoryInterface;
50
use CultuurNet\UDB3\Event\EventServiceInterface;
51
use CultuurNet\UDB3\Event\ValueObjects\Audience;
52
use CultuurNet\UDB3\Event\ValueObjects\AudienceType;
53
use CultuurNet\UDB3\EventListener\EventSpecification;
54
use CultuurNet\UDB3\Iri\IriGeneratorInterface;
55
use CultuurNet\UDB3\Language;
56
use CultuurNet\UDB3\Offer\AvailableTo;
57
use CultuurNet\UDB3\Offer\IriOfferIdentifierFactoryInterface;
58
use CultuurNet\UDB3\Offer\ReadModel\JSONLD\OfferLDProjector;
59
use CultuurNet\UDB3\Offer\ReadModel\JSONLD\OfferUpdate;
60
use CultuurNet\UDB3\Offer\WorkflowStatus;
61
use CultuurNet\UDB3\Organizer\OrganizerProjectedToJSONLD;
62
use CultuurNet\UDB3\OrganizerService;
63
use CultuurNet\UDB3\Place\Events\PlaceProjectedToJSONLD;
64
use CultuurNet\UDB3\PlaceService;
65
use CultuurNet\UDB3\ReadModel\JsonDocument;
66
use CultuurNet\UDB3\ReadModel\JsonDocumentMetaDataEnricherInterface;
67
use CultuurNet\UDB3\RecordedOn;
68
use CultuurNet\UDB3\Theme;
69
use Symfony\Component\Serializer\SerializerInterface;
70
use ValueObjects\StringLiteral\StringLiteral;
71
use ValueObjects\Web\Url;
72
73
/**
74
 * Projects state changes on Event entities to a JSON-LD read model in a
75
 * document repository.
76
 *
77
 * Implements PlaceServiceInterface and OrganizerServiceInterface to do a double
78
 * dispatch with CdbXMLImporter.
79
 */
80
class EventLDProjector extends OfferLDProjector implements
81
    EventListenerInterface,
82
    PlaceServiceInterface,
83
    OrganizerServiceInterface
84
{
85
    /**
86
     * @var PlaceService
87
     */
88
    protected $placeService;
89
90
    /**
91
     * @var EventServiceInterface
92
     */
93
    protected $eventService;
94
95
    /**
96
     * @var IriOfferIdentifierFactoryInterface
97
     */
98
    protected $iriOfferIdentifierFactory;
99
100
    /**
101
     * @var CdbXMLImporter
102
     */
103
    protected $cdbXMLImporter;
104
105
    /**
106
     * @param DocumentRepositoryInterface $repository
107
     * @param IriGeneratorInterface $iriGenerator
108
     * @param EventServiceInterface $eventService
109
     * @param PlaceService $placeService
110
     * @param OrganizerService $organizerService
111
     * @param SerializerInterface $mediaObjectSerializer
112
     * @param IriOfferIdentifierFactoryInterface $iriOfferIdentifierFactory
113
     * @param CdbXMLImporter $cdbXMLImporter
114
     * @param JsonDocumentMetaDataEnricherInterface $jsonDocumentMetaDataEnricher
115
     * @param EventSpecification $eventsNotTriggeringUpdateModified
116
     */
117
    public function __construct(
118
        DocumentRepositoryInterface $repository,
119
        IriGeneratorInterface $iriGenerator,
120
        EventServiceInterface $eventService,
121
        PlaceService $placeService,
122
        OrganizerService $organizerService,
123
        SerializerInterface $mediaObjectSerializer,
124
        IriOfferIdentifierFactoryInterface $iriOfferIdentifierFactory,
125
        CdbXMLImporter $cdbXMLImporter,
126
        JsonDocumentMetaDataEnricherInterface $jsonDocumentMetaDataEnricher,
127
        EventSpecification $eventsNotTriggeringUpdateModified
128
    ) {
129
        parent::__construct(
130
            $repository,
131
            $iriGenerator,
132
            $organizerService,
133
            $mediaObjectSerializer,
134
            $jsonDocumentMetaDataEnricher,
135
            $eventsNotTriggeringUpdateModified
136
        );
137
138
        $this->placeService = $placeService;
139
        $this->eventService = $eventService;
140
        $this->cdbXMLImporter = $cdbXMLImporter;
141
142
        $this->iriOfferIdentifierFactory = $iriOfferIdentifierFactory;
143
    }
144
145
    /**
146
     * @param string $id
147
     * @return JsonDocument
148
     */
149 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...
150
    {
151
        $document = new JsonDocument($id);
152
153
        $offerLd = $document->getBody();
154
        $offerLd->{'@id'} = $this->iriGenerator->iri($id);
155
        $offerLd->{'@context'} = '/contexts/event';
156
157
        return $document->withBody($offerLd);
158
    }
159
160 View Code Duplication
    protected function applyOrganizerProjectedToJSONLD(OrganizerProjectedToJSONLD $organizerProjectedToJSONLD)
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...
161
    {
162
        $eventIds = $this->eventsOrganizedByOrganizer(
163
            $organizerProjectedToJSONLD->getId()
164
        );
165
166
        $organizer = $this->organizerService->getEntity(
167
            $organizerProjectedToJSONLD->getId()
168
        );
169
170
        $documents = [];
171
172
        foreach ($eventIds as $eventId) {
173
            $document = $this->loadDocumentFromRepositoryByItemId(
174
                $eventId
175
            );
176
            $eventLD = $document->getBody();
177
178
            $newEventLD = clone $eventLD;
179
            $newEventLD->organizer = json_decode($organizer);
180
181
            if ($newEventLD != $eventLD) {
182
                $documents[] = $document->withBody($newEventLD);
183
            }
184
        }
185
186
        return $documents;
187
    }
188
189
    protected function applyPlaceProjectedToJSONLD(
190
        PlaceProjectedToJSONLD $placeProjectedToJSONLD
191
    ) {
192
        $identifier = $this->iriOfferIdentifierFactory->fromIri(
193
            Url::fromNative($placeProjectedToJSONLD->getIri())
194
        );
195
196
        $eventsLocatedAtPlace = $this->eventsLocatedAtPlace(
197
            $identifier->getId()
198
        );
199
200
        $placeJSONLD = $this->placeService->getEntity(
201
            $identifier->getId()
202
        );
203
204
        $documents = [];
205
206
        foreach ($eventsLocatedAtPlace as $eventId) {
207
            $document = $this->loadDocumentFromRepositoryByItemId(
208
                $eventId
209
            );
210
            $eventLD = $document->getBody();
211
212
            $newEventLD = clone $eventLD;
213
            $newEventLD->location = json_decode($placeJSONLD);
214
215
            if ($newEventLD != $eventLD) {
216
                $documents[] = $document->withBody($newEventLD);
217
            }
218
        }
219
220
        return $documents;
221
    }
222
223
    /**
224
     * @param string $organizerId
225
     * @return string[]
226
     */
227
    protected function eventsOrganizedByOrganizer($organizerId)
228
    {
229
        return $this->eventService->eventsOrganizedByOrganizer(
230
            $organizerId
231
        );
232
    }
233
234
    /**
235
     * @param string $placeId
236
     * @return string[]
237
     */
238
    protected function eventsLocatedAtPlace($placeId)
239
    {
240
        return $this->eventService->eventsLocatedAtPlace(
241
            $placeId
242
        );
243
    }
244
245
    /**
246
     * @param EventImportedFromUDB2 $eventImportedFromUDB2
247
     * @return JsonDocument
248
     */
249
    protected function applyEventImportedFromUDB2(
250
        EventImportedFromUDB2 $eventImportedFromUDB2
251
    ) {
252
        return $this->applyEventCdbXmlFromUDB2(
253
            $eventImportedFromUDB2->getEventId(),
254
            $eventImportedFromUDB2->getCdbXmlNamespaceUri(),
255
            $eventImportedFromUDB2->getCdbXml()
256
        );
257
    }
258
259
    /**
260
     * @param EventUpdatedFromUDB2 $eventUpdatedFromUDB2
261
     * @return JsonDocument
262
     */
263
    protected function applyEventUpdatedFromUDB2(
264
        EventUpdatedFromUDB2 $eventUpdatedFromUDB2
265
    ) {
266
        return $this->applyEventCdbXmlFromUDB2(
267
            $eventUpdatedFromUDB2->getEventId(),
268
            $eventUpdatedFromUDB2->getCdbXmlNamespaceUri(),
269
            $eventUpdatedFromUDB2->getCdbXml()
270
        );
271
    }
272
273
    /**
274
     * Helper function to save a JSON-LD document from cdbxml coming from UDB2.
275
     *
276
     * @param string $eventId
277
     * @param string $cdbXmlNamespaceUri
278
     * @param string $cdbXml
279
     * @return JsonDocument
280
     */
281
    protected function applyEventCdbXmlFromUDB2(
282
        $eventId,
283
        $cdbXmlNamespaceUri,
284
        $cdbXml
285
    ) {
286
        $document = $this->newDocument($eventId);
287
288
        $eventLd = $this->projectEventCdbXmlToObject(
289
            $document->getBody(),
290
            $eventId,
291
            $cdbXmlNamespaceUri,
292
            $cdbXml
293
        );
294
295
        return $document->withBody($eventLd);
296
    }
297
298
    /**
299
     * @param \stdClass $jsonLd
300
     * @param string $eventId
301
     * @param string $cdbXmlNamespaceUri
302
     * @param string $cdbXml
303
     * @return \stdClass
304
     * @throws \CultureFeed_Cdb_ParseException
305
     */
306
    protected function projectEventCdbXmlToObject(
307
        \stdClass $jsonLd,
308
        $eventId,
309
        $cdbXmlNamespaceUri,
310
        $cdbXml
311
    ) {
312
        $udb2Event = EventItemFactory::createEventFromCdbXml(
313
            $cdbXmlNamespaceUri,
314
            $cdbXml
315
        );
316
317
        $jsonLd = $this->cdbXMLImporter->documentWithCdbXML(
318
            $jsonLd,
319
            $udb2Event,
320
            $this,
321
            $this,
322
            $this->slugger
323
        );
324
325
        // Because we can not properly track media coming from UDB2 we simply
326
        // ignore it and give priority to content added through UDB3.
327
        // It's possible that an event has been deleted in udb3, but never
328
        // in udb2. If an update comes for that event from udb2, it should
329
        // be imported again. This is intended by design.
330
        // @see https://jira.uitdatabank.be/browse/III-1092
331
        try {
332
            $document = $this->loadDocumentFromRepositoryByItemId($eventId);
333
        } catch (DocumentGoneException $documentGoneException) {
334
            $document = $this->newDocument($eventId);
335
        }
336
337
        $media = $this->UDB3Media($document);
338
        if (!empty($media)) {
339
            $jsonLd->mediaObject = $media;
340
        }
341
342
        // When importing from UDB2 the main language is always nl.
343
        // When updating from UDB2 never change the main language.
344
        if (!isset($jsonLd->mainLanguage)) {
345
            $this->setMainLanguage($jsonLd, new Language('nl'));
346
        }
347
348
        // Because UDB2 cannot keep track of UDB3 places as a location
349
        // ignore it and give priority to content added through UDB3.
350
        $location = $this->UDB3Location($document);
351
        if (!empty($location)) {
352
            $jsonLd->location = $location;
353
        }
354
355
        return $jsonLd;
356
    }
357
358
    /**
359
     * Return the media of an event if it already exists.
360
     *
361
     * @param JsonDocument $document The JsonDocument.
362
     *
363
     * @return array
364
     *  A list of media objects.
365
     */
366
    private function UDB3Media($document)
367
    {
368
        $media = [];
369
370
        if ($document) {
371
            $item = $document->getBody();
372
            // At the moment we do not include any media coming from UDB2.
373
            // If the mediaObject property contains data it's coming from UDB3.
374
            $item->mediaObject = isset($item->mediaObject) ? $item->mediaObject : [];
375
        }
376
377
        return $media;
378
    }
379
380
    /**
381
     * Return the location of an event if it already exists.
382
     *
383
     * @param JsonDocument $document The JsonDocument.
384
     *
385
     * @return array|null
386
     *  The location
387
     */
388
    private function UDB3Location($document)
389
    {
390
        $location = null;
391
392
        if ($document) {
393
            $item = $document->getBody();
394
            $location = isset($item->location) ? $item->location : null;
395
        }
396
397
        return $location;
398
    }
399
400
    /**
401
     * @param EventCreated $eventCreated
402
     * @param DomainMessage $domainMessage
403
     * @return JsonDocument
404
     */
405
    protected function applyEventCreated(
406
        EventCreated $eventCreated,
407
        DomainMessage $domainMessage
408
    ) {
409
        $document = $this->newDocument($eventCreated->getEventId());
410
        $jsonLD = $document->getBody();
411
412
        $jsonLD->{'@id'} = $this->iriGenerator->iri(
413
            $eventCreated->getEventId()
414
        );
415
416
        $this->setMainLanguage($jsonLD, $eventCreated->getMainLanguage());
417
418
        $jsonLD->name[$eventCreated->getMainLanguage()->getCode()] = $eventCreated->getTitle();
419
        $jsonLD->location = array(
420
                '@type' => 'Place',
421
            ) + (array)$this->placeJSONLD(
422
                $eventCreated->getLocation()->getCdbid()
423
            );
424
425
        $calendarJsonLD = $eventCreated->getCalendar()->toJsonLd();
426
        $jsonLD = (object)array_merge((array)$jsonLD, $calendarJsonLD);
427
428
        $availableTo = AvailableTo::createFromCalendar($eventCreated->getCalendar());
429
        $jsonLD->availableTo = (string)$availableTo;
430
431
        // Same as.
432
        $jsonLD->sameAs = $this->generateSameAs(
433
            $eventCreated->getEventId(),
434
            reset($jsonLD->name)
435
        );
436
437
        $eventType = $eventCreated->getEventType();
438
        $jsonLD->terms = [
439
            $eventType->toJsonLd(),
440
        ];
441
442
        $theme = $eventCreated->getTheme();
443
        if (!empty($theme)) {
444
            $jsonLD->terms[] = $theme->toJsonLd();
445
        }
446
447
        $created = RecordedOn::fromDomainMessage($domainMessage);
448
        $jsonLD->created = $created->toString();
449
        $jsonLD->modified = $created->toString();
450
451
        $metaData = $domainMessage->getMetadata()->serialize();
452 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...
453
            $jsonLD->creator = $metaData['user_email'];
454
        } elseif (isset($metaData['user_nick'])) {
455
            $jsonLD->creator = $metaData['user_nick'];
456
        }
457
458
        $jsonLD->workflowStatus = WorkflowStatus::DRAFT()->getName();
459
460
        $defaultAudience = new Audience(AudienceType::EVERYONE());
461
        $jsonLD->audience = $defaultAudience->serialize();
462
463
        return $document->withBody($jsonLD);
464
    }
465
466
    /**
467
     * @param EventCopied $eventCopied
468
     * @param DomainMessage $domainMessage
469
     * @return JsonDocument
470
     */
471
    protected function applyEventCopied(
472
        EventCopied $eventCopied,
473
        DomainMessage $domainMessage
474
    ) {
475
        $originalDocument = $this->repository->get($eventCopied->getOriginalEventId());
476
        $eventJsonLD = $originalDocument->getBody();
477
478
        // Set the created and modified date.
479
        $created = RecordedOn::fromDomainMessage($domainMessage);
480
        $eventJsonLD->created = $created->toString();
481
        $eventJsonLD->modified = $created->toString();
482
483
        // Set the creator.
484
        $eventJsonLD->creator = $this->getAuthorFromMetadata($domainMessage->getMetadata())->toNative();
485
486
        // Set the id.
487
        $eventJsonLD->{'@id'} = $this->iriGenerator->iri($eventCopied->getItemId());
488
489
        // Set the new calendar.
490
        $eventJsonLD = (object) array_merge(
491
            (array) $eventJsonLD,
492
            $eventCopied->getCalendar()->toJsonLd()
493
        );
494
495
        // Set workflow status.
496
        $eventJsonLD->workflowStatus = WorkflowStatus::DRAFT()->getName();
497
498
        // Remove labels.
499
        unset($eventJsonLD->labels);
500
        unset($eventJsonLD->hiddenLabels);
501
502
        // Set available to and from.
503
        $availableTo = AvailableTo::createFromCalendar($eventCopied->getCalendar());
504
        $eventJsonLD->availableTo = (string) $availableTo;
505
        unset($eventJsonLD->availableFrom);
506
507
        $newDocument = new JsonDocument($eventCopied->getItemId());
508
        $newDocument = $newDocument->withBody($eventJsonLD);
509
        return $newDocument;
510
    }
511
512
    /**
513
     * @param EventDeleted $eventDeleted
514
     * @return null
515
     */
516 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...
517
    {
518
        $document = $this->loadDocumentFromRepository($eventDeleted);
519
520
        $jsonLD = $document->getBody();
521
522
        $jsonLD->workflowStatus = WorkflowStatus::DELETED()->getName();
523
524
        return $document->withBody($jsonLD);
525
    }
526
527
    /**
528
     * Apply the major info updated command to the projector.
529
     * @param MajorInfoUpdated $majorInfoUpdated
530
     * @return JsonDocument
531
     */
532
    protected function applyMajorInfoUpdated(MajorInfoUpdated $majorInfoUpdated)
533
    {
534
        $document = $this
535
            ->loadDocumentFromRepository($majorInfoUpdated)
536
            ->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...
537
538
        $jsonLD = $document->getBody();
539
540
        $jsonLD->name->nl = $majorInfoUpdated->getTitle();
541
        $jsonLD->location = array(
542
          '@type' => 'Place',
543
        ) + (array)$this->placeJSONLD($majorInfoUpdated->getLocation()->getCdbid());
544
545
        $availableTo = AvailableTo::createFromCalendar($majorInfoUpdated->getCalendar());
546
        $jsonLD->availableTo = (string)$availableTo;
547
548
        // Remove old theme and event type.
549
        $jsonLD->terms = array_filter($jsonLD->terms, function ($term) {
550
            return $term->domain !== EventType::DOMAIN &&  $term->domain !== Theme::DOMAIN;
551
        });
552
        $jsonLD->terms = array_values($jsonLD->terms);
553
554
        $eventType = $majorInfoUpdated->getEventType();
555
        $jsonLD->terms[] = $eventType->toJsonLd();
556
557
        $theme = $majorInfoUpdated->getTheme();
558
        if (!empty($theme)) {
559
            $jsonLD->terms[] = $theme->toJsonLd();
560
        }
561
562
        return $document->withBody($jsonLD);
563
    }
564
565
    /**
566
     * @param LocationUpdated $locationUpdated
567
     *
568
     * @return JsonDocument
569
     */
570
    public function applyLocationUpdated(LocationUpdated $locationUpdated)
571
    {
572
        $document = $this->loadDocumentFromRepository($locationUpdated);
573
574
        $jsonLD = $document->getBody();
575
576
        $jsonLD->location = [
577
            '@type' => 'Place',
578
         ] + (array) $this->placeJSONLD($locationUpdated->getLocationId()->toNative());
579
580
        return $document->withBody($jsonLD);
581
    }
582
583
    /**
584
     * @param GeoCoordinatesUpdated $geoCoordinatesUpdated
585
     * @return JsonDocument
586
     */
587 View Code Duplication
    protected function applyGeoCoordinatesUpdated(GeoCoordinatesUpdated $geoCoordinatesUpdated)
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...
588
    {
589
        $document = $this->loadDocumentFromRepositoryByItemId($geoCoordinatesUpdated->getItemId());
590
591
        $eventLd = $document->getBody();
592
593
        $eventLd->location->geo = (object) [
594
            'latitude' => $geoCoordinatesUpdated->getCoordinates()->getLatitude()->toDouble(),
595
            'longitude' => $geoCoordinatesUpdated->getCoordinates()->getLongitude()->toDouble(),
596
        ];
597
598
        return $document->withBody($eventLd);
599
    }
600
601
    /**
602
     * @param AudienceUpdated $audienceUpdated
603
     * @return JsonDocument
604
     */
605
    protected function applyAudienceUpdated(AudienceUpdated $audienceUpdated)
606
    {
607
        $document = $this->loadDocumentFromRepository($audienceUpdated);
608
        $jsonLD = $document->getBody();
609
610
        $jsonLD->audience = $audienceUpdated->getAudience()->serialize();
611
612
        return $document->withBody($jsonLD);
613
    }
614
615
    /**
616
     * @inheritdoc
617
     */
618
    public function placeJSONLD($placeId)
619
    {
620
        if (empty($placeId)) {
621
            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...
622
        }
623
624
        try {
625
            $placeJSONLD = $this->placeService->getEntity(
626
                $placeId
627
            );
628
629
            return json_decode($placeJSONLD);
630
        } catch (EntityNotFoundException $e) {
631
            // In case the place can not be found at the moment, just add its ID
632
            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...
633
                '@id' => $this->placeService->iri($placeId),
634
            );
635
        } catch (DocumentGoneException $e) {
636
            // In case the place can not be found at the moment, just add its ID
637
            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...
638
                '@id' => $this->placeService->iri($placeId),
639
            );
640
        }
641
    }
642
643
    private function generateSameAs($eventId, $name)
644
    {
645
        $eventSlug = $this->slugger->slug($name);
646
        return array(
647
            'http://www.uitinvlaanderen.be/agenda/e/' . $eventSlug . '/' . $eventId,
648
        );
649
    }
650
651 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...
652
    {
653
        $properties = $metadata->serialize();
654
655
        if (isset($properties['user_nick'])) {
656
            return new StringLiteral($properties['user_nick']);
657
        }
658
    }
659
660 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...
661
    {
662
        $properties = $metadata->serialize();
663
664
        if (isset($properties['consumer']['name'])) {
665
            return new StringLiteral($properties['consumer']['name']);
666
        }
667
    }
668
669
    /**
670
     * @return string
671
     */
672
    protected function getLabelAddedClassName()
673
    {
674
        return LabelAdded::class;
675
    }
676
677
    /**
678
     * @return string
679
     */
680
    protected function getLabelRemovedClassName()
681
    {
682
        return LabelRemoved::class;
683
    }
684
685
    /**
686
     * @return string
687
     */
688
    protected function getImageAddedClassName()
689
    {
690
        return ImageAdded::class;
691
    }
692
693
    /**
694
     * @return string
695
     */
696
    protected function getImageRemovedClassName()
697
    {
698
        return ImageRemoved::class;
699
    }
700
701
    /**
702
     * @return string
703
     */
704
    protected function getImageUpdatedClassName()
705
    {
706
        return ImageUpdated::class;
707
    }
708
709
    protected function getMainImageSelectedClassName()
710
    {
711
        return MainImageSelected::class;
712
    }
713
714
    /**
715
     * @return string
716
     */
717
    protected function getTitleTranslatedClassName()
718
    {
719
        return TitleTranslated::class;
720
    }
721
722
    /**
723
     * @return string
724
     */
725
    protected function getDescriptionTranslatedClassName()
726
    {
727
        return DescriptionTranslated::class;
728
    }
729
730
    /**
731
     * @return string
732
     */
733
    protected function getOrganizerUpdatedClassName()
734
    {
735
        return OrganizerUpdated::class;
736
    }
737
738
    /**
739
     * @return string
740
     */
741
    protected function getOrganizerDeletedClassName()
742
    {
743
        return OrganizerDeleted::class;
744
    }
745
746
    protected function getBookingInfoUpdatedClassName()
747
    {
748
        return BookingInfoUpdated::class;
749
    }
750
751
    /**
752
     * @return string
753
     */
754
    protected function getPriceInfoUpdatedClassName()
755
    {
756
        return PriceInfoUpdated::class;
757
    }
758
759
    protected function getContactPointUpdatedClassName()
760
    {
761
        return ContactPointUpdated::class;
762
    }
763
764
    protected function getDescriptionUpdatedClassName()
765
    {
766
        return DescriptionUpdated::class;
767
    }
768
769
    protected function getCalendarUpdatedClassName()
770
    {
771
        return CalendarUpdated::class;
772
    }
773
774
    protected function getTypicalAgeRangeUpdatedClassName()
775
    {
776
        return TypicalAgeRangeUpdated::class;
777
    }
778
779
    protected function getTypicalAgeRangeDeletedClassName()
780
    {
781
        return TypicalAgeRangeDeleted::class;
782
    }
783
784
    protected function getPublishedClassName()
785
    {
786
        return Published::class;
787
    }
788
789
    protected function getApprovedClassName()
790
    {
791
        return Approved::class;
792
    }
793
794
    protected function getRejectedClassName()
795
    {
796
        return Rejected::class;
797
    }
798
799
    protected function getFlaggedAsDuplicateClassName()
800
    {
801
        return FlaggedAsDuplicate::class;
802
    }
803
804
    protected function getFlaggedAsInappropriateClassName()
805
    {
806
        return FlaggedAsInappropriate::class;
807
    }
808
809
    protected function getImagesImportedFromUdb2ClassName()
810
    {
811
        return ImagesImportedFromUDB2::class;
812
    }
813
814
    protected function getImagesUpdatedFromUdb2ClassName()
815
    {
816
        return ImagesUpdatedFromUDB2::class;
817
    }
818
819
    protected function getTitleUpdatedClassName()
820
    {
821
        return TitleUpdated::class;
822
    }
823
824
    protected function getTypeUpdatedClassName()
825
    {
826
        return TypeUpdated::class;
827
    }
828
829
    protected function getThemeUpdatedClassName()
830
    {
831
        return ThemeUpdated::class;
832
    }
833
834
    protected function getFacilitiesUpdatedClassName()
835
    {
836
        return FacilitiesUpdated::class;
837
    }
838
}
839