Completed
Pull Request — master (#421)
by Jonas
03:05
created

Place::getCanonicalPlaceId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace CultuurNet\UDB3\Place;
4
5
use CultuurNet\Geocoding\Coordinate\Coordinates;
6
use CultuurNet\UDB3\Address\Address;
7
use CultuurNet\UDB3\BookingInfo;
8
use CultuurNet\UDB3\Calendar;
9
use CultuurNet\UDB3\CalendarInterface;
10
use CultuurNet\UDB3\Cdb\ActorItemFactory;
11
use CultuurNet\UDB3\Cdb\UpdateableWithCdbXmlInterface;
12
use CultuurNet\UDB3\ContactPoint;
13
use CultuurNet\UDB3\Description;
14
use CultuurNet\UDB3\Event\EventType;
15
use CultuurNet\UDB3\Label;
16
use CultuurNet\UDB3\LabelCollection;
17
use CultuurNet\UDB3\Media\ImageCollection;
18
use CultuurNet\UDB3\Model\ValueObject\Taxonomy\Label\Labels;
19
use CultuurNet\UDB3\Language;
20
use CultuurNet\UDB3\Offer\AgeRange;
21
use CultuurNet\UDB3\Offer\Offer;
22
use CultuurNet\UDB3\Media\Image;
23
use CultuurNet\UDB3\Offer\WorkflowStatus;
24
use CultuurNet\UDB3\Place\Events\AddressTranslated;
25
use CultuurNet\UDB3\Place\Events\AddressUpdated;
26
use CultuurNet\UDB3\Place\Events\BookingInfoUpdated;
27
use CultuurNet\UDB3\Place\Events\CalendarUpdated;
28
use CultuurNet\UDB3\Place\Events\ContactPointUpdated;
29
use CultuurNet\UDB3\Place\Events\DescriptionTranslated;
30
use CultuurNet\UDB3\Place\Events\DescriptionUpdated;
31
use CultuurNet\UDB3\Place\Events\FacilitiesUpdated;
32
use CultuurNet\UDB3\Place\Events\GeoCoordinatesUpdated;
33
use CultuurNet\UDB3\Place\Events\Image\ImagesImportedFromUDB2;
34
use CultuurNet\UDB3\Place\Events\Image\ImagesUpdatedFromUDB2;
35
use CultuurNet\UDB3\Place\Events\ImageAdded;
36
use CultuurNet\UDB3\Place\Events\ImageRemoved;
37
use CultuurNet\UDB3\Place\Events\ImageUpdated;
38
use CultuurNet\UDB3\Place\Events\LabelsImported;
39
use CultuurNet\UDB3\Place\Events\MainImageSelected;
40
use CultuurNet\UDB3\Place\Events\LabelAdded;
41
use CultuurNet\UDB3\Place\Events\LabelRemoved;
42
use CultuurNet\UDB3\Place\Events\MajorInfoUpdated;
43
use CultuurNet\UDB3\Place\Events\MarkedAsDuplicate;
44
use CultuurNet\UDB3\Place\Events\MarkedAsCanonical;
45
use CultuurNet\UDB3\Place\Events\Moderation\Approved;
46
use CultuurNet\UDB3\Place\Events\Moderation\FlaggedAsDuplicate;
47
use CultuurNet\UDB3\Place\Events\Moderation\FlaggedAsInappropriate;
48
use CultuurNet\UDB3\Place\Events\Moderation\Published;
49
use CultuurNet\UDB3\Place\Events\Moderation\Rejected;
50
use CultuurNet\UDB3\Place\Events\OrganizerDeleted;
51
use CultuurNet\UDB3\Place\Events\OrganizerUpdated;
52
use CultuurNet\UDB3\Place\Events\PlaceCreated;
53
use CultuurNet\UDB3\Place\Events\PlaceDeleted;
54
use CultuurNet\UDB3\Place\Events\PlaceImportedFromUDB2;
55
use CultuurNet\UDB3\Place\Events\PlaceUpdatedFromUDB2;
56
use CultuurNet\UDB3\Place\Events\PriceInfoUpdated;
57
use CultuurNet\UDB3\Place\Events\ThemeUpdated;
58
use CultuurNet\UDB3\Place\Events\TitleTranslated;
59
use CultuurNet\UDB3\Place\Events\TitleUpdated;
60
use CultuurNet\UDB3\Place\Events\TypeUpdated;
61
use CultuurNet\UDB3\Place\Events\TypicalAgeRangeDeleted;
62
use CultuurNet\UDB3\Place\Events\TypicalAgeRangeUpdated;
63
use CultuurNet\UDB3\PriceInfo\PriceInfo;
64
use CultuurNet\UDB3\Theme;
65
use CultuurNet\UDB3\Title;
66
use DateTimeImmutable;
67
use ValueObjects\Identity\UUID;
68
use ValueObjects\StringLiteral\StringLiteral;
69
70
class Place extends Offer implements UpdateableWithCdbXmlInterface
71
{
72
    /**
73
     * @var string
74
     */
75
    private $placeId;
76
77
    /**
78
     * @var Address[]
79
     */
80
    private $addresses;
81
82
    /**
83
     * @var boolean
84
     */
85
    private $isDuplicate = false;
86
87
    /**
88
     * @var string[]
89
     */
90
    private $duplicates = [];
91
92
    /**
93
     * @var string|null
94
     */
95
    private $canonicalPlaceId;
96
97
    public function __construct()
98
    {
99
        parent::__construct();
100
101
        $this->addresses = [];
102
    }
103
104
    /**
105
     * {@inheritdoc}
106
     */
107
    public function getAggregateRootId()
108
    {
109
        return $this->placeId;
110
    }
111
112
    /**
113
     * @todo Rename this method to create() after moving this part of the codebase to udb3-silex
114
     */
115
    public static function createPlace(
116
        string $id,
117
        Language $mainLanguage,
118
        Title $title,
119
        EventType $eventType,
120
        Address $address,
121
        CalendarInterface $calendar,
122
        Theme $theme = null,
123
        DateTimeImmutable $publicationDate = null
124
    ): self {
125
        $place = new self();
126
        $place->apply(new PlaceCreated(
127
            $id,
128
            $mainLanguage,
129
            $title,
130
            $eventType,
131
            $address,
132
            $calendar,
133
            $theme,
134
            $publicationDate
135
        ));
136
137
        return $place;
138
    }
139
140
    protected function applyPlaceCreated(PlaceCreated $placeCreated): void
141
    {
142
        $this->mainLanguage = $placeCreated->getMainLanguage();
143
        $this->titles[$this->mainLanguage->getCode()] = $placeCreated->getTitle();
144
        $this->calendar = $placeCreated->getCalendar();
145
        $this->contactPoint = new ContactPoint();
146
        $this->bookingInfo = new BookingInfo();
147
        $this->typeId = $placeCreated->getEventType()->getId();
148
        $this->themeId = $placeCreated->getTheme() ? $placeCreated->getTheme()->getId() : null;
149
        $this->addresses[$this->mainLanguage->getCode()] = $placeCreated->getAddress();
150
        $this->placeId = $placeCreated->getPlaceId();
151
        $this->workflowStatus = WorkflowStatus::DRAFT();
152
    }
153
154
    public function updateMajorInfo(
155
        Title $title,
156
        EventType $eventType,
157
        Address $address,
158
        CalendarInterface $calendar,
159
        Theme $theme = null
160
    ): void {
161
        $this->apply(
162
            new MajorInfoUpdated(
163
                $this->placeId,
164
                $title,
165
                $eventType,
166
                $address,
167
                $calendar,
168
                $theme
169
            )
170
        );
171
    }
172
173
    protected function applyMajorInfoUpdated(MajorInfoUpdated $majorInfoUpdated): void
174
    {
175
        $this->addresses[$this->mainLanguage->getCode()] = $majorInfoUpdated->getAddress();
176
    }
177
178
    public function updateAddress(Address $address, Language $language): void
179
    {
180
        if ($language->getCode() === $this->mainLanguage->getCode()) {
181
            $event = new AddressUpdated($this->placeId, $address);
182
        } else {
183
            $event = new AddressTranslated($this->placeId, $address, $language);
184
        }
185
186
        if ($this->allowAddressUpdate($address, $language)) {
187
            $this->apply($event);
188
        }
189
    }
190
191
    protected function applyAddressUpdated(AddressUpdated $addressUpdated): void
192
    {
193
        $this->addresses[$this->mainLanguage->getCode()] = $addressUpdated->getAddress();
194
    }
195
196
    protected function applyAddressTranslated(AddressTranslated $addressTranslated): void
197
    {
198
        $this->addresses[$addressTranslated->getLanguage()->getCode()] = $addressTranslated->getAddress();
199
    }
200
201
    public function markAsDuplicateOf(string $placeIdOfCanonical): void
202
    {
203
        if ($this->isDeleted) {
204
            throw CannotMarkPlaceAsDuplicate::becauseItIsDeleted($this->placeId);
205
        }
206
207
        if ($this->isDuplicate) {
208
            throw CannotMarkPlaceAsDuplicate::becauseItIsAlreadyADuplicate($this->placeId);
209
        }
210
211
        $this->apply(new MarkedAsDuplicate($this->placeId, $placeIdOfCanonical));
212
    }
213
214
    public function markAsCanonicalFor(string $placeIdOfDuplicate, array $duplicatesOfDuplicate = []): void
215
    {
216
        if ($this->isDeleted) {
217
            throw CannotMarkPlaceAsCanonical::becauseItIsDeleted($this->placeId);
218
        }
219
220
        if ($this->isDuplicate) {
221
            throw CannotMarkPlaceAsCanonical::becauseItIsAlreadyADuplicate($this->placeId);
222
        }
223
224
        $this->apply(new MarkedAsCanonical($this->placeId, $placeIdOfDuplicate, $duplicatesOfDuplicate));
225
    }
226
227
    /**
228
     * @return string[]
229
     */
230
    public function getDuplicates(): array
231
    {
232
        return $this->duplicates;
233
    }
234
235
    private function allowAddressUpdate(Address $address, Language $language): bool
236
    {
237
        // No current address in the provided language so update with new address is allowed.
238
        if (!isset($this->addresses[$language->getCode()])) {
239
            return true;
240
        }
241
242
        // The current address in de the provided language is different then the new address, so update allowed.
243
        if (!$this->addresses[$language->getCode()]->sameAs($address)) {
244
            return true;
245
        }
246
247
        return false;
248
    }
249
250
    public static function importFromUDB2Actor(
251
        string $actorId,
252
        string $cdbXml,
253
        string $cdbXmlNamespaceUri
254
    ): self {
255
        $place = new static();
256
        $place->apply(
257
            new PlaceImportedFromUDB2(
258
                $actorId,
259
                $cdbXml,
260
                $cdbXmlNamespaceUri
261
            )
262
        );
263
264
        return $place;
265
    }
266
267
    protected function applyPlaceImportedFromUDB2(PlaceImportedFromUDB2 $placeImported): void
268
    {
269
        $this->placeId = $placeImported->getActorId();
270
271
        // When importing from UDB2 the default main language is always 'nl'.
272
        $this->mainLanguage = new Language('nl');
273
274
        $udb2Actor = ActorItemFactory::createActorFromCdbXml(
275
            $placeImported->getCdbXmlNamespaceUri(),
276
            $placeImported->getCdbXml()
277
        );
278
279
        // Just clear the facilities.
280
        $this->facilities = [];
281
282
        // Just clear the contact point.
283
        $this->contactPoint = null;
284
285
        // Just clear the calendar.
286
        $this->calendar = null;
287
288
        // Note: an actor has no typical age range so after it can't be changed
289
        // by an UDB2 update. Nothing has to be done.
290
291
        // Just clear the booking info.
292
        $this->bookingInfo = null;
293
294
        // Just clear the price info.
295
        $this->priceInfo = null;
296
297
        $this->importWorkflowStatus($udb2Actor);
298
        $this->labels = LabelCollection::fromKeywords($udb2Actor->getKeywords(true));
299
    }
300
301
    protected function applyPlaceUpdatedFromUDB2(PlaceUpdatedFromUDB2 $placeUpdatedFromUDB2): void
302
    {
303
        // Note: when updating from UDB2 never change the main language.
304
305
        $udb2Actor = ActorItemFactory::createActorFromCdbXml(
306
            $placeUpdatedFromUDB2->getCdbXmlNamespaceUri(),
307
            $placeUpdatedFromUDB2->getCdbXml()
308
        );
309
310
        // Just clear the facilities.
311
        $this->facilities = [];
312
313
        // Just clear the contact point.
314
        $this->contactPoint = null;
315
316
        // Just clear the calendar.
317
        $this->calendar = null;
318
319
        // Note: an actor has no typical age range so after it can't be changed
320
        // by an UDB2 update. Nothing has to be done.
321
322
        // Just clear the booking info.
323
        $this->bookingInfo = null;
324
325
        // Just clear the price info.
326
        $this->priceInfo = null;
327
328
        $this->importWorkflowStatus($udb2Actor);
329
        $this->labels = LabelCollection::fromKeywords($udb2Actor->getKeywords(true));
330
331
        unset($this->addresses[$this->mainLanguage->getCode()]);
332
    }
333
334
    protected function applyPlaceDeleted(PlaceDeleted $event): void
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
335
    {
336
        $this->isDeleted = true;
337
    }
338
339
    protected function applyMarkedAsDuplicate(MarkedAsDuplicate $event): void
340
    {
341
        $this->isDuplicate = true;
342
        $this->canonicalPlaceId = $event->getDuplicateOf();
343
    }
344
345
    protected function applyMarkedAsCanonical(MarkedAsCanonical $event): void
346
    {
347
        $this->duplicates[] = $event->getDuplicatedBy();
348
        foreach ($event->getDuplicatesOfDuplicate() as $duplicateOfDuplicate) {
349
            $this->duplicates[] = $duplicateOfDuplicate;
350
        }
351
    }
352
353
    public function getCanonicalPlaceId(): ?string
354
    {
355
        return $this->canonicalPlaceId;
356
    }
357
358
    /**
359
     * @inheritdoc
360
     */
361
    public function updateWithCdbXml($cdbXml, $cdbXmlNamespaceUri)
362
    {
363
        ActorItemFactory::createActorFromCdbXml($cdbXmlNamespaceUri, $cdbXml);
364
365
        $this->apply(
366
            new PlaceUpdatedFromUDB2(
367
                $this->placeId,
368
                $cdbXml,
369
                $cdbXmlNamespaceUri
370
            )
371
        );
372
    }
373
374
    /**
375
     * @param Label $label
376
     * @return LabelAdded
377
     */
378
    protected function createLabelAddedEvent(Label $label)
379
    {
380
        return new LabelAdded($this->placeId, $label);
381
    }
382
383
    /**
384
     * @param Label $label
385
     * @return LabelRemoved
386
     */
387
    protected function createLabelRemovedEvent(Label $label)
388
    {
389
        return new LabelRemoved($this->placeId, $label);
390
    }
391
392
    /**
393
     * @inheritdoc
394
     */
395
    protected function createLabelsImportedEvent(Labels $labels)
396
    {
397
        return new LabelsImported($this->placeId, $labels);
398
    }
399
400
    protected function createImageAddedEvent(Image $image)
401
    {
402
        return new ImageAdded($this->placeId, $image);
403
    }
404
405
    protected function createImageRemovedEvent(Image $image)
406
    {
407
        return new ImageRemoved($this->placeId, $image);
408
    }
409
410
    protected function createImageUpdatedEvent(
411
        UUID $mediaObjectId,
412
        StringLiteral $description,
413
        StringLiteral $copyrightHolder
414
    ) {
415
        return new ImageUpdated(
416
            $this->placeId,
417
            $mediaObjectId,
418
            $description,
419
            $copyrightHolder
420
        );
421
    }
422
423
    protected function createMainImageSelectedEvent(Image $image)
424
    {
425
        return new MainImageSelected($this->placeId, $image);
426
    }
427
428
    /**
429
     * @inheritdoc
430
     */
431
    protected function createTitleTranslatedEvent(Language $language, Title $title)
432
    {
433
        return new TitleTranslated($this->placeId, $language, $title);
434
    }
435
436
    /**
437
     * @param Title $title
438
     * @return TitleUpdated
439
     */
440
    protected function createTitleUpdatedEvent(Title $title)
441
    {
442
        return new TitleUpdated($this->placeId, $title);
443
    }
444
445
    /**
446
     * @inheritdoc
447
     */
448
    protected function createDescriptionTranslatedEvent(Language $language, Description $description)
449
    {
450
        return new DescriptionTranslated($this->placeId, $language, $description);
451
    }
452
453
    /**
454
     * @inheritdoc
455
     */
456
    protected function createDescriptionUpdatedEvent(Description $description)
457
    {
458
        return new DescriptionUpdated($this->placeId, $description);
459
    }
460
461
    /**
462
     * @inheritdoc
463
     */
464
    protected function createCalendarUpdatedEvent(Calendar $calendar)
465
    {
466
        return new CalendarUpdated($this->placeId, $calendar);
467
    }
468
469
    /**
470
     * @param AgeRange $typicalAgeRange
471
     * @return TypicalAgeRangeUpdated
472
     */
473
    protected function createTypicalAgeRangeUpdatedEvent($typicalAgeRange)
474
    {
475
        return new TypicalAgeRangeUpdated($this->placeId, $typicalAgeRange);
476
    }
477
478
    /**
479
     * @return TypicalAgeRangeDeleted
480
     */
481
    protected function createTypicalAgeRangeDeletedEvent()
482
    {
483
        return new TypicalAgeRangeDeleted($this->placeId);
484
    }
485
486
    /**
487
     * @param string $organizerId
488
     * @return OrganizerUpdated
489
     */
490
    protected function createOrganizerUpdatedEvent($organizerId)
491
    {
492
        return new OrganizerUpdated($this->placeId, $organizerId);
493
    }
494
495
    /**
496
     * @param string $organizerId
497
     * @return OrganizerDeleted
498
     */
499
    protected function createOrganizerDeletedEvent($organizerId)
500
    {
501
        return new OrganizerDeleted($this->placeId, $organizerId);
502
    }
503
504
    /**
505
     * @param ContactPoint $contactPoint
506
     * @return ContactPointUpdated
507
     */
508
    protected function createContactPointUpdatedEvent(ContactPoint $contactPoint)
509
    {
510
        return new ContactPointUpdated($this->placeId, $contactPoint);
511
    }
512
513
    /**
514
     * @inheritdoc
515
     */
516
    protected function createGeoCoordinatesUpdatedEvent(Coordinates $coordinates)
517
    {
518
        return new GeoCoordinatesUpdated($this->placeId, $coordinates);
519
    }
520
521
    /**
522
     * @param BookingInfo $bookingInfo
523
     * @return BookingInfoUpdated
524
     */
525
    protected function createBookingInfoUpdatedEvent(BookingInfo $bookingInfo)
526
    {
527
        return new BookingInfoUpdated($this->placeId, $bookingInfo);
528
    }
529
530
    /**
531
     * @param PriceInfo $priceInfo
532
     * @return PriceInfoUpdated
533
     */
534
    protected function createPriceInfoUpdatedEvent(PriceInfo $priceInfo)
535
    {
536
        return new PriceInfoUpdated($this->placeId, $priceInfo);
537
    }
538
539
    /**
540
     * @return PlaceDeleted
541
     */
542
    protected function createOfferDeletedEvent()
543
    {
544
        return new PlaceDeleted($this->placeId);
545
    }
546
547
    /**
548
     * @inheritDoc
549
     */
550
    protected function createPublishedEvent(\DateTimeInterface $publicationDate)
551
    {
552
        return new Published($this->placeId, $publicationDate);
553
    }
554
555
    /**
556
     * @inheritDoc
557
     */
558
    protected function createApprovedEvent()
559
    {
560
        return new Approved($this->placeId);
561
    }
562
563
    /**
564
     * @inheritDoc
565
     */
566
    protected function createRejectedEvent(StringLiteral $reason)
567
    {
568
        return new Rejected($this->placeId, $reason);
569
    }
570
571
    /**
572
     * @inheritDoc
573
     */
574
    protected function createFlaggedAsDuplicate()
575
    {
576
        return new FlaggedAsDuplicate($this->placeId);
577
    }
578
579
    /**
580
     * @inheritDoc
581
     */
582
    protected function createFlaggedAsInappropriate()
583
    {
584
        return new FlaggedAsInappropriate($this->placeId);
585
    }
586
587
    /**
588
     * @inheritDoc
589
     * @return ImagesImportedFromUDB2
590
     */
591
    protected function createImagesImportedFromUDB2(ImageCollection $images)
592
    {
593
        return new ImagesImportedFromUDB2($this->placeId, $images);
594
    }
595
596
    /**
597
     * @inheritDoc
598
     * @return ImagesUpdatedFromUDB2
599
     */
600
    protected function createImagesUpdatedFromUDB2(ImageCollection $images)
601
    {
602
        return new ImagesUpdatedFromUDB2($this->placeId, $images);
603
    }
604
605
    protected function createTypeUpdatedEvent(EventType $type)
606
    {
607
        return new TypeUpdated($this->placeId, $type);
608
    }
609
610
    protected function createThemeUpdatedEvent(Theme $theme)
611
    {
612
        return new ThemeUpdated($this->placeId, $theme);
613
    }
614
615
    /**
616
     * @inheritdoc
617
     */
618
    protected function createFacilitiesUpdatedEvent(array $facilities)
619
    {
620
        return new FacilitiesUpdated($this->placeId, $facilities);
621
    }
622
}
623