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