Completed
Pull Request — master (#272)
by Kristof
12:29
created

PlaceLDProjector::getImageRemovedClassName()   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\Place\ReadModel\JSONLD;
4
5
use Broadway\Domain\DateTime;
6
use Broadway\Domain\DomainMessage;
7
use Broadway\EventHandling\EventListenerInterface;
8
use CultuurNet\UDB3\Actor\ActorImportedFromUDB2;
9
use CultuurNet\UDB3\Cdb\ActorItemFactory;
10
use CultuurNet\UDB3\CulturefeedSlugger;
11
use CultuurNet\UDB3\EntityServiceInterface;
12
use CultuurNet\UDB3\Event\EventType;
13
use CultuurNet\UDB3\Event\ReadModel\DocumentGoneException;
14
use CultuurNet\UDB3\Event\ReadModel\DocumentRepositoryInterface;
15
use CultuurNet\UDB3\Facility;
16
use CultuurNet\UDB3\Iri\IriGeneratorInterface;
17
use CultuurNet\UDB3\Offer\AvailableTo;
18
use CultuurNet\UDB3\Offer\ReadModel\JSONLD\OfferLDProjector;
19
use CultuurNet\UDB3\Offer\ReadModel\JSONLD\OfferUpdate;
20
use CultuurNet\UDB3\Offer\WorkflowStatus;
21
use CultuurNet\UDB3\Place\Events\BookingInfoUpdated;
22
use CultuurNet\UDB3\Place\Events\ContactPointUpdated;
23
use CultuurNet\UDB3\Place\Events\DescriptionTranslated;
24
use CultuurNet\UDB3\Place\Events\DescriptionUpdated;
25
use CultuurNet\UDB3\Place\Events\FacilitiesUpdated;
26
use CultuurNet\UDB3\Place\Events\Image\ImagesImportedFromUDB2;
27
use CultuurNet\UDB3\Place\Events\Image\ImagesUpdatedFromUDB2;
28
use CultuurNet\UDB3\Place\Events\ImageAdded;
29
use CultuurNet\UDB3\Place\Events\ImageRemoved;
30
use CultuurNet\UDB3\Place\Events\ImageUpdated;
31
use CultuurNet\UDB3\Place\Events\LabelAdded;
32
use CultuurNet\UDB3\Place\Events\LabelRemoved;
33
use CultuurNet\UDB3\Place\Events\MainImageSelected;
34
use CultuurNet\UDB3\Place\Events\MajorInfoUpdated;
35
use CultuurNet\UDB3\Place\Events\Moderation\Approved;
36
use CultuurNet\UDB3\Place\Events\Moderation\FlaggedAsDuplicate;
37
use CultuurNet\UDB3\Place\Events\Moderation\FlaggedAsInappropriate;
38
use CultuurNet\UDB3\Place\Events\Moderation\Published;
39
use CultuurNet\UDB3\Place\Events\Moderation\Rejected;
40
use CultuurNet\UDB3\Place\Events\OrganizerDeleted;
41
use CultuurNet\UDB3\Place\Events\OrganizerUpdated;
42
use CultuurNet\UDB3\Place\Events\PlaceCreated;
43
use CultuurNet\UDB3\Place\Events\PlaceDeleted;
44
use CultuurNet\UDB3\Place\Events\PlaceImportedFromUDB2;
45
use CultuurNet\UDB3\Place\Events\PlaceUpdatedFromUDB2;
46
use CultuurNet\UDB3\Place\Events\PriceInfoUpdated;
47
use CultuurNet\UDB3\Place\Events\TitleTranslated;
48
use CultuurNet\UDB3\Place\Events\TypicalAgeRangeDeleted;
49
use CultuurNet\UDB3\Place\Events\TypicalAgeRangeUpdated;
50
use CultuurNet\UDB3\Place\PlaceEvent;
51
use CultuurNet\UDB3\ReadModel\JsonDocument;
52
use CultuurNet\UDB3\Theme;
53
use Symfony\Component\Serializer\SerializerInterface;
54
55
/**
56
 * Projects state changes on Place entities to a JSON-LD read model in a
57
 * document repository.
58
 */
59
class PlaceLDProjector extends OfferLDProjector implements EventListenerInterface
60
{
61
    /**
62
     * @var CdbXMLImporter
63
     */
64
    protected $cdbXMLImporter;
65
66
    /**
67
     * @param DocumentRepositoryInterface $repository
68
     * @param IriGeneratorInterface $iriGenerator
69
     * @param EntityServiceInterface $organizerService
70
     * @param SerializerInterface $mediaObjectSerializer
71
     * @param CdbXMLImporter $cdbXMLImporter
72
     */
73
    public function __construct(
74
        DocumentRepositoryInterface $repository,
75
        IriGeneratorInterface $iriGenerator,
76
        EntityServiceInterface $organizerService,
77
        SerializerInterface $mediaObjectSerializer,
78
        CdbXMLImporter $cdbXMLImporter
79
    ) {
80
        parent::__construct(
81
            $repository,
82
            $iriGenerator,
83
            $organizerService,
84
            $mediaObjectSerializer
85
        );
86
87
        $this->slugger = new CulturefeedSlugger();
88
        $this->cdbXMLImporter = $cdbXMLImporter;
89
    }
90
91
    protected function getImagesImportedFromUdb2ClassName()
92
    {
93
        return ImagesImportedFromUDB2::class;
94
    }
95
96
    protected function getImagesUpdatedFromUdb2ClassName()
97
    {
98
        return ImagesUpdatedFromUDB2::class;
99
    }
100
101
    /**
102
     * @param PlaceImportedFromUDB2 $placeImportedFromUDB2
103
     */
104
    protected function applyPlaceImportedFromUDB2(
105
        PlaceImportedFromUDB2 $placeImportedFromUDB2
106
    ) {
107
        $this->projectActorImportedFromUDB2($placeImportedFromUDB2);
108
    }
109
110
    /**
111
     * @param PlaceUpdatedFromUDB2 $placeUpdatedFromUDB2
112
     */
113
    protected function applyPlaceUpdatedFromUDB2(
114
        PlaceUpdatedFromUDB2 $placeUpdatedFromUDB2
115
    ) {
116
        $this->projectActorImportedFromUDB2($placeUpdatedFromUDB2);
117
    }
118
119
    /**
120
     * @param ActorImportedFromUDB2 $actorImportedFromUDB2
121
     */
122
    protected function projectActorImportedFromUDB2(
123
        ActorImportedFromUDB2 $actorImportedFromUDB2
124
    ) {
125
        $actorId = $actorImportedFromUDB2->getActorId();
126
127
        $udb2Actor = ActorItemFactory::createActorFromCdbXml(
128
            $actorImportedFromUDB2->getCdbXmlNamespaceUri(),
129
            $actorImportedFromUDB2->getCdbXml()
130
        );
131
132
        try {
133
            $document = $this->loadPlaceDocumentFromRepositoryById($actorId);
134
        } catch (DocumentGoneException $e) {
135
            $document = $this->newDocument($actorId);
136
        }
137
138
        $actorLd = $document->getBody();
139
140
        $actorLd = $this->cdbXMLImporter->documentWithCdbXML(
141
            $actorLd,
142
            $udb2Actor
143
        );
144
145
        $this->repository->save($document->withBody($actorLd));
146
    }
147
148
    /**
149
     * @param string $id
150
     * @return JsonDocument
151
     */
152 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...
153
    {
154
        $document = new JsonDocument($id);
155
156
        $placeLd = $document->getBody();
157
        $placeLd->{'@id'} = $this->iriGenerator->iri($id);
158
        $placeLd->{'@context'} = '/contexts/place';
159
160
        return $document->withBody($placeLd);
161
    }
162
163
    /**
164
     * @param PlaceCreated $placeCreated
165
     * @param DomainMessage $domainMessage
166
     */
167
    protected function applyPlaceCreated(PlaceCreated $placeCreated, DomainMessage $domainMessage)
168
    {
169
        $document = $this->newDocument($placeCreated->getPlaceId());
170
171
        $jsonLD = $document->getBody();
172
173
        $jsonLD->{'@id'} = $this->iriGenerator->iri(
174
            $placeCreated->getPlaceId()
175
        );
176
177
        if (empty($jsonLD->name)) {
178
            $jsonLD->name = new \stdClass();
179
        }
180
181
        $jsonLD->name->nl = $placeCreated->getTitle();
182
183
        $jsonLD->address = $placeCreated->getAddress()->toJsonLd();
184
185
        $calendarJsonLD = $placeCreated->getCalendar()->toJsonLd();
186
        $jsonLD = (object) array_merge((array) $jsonLD, $calendarJsonLD);
187
188
        $availableTo = AvailableTo::createFromCalendar($placeCreated->getCalendar());
189
        $jsonLD->availableTo = (string)$availableTo;
190
191
        $eventType = $placeCreated->getEventType();
192
        $jsonLD->terms = [
193
            $eventType->toJsonLd()
194
        ];
195
196
        $theme = $placeCreated->getTheme();
197
        if (!empty($theme)) {
198
            $jsonLD->terms[] = $theme->toJsonLd();
199
        }
200
201
        $recordedOn = $domainMessage->getRecordedOn()->toString();
202
        $jsonLD->created = \DateTime::createFromFormat(
203
            DateTime::FORMAT_STRING,
204
            $recordedOn
205
        )->format('c');
206
207
        $jsonLD->modified = $jsonLD->created;
208
209
        $metaData = $domainMessage->getMetadata()->serialize();
210 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...
211
            $jsonLD->creator = $metaData['user_email'];
212
        } elseif (isset($metaData['user_nick'])) {
213
            $jsonLD->creator = $metaData['user_nick'];
214
        }
215
216
        $jsonLD->workflowStatus = WorkflowStatus::DRAFT()->getName();
217
218
        $this->repository->save($document->withBody($jsonLD));
219
    }
220
221
    /**
222
     * @param PlaceDeleted $placeDeleted
223
     */
224
    protected function applyPlaceDeleted(PlaceDeleted $placeDeleted)
225
    {
226
        $this->repository->remove($placeDeleted->getItemId());
227
    }
228
229
    /**
230
     * Apply the major info updated command to the projector.
231
     * @param MajorInfoUpdated $majorInfoUpdated
232
     */
233
    protected function applyMajorInfoUpdated(MajorInfoUpdated $majorInfoUpdated)
234
    {
235
        $document = $this
236
            ->loadPlaceDocumentFromRepository($majorInfoUpdated)
237
            ->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...
238
239
        $jsonLD = $document->getBody();
240
241
        $jsonLD->name->nl = $majorInfoUpdated->getTitle();
242
        $jsonLD->address = $majorInfoUpdated->getAddress()->toJsonLd();
243
244
        $availableTo = AvailableTo::createFromCalendar($majorInfoUpdated->getCalendar());
245
        $jsonLD->availableTo = (string)$availableTo;
246
247
        // Remove old theme and event type.
248
        $jsonLD->terms = array_filter($jsonLD->terms, function ($term) {
249
            return $term->domain !== EventType::DOMAIN &&  $term->domain !== Theme::DOMAIN;
250
        });
251
252
        $eventType = $majorInfoUpdated->getEventType();
253
        $jsonLD->terms = [
254
            $eventType->toJsonLd()
255
        ];
256
257
        $theme = $majorInfoUpdated->getTheme();
258
        if (!empty($theme)) {
259
            $jsonLD->terms[] = $theme->toJsonLd();
260
        }
261
262
        $this->repository->save($document->withBody($jsonLD));
263
264
    }
265
266
    /**
267
     * Apply the facilitiesupdated event to the place repository.
268
     * @param FacilitiesUpdated $facilitiesUpdated
269
     */
270
    protected function applyFacilitiesUpdated(FacilitiesUpdated $facilitiesUpdated)
271
    {
272
273
        $document = $this->loadPlaceDocumentFromRepository($facilitiesUpdated);
274
275
        $placeLd = $document->getBody();
276
277
        $terms = isset($placeLd->terms) ? $placeLd->terms : array();
278
279
        // Remove all old facilities + get numeric keys.
280
        $terms = array_values(array_filter(
281
            $terms,
282
            function ($term) {
283
                return $term->domain !== Facility::DOMAIN;
284
            }
285
        ));
286
287
        // Add the new facilities.
288
        foreach ($facilitiesUpdated->getFacilities() as $facility) {
289
            $terms[] = $facility->toJsonLd();
290
        }
291
292
        $placeLd->terms = $terms;
293
294
        $this->repository->save($document->withBody($placeLd));
295
296
    }
297
298
    /**
299
     * @param PlaceEvent $place
300
     * @return JsonDocument
301
     */
302
    protected function loadPlaceDocumentFromRepository(PlaceEvent $place)
303
    {
304
        $document = $this->repository->get($place->getPlaceId());
305
306
        if (!$document) {
307
            return $this->newDocument($place->getPlaceId());
308
        }
309
310
        return $document;
311
    }
312
313
    /**
314
     * @param string $itemId
315
     * @return JsonDocument
316
     */
317
    protected function loadPlaceDocumentFromRepositoryById($itemId)
318
    {
319
        $document = $this->repository->get($itemId);
320
321
        if (!$document) {
322
            return $this->newDocument($itemId);
323
        }
324
325
        return $document;
326
    }
327
328
    /**
329
     * @return string
330
     */
331
    protected function getLabelAddedClassName()
332
    {
333
        return LabelAdded::class;
334
    }
335
336
    /**
337
     * @return string
338
     */
339
    protected function getLabelRemovedClassName()
340
    {
341
        return LabelRemoved::class;
342
    }
343
344
    /**
345
     * @return string
346
     */
347
    protected function getImageAddedClassName()
348
    {
349
        return ImageAdded::class;
350
    }
351
352
    /**
353
     * @return string
354
     */
355
    protected function getImageRemovedClassName()
356
    {
357
        return ImageRemoved::class;
358
    }
359
360
    /**
361
     * @return string
362
     */
363
    protected function getImageUpdatedClassName()
364
    {
365
        return ImageUpdated::class;
366
    }
367
368
    protected function getMainImageSelectedClassName()
369
    {
370
        return MainImageSelected::class;
371
    }
372
373
    /**
374
     * @return string
375
     */
376
    protected function getTitleTranslatedClassName()
377
    {
378
        return TitleTranslated::class;
379
    }
380
381
    /**
382
     * @return string
383
     */
384
    protected function getDescriptionTranslatedClassName()
385
    {
386
        return DescriptionTranslated::class;
387
    }
388
389
    /**
390
     * @return string
391
     */
392
    protected function getOrganizerUpdatedClassName()
393
    {
394
        return OrganizerUpdated::class;
395
    }
396
397
    /**
398
     * @return string
399
     */
400
    protected function getOrganizerDeletedClassName()
401
    {
402
        return OrganizerDeleted::class;
403
    }
404
405
    protected function getBookingInfoUpdatedClassName()
406
    {
407
        return BookingInfoUpdated::class;
408
    }
409
410
    /**
411
     * @return string
412
     */
413
    protected function getPriceInfoUpdatedClassName()
414
    {
415
        return PriceInfoUpdated::class;
416
    }
417
418
    protected function getContactPointUpdatedClassName()
419
    {
420
        return ContactPointUpdated::class;
421
    }
422
423
    protected function getDescriptionUpdatedClassName()
424
    {
425
        return DescriptionUpdated::class;
426
    }
427
428
    protected function getTypicalAgeRangeUpdatedClassName()
429
    {
430
        return TypicalAgeRangeUpdated::class;
431
    }
432
433
    protected function getTypicalAgeRangeDeletedClassName()
434
    {
435
        return TypicalAgeRangeDeleted::class;
436
    }
437
438
    protected function getPublishedClassName()
439
    {
440
        return Published::class;
441
    }
442
443
    protected function getApprovedClassName()
444
    {
445
        return Approved::class;
446
    }
447
448
    protected function getRejectedClassName()
449
    {
450
        return Rejected::class;
451
    }
452
453
    protected function getFlaggedAsDuplicateClassName()
454
    {
455
        return FlaggedAsDuplicate::class;
456
    }
457
458
    protected function getFlaggedAsInappropriateClassName()
459
    {
460
        return FlaggedAsInappropriate::class;
461
    }
462
}
463