Completed
Push — master ( 3bc119...0177d6 )
by Jonas
23s queued 11s
created

Place::applyMarkedAsCanonical()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
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
    public function __construct()
93
    {
94
        parent::__construct();
95
96
        $this->addresses = [];
97
    }
98
99
    /**
100
     * {@inheritdoc}
101
     */
102
    public function getAggregateRootId()
103
    {
104
        return $this->placeId;
105
    }
106
107
    /**
108
     * @todo Rename this method to create() after moving this part of the codebase to udb3-silex
109
     */
110
    public static function createPlace(
111
        string $id,
112
        Language $mainLanguage,
113
        Title $title,
114
        EventType $eventType,
115
        Address $address,
116
        CalendarInterface $calendar,
117
        Theme $theme = null,
118
        DateTimeImmutable $publicationDate = null
119
    ): self {
120
        $place = new self();
121
        $place->apply(new PlaceCreated(
122
            $id,
123
            $mainLanguage,
124
            $title,
125
            $eventType,
126
            $address,
127
            $calendar,
128
            $theme,
129
            $publicationDate
130
        ));
131
132
        return $place;
133
    }
134
135 View Code Duplication
    protected function applyPlaceCreated(PlaceCreated $placeCreated): void
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...
136
    {
137
        $this->mainLanguage = $placeCreated->getMainLanguage();
138
        $this->titles[$this->mainLanguage->getCode()] = $placeCreated->getTitle();
139
        $this->calendar = $placeCreated->getCalendar();
140
        $this->contactPoint = new ContactPoint();
141
        $this->bookingInfo = new BookingInfo();
142
        $this->typeId = $placeCreated->getEventType()->getId();
143
        $this->themeId = $placeCreated->getTheme() ? $placeCreated->getTheme()->getId() : null;
144
        $this->addresses[$this->mainLanguage->getCode()] = $placeCreated->getAddress();
145
        $this->placeId = $placeCreated->getPlaceId();
146
        $this->workflowStatus = WorkflowStatus::DRAFT();
147
    }
148
149
    public function updateMajorInfo(
150
        Title $title,
151
        EventType $eventType,
152
        Address $address,
153
        CalendarInterface $calendar,
154
        Theme $theme = null
155
    ): void {
156
        $this->apply(
157
            new MajorInfoUpdated(
158
                $this->placeId,
159
                $title,
160
                $eventType,
161
                $address,
162
                $calendar,
163
                $theme
164
            )
165
        );
166
    }
167
168
    protected function applyMajorInfoUpdated(MajorInfoUpdated $majorInfoUpdated): void
169
    {
170
        $this->addresses[$this->mainLanguage->getCode()] = $majorInfoUpdated->getAddress();
171
    }
172
173 View Code Duplication
    public function updateAddress(Address $address, Language $language): void
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...
174
    {
175
        if ($language->getCode() === $this->mainLanguage->getCode()) {
176
            $event = new AddressUpdated($this->placeId, $address);
177
        } else {
178
            $event = new AddressTranslated($this->placeId, $address, $language);
179
        }
180
181
        if ($this->allowAddressUpdate($address, $language)) {
182
            $this->apply($event);
183
        }
184
    }
185
186
    protected function applyAddressUpdated(AddressUpdated $addressUpdated): void
187
    {
188
        $this->addresses[$this->mainLanguage->getCode()] = $addressUpdated->getAddress();
189
    }
190
191
    protected function applyAddressTranslated(AddressTranslated $addressTranslated): void
192
    {
193
        $this->addresses[$addressTranslated->getLanguage()->getCode()] = $addressTranslated->getAddress();
194
    }
195
196 View Code Duplication
    public function markAsDuplicateOf(string $placeIdOfCanonical): void
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...
197
    {
198
        if ($this->isDeleted) {
199
            throw CannotMarkPlaceAsDuplicate::becauseItIsDeleted($this->placeId);
200
        }
201
202
        if ($this->isDuplicate) {
203
            throw CannotMarkPlaceAsDuplicate::becauseItIsAlreadyADuplicate($this->placeId);
204
        }
205
206
        $this->apply(new MarkedAsDuplicate($this->placeId, $placeIdOfCanonical));
207
    }
208
209 View Code Duplication
    public function markAsCanonicalFor(string $placeIdOfDuplicate, array $duplicatesOfDuplicate = []): void
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...
210
    {
211
        if ($this->isDeleted) {
212
            throw CannotMarkPlaceAsCanonical::becauseItIsDeleted($this->placeId);
213
        }
214
215
        if ($this->isDuplicate) {
216
            throw CannotMarkPlaceAsCanonical::becauseItIsAlreadyADuplicate($this->placeId);
217
        }
218
219
        $this->apply(new MarkedAsCanonical($this->placeId, $placeIdOfDuplicate, $duplicatesOfDuplicate));
220
    }
221
222
    /**
223
     * @return string[]
224
     */
225
    public function getDuplicates(): array
226
    {
227
        return $this->duplicates;
228
    }
229
230
    private function allowAddressUpdate(Address $address, Language $language): bool
231
    {
232
        // No current address in the provided language so update with new address is allowed.
233
        if (!isset($this->addresses[$language->getCode()])) {
234
            return true;
235
        }
236
237
        // The current address in de the provided language is different then the new address, so update allowed.
238
        if (!$this->addresses[$language->getCode()]->sameAs($address)) {
239
            return true;
240
        }
241
242
        return false;
243
    }
244
245
    public static function importFromUDB2Actor(
246
        string $actorId,
247
        string $cdbXml,
248
        string $cdbXmlNamespaceUri
249
    ): self {
250
        $place = new static();
251
        $place->apply(
252
            new PlaceImportedFromUDB2(
253
                $actorId,
254
                $cdbXml,
255
                $cdbXmlNamespaceUri
256
            )
257
        );
258
259
        return $place;
260
    }
261
262
    protected function applyPlaceImportedFromUDB2(PlaceImportedFromUDB2 $placeImported): void
263
    {
264
        $this->placeId = $placeImported->getActorId();
265
266
        // When importing from UDB2 the default main language is always 'nl'.
267
        $this->mainLanguage = new Language('nl');
268
269
        $udb2Actor = ActorItemFactory::createActorFromCdbXml(
270
            $placeImported->getCdbXmlNamespaceUri(),
271
            $placeImported->getCdbXml()
272
        );
273
274
        // Just clear the facilities.
275
        $this->facilities = [];
276
277
        // Just clear the contact point.
278
        $this->contactPoint = null;
279
280
        // Just clear the calendar.
281
        $this->calendar = null;
282
283
        // Note: an actor has no typical age range so after it can't be changed
284
        // by an UDB2 update. Nothing has to be done.
285
286
        // Just clear the booking info.
287
        $this->bookingInfo = null;
288
289
        // Just clear the price info.
290
        $this->priceInfo = null;
291
292
        $this->importWorkflowStatus($udb2Actor);
293
        $this->labels = LabelCollection::fromKeywords($udb2Actor->getKeywords(true));
294
    }
295
296
    protected function applyPlaceUpdatedFromUDB2(PlaceUpdatedFromUDB2 $placeUpdatedFromUDB2): void
297
    {
298
        // Note: when updating from UDB2 never change the main language.
299
300
        $udb2Actor = ActorItemFactory::createActorFromCdbXml(
301
            $placeUpdatedFromUDB2->getCdbXmlNamespaceUri(),
302
            $placeUpdatedFromUDB2->getCdbXml()
303
        );
304
305
        // Just clear the facilities.
306
        $this->facilities = [];
307
308
        // Just clear the contact point.
309
        $this->contactPoint = null;
310
311
        // Just clear the calendar.
312
        $this->calendar = null;
313
314
        // Note: an actor has no typical age range so after it can't be changed
315
        // by an UDB2 update. Nothing has to be done.
316
317
        // Just clear the booking info.
318
        $this->bookingInfo = null;
319
320
        // Just clear the price info.
321
        $this->priceInfo = null;
322
323
        $this->importWorkflowStatus($udb2Actor);
324
        $this->labels = LabelCollection::fromKeywords($udb2Actor->getKeywords(true));
325
326
        unset($this->addresses[$this->mainLanguage->getCode()]);
327
    }
328
329
    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...
330
    {
331
        $this->isDeleted = true;
332
    }
333
334
    protected function applyMarkedAsDuplicate(MarkedAsDuplicate $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->isDuplicate = true;
337
    }
338
339
    protected function applyMarkedAsCanonical(MarkedAsCanonical $event): void
340
    {
341
        $this->duplicates[] = $event->getDuplicatedBy();
342
        foreach ($event->getDuplicatesOfDuplicate() as $duplicateOfDuplicate) {
343
            $this->duplicates[] = $duplicateOfDuplicate;
344
        }
345
    }
346
347
    /**
348
     * @inheritdoc
349
     */
350
    public function updateWithCdbXml($cdbXml, $cdbXmlNamespaceUri)
351
    {
352
        ActorItemFactory::createActorFromCdbXml($cdbXmlNamespaceUri, $cdbXml);
353
354
        $this->apply(
355
            new PlaceUpdatedFromUDB2(
356
                $this->placeId,
357
                $cdbXml,
358
                $cdbXmlNamespaceUri
359
            )
360
        );
361
    }
362
363
    /**
364
     * @param Label $label
365
     * @return LabelAdded
366
     */
367
    protected function createLabelAddedEvent(Label $label)
368
    {
369
        return new LabelAdded($this->placeId, $label);
370
    }
371
372
    /**
373
     * @param Label $label
374
     * @return LabelRemoved
375
     */
376
    protected function createLabelRemovedEvent(Label $label)
377
    {
378
        return new LabelRemoved($this->placeId, $label);
379
    }
380
381
    /**
382
     * @inheritdoc
383
     */
384
    protected function createLabelsImportedEvent(Labels $labels)
385
    {
386
        return new LabelsImported($this->placeId, $labels);
387
    }
388
389
    protected function createImageAddedEvent(Image $image)
390
    {
391
        return new ImageAdded($this->placeId, $image);
392
    }
393
394
    protected function createImageRemovedEvent(Image $image)
395
    {
396
        return new ImageRemoved($this->placeId, $image);
397
    }
398
399
    protected function createImageUpdatedEvent(
400
        UUID $mediaObjectId,
401
        StringLiteral $description,
402
        StringLiteral $copyrightHolder
403
    ) {
404
        return new ImageUpdated(
405
            $this->placeId,
406
            $mediaObjectId,
407
            $description,
408
            $copyrightHolder
409
        );
410
    }
411
412
    protected function createMainImageSelectedEvent(Image $image)
413
    {
414
        return new MainImageSelected($this->placeId, $image);
415
    }
416
417
    /**
418
     * @inheritdoc
419
     */
420
    protected function createTitleTranslatedEvent(Language $language, Title $title)
421
    {
422
        return new TitleTranslated($this->placeId, $language, $title);
423
    }
424
425
    /**
426
     * @param Title $title
427
     * @return TitleUpdated
428
     */
429
    protected function createTitleUpdatedEvent(Title $title)
430
    {
431
        return new TitleUpdated($this->placeId, $title);
432
    }
433
434
    /**
435
     * @inheritdoc
436
     */
437
    protected function createDescriptionTranslatedEvent(Language $language, Description $description)
438
    {
439
        return new DescriptionTranslated($this->placeId, $language, $description);
440
    }
441
442
    /**
443
     * @inheritdoc
444
     */
445
    protected function createDescriptionUpdatedEvent(Description $description)
446
    {
447
        return new DescriptionUpdated($this->placeId, $description);
448
    }
449
450
    /**
451
     * @inheritdoc
452
     */
453
    protected function createCalendarUpdatedEvent(Calendar $calendar)
454
    {
455
        return new CalendarUpdated($this->placeId, $calendar);
456
    }
457
458
    /**
459
     * @param AgeRange $typicalAgeRange
460
     * @return TypicalAgeRangeUpdated
461
     */
462
    protected function createTypicalAgeRangeUpdatedEvent($typicalAgeRange)
463
    {
464
        return new TypicalAgeRangeUpdated($this->placeId, $typicalAgeRange);
465
    }
466
467
    /**
468
     * @return TypicalAgeRangeDeleted
469
     */
470
    protected function createTypicalAgeRangeDeletedEvent()
471
    {
472
        return new TypicalAgeRangeDeleted($this->placeId);
473
    }
474
475
    /**
476
     * @param string $organizerId
477
     * @return OrganizerUpdated
478
     */
479
    protected function createOrganizerUpdatedEvent($organizerId)
480
    {
481
        return new OrganizerUpdated($this->placeId, $organizerId);
482
    }
483
484
    /**
485
     * @param string $organizerId
486
     * @return OrganizerDeleted
487
     */
488
    protected function createOrganizerDeletedEvent($organizerId)
489
    {
490
        return new OrganizerDeleted($this->placeId, $organizerId);
491
    }
492
493
    /**
494
     * @param ContactPoint $contactPoint
495
     * @return ContactPointUpdated
496
     */
497
    protected function createContactPointUpdatedEvent(ContactPoint $contactPoint)
498
    {
499
        return new ContactPointUpdated($this->placeId, $contactPoint);
500
    }
501
502
    /**
503
     * @inheritdoc
504
     */
505
    protected function createGeoCoordinatesUpdatedEvent(Coordinates $coordinates)
506
    {
507
        return new GeoCoordinatesUpdated($this->placeId, $coordinates);
508
    }
509
510
    /**
511
     * @param BookingInfo $bookingInfo
512
     * @return BookingInfoUpdated
513
     */
514
    protected function createBookingInfoUpdatedEvent(BookingInfo $bookingInfo)
515
    {
516
        return new BookingInfoUpdated($this->placeId, $bookingInfo);
517
    }
518
519
    /**
520
     * @param PriceInfo $priceInfo
521
     * @return PriceInfoUpdated
522
     */
523
    protected function createPriceInfoUpdatedEvent(PriceInfo $priceInfo)
524
    {
525
        return new PriceInfoUpdated($this->placeId, $priceInfo);
526
    }
527
528
    /**
529
     * @return PlaceDeleted
530
     */
531
    protected function createOfferDeletedEvent()
532
    {
533
        return new PlaceDeleted($this->placeId);
534
    }
535
536
    /**
537
     * @inheritDoc
538
     */
539
    protected function createPublishedEvent(\DateTimeInterface $publicationDate)
540
    {
541
        return new Published($this->placeId, $publicationDate);
542
    }
543
544
    /**
545
     * @inheritDoc
546
     */
547
    protected function createApprovedEvent()
548
    {
549
        return new Approved($this->placeId);
550
    }
551
552
    /**
553
     * @inheritDoc
554
     */
555
    protected function createRejectedEvent(StringLiteral $reason)
556
    {
557
        return new Rejected($this->placeId, $reason);
558
    }
559
560
    /**
561
     * @inheritDoc
562
     */
563
    protected function createFlaggedAsDuplicate()
564
    {
565
        return new FlaggedAsDuplicate($this->placeId);
566
    }
567
568
    /**
569
     * @inheritDoc
570
     */
571
    protected function createFlaggedAsInappropriate()
572
    {
573
        return new FlaggedAsInappropriate($this->placeId);
574
    }
575
576
    /**
577
     * @inheritDoc
578
     * @return ImagesImportedFromUDB2
579
     */
580
    protected function createImagesImportedFromUDB2(ImageCollection $images)
581
    {
582
        return new ImagesImportedFromUDB2($this->placeId, $images);
583
    }
584
585
    /**
586
     * @inheritDoc
587
     * @return ImagesUpdatedFromUDB2
588
     */
589
    protected function createImagesUpdatedFromUDB2(ImageCollection $images)
590
    {
591
        return new ImagesUpdatedFromUDB2($this->placeId, $images);
592
    }
593
594
    protected function createTypeUpdatedEvent(EventType $type)
595
    {
596
        return new TypeUpdated($this->placeId, $type);
597
    }
598
599
    protected function createThemeUpdatedEvent(Theme $theme)
600
    {
601
        return new ThemeUpdated($this->placeId, $theme);
602
    }
603
604
    /**
605
     * @inheritdoc
606
     */
607
    protected function createFacilitiesUpdatedEvent(array $facilities)
608
    {
609
        return new FacilitiesUpdated($this->placeId, $facilities);
610
    }
611
}
612