Completed
Pull Request — master (#336)
by Luc
04:29
created

Offer::updateFacilities()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace CultuurNet\UDB3\Offer;
4
5
use Broadway\EventSourcing\EventSourcedAggregateRoot;
6
use CultureFeed_Cdb_Item_Base;
7
use CultuurNet\UDB3\BookingInfo;
8
use CultuurNet\UDB3\Calendar;
9
use CultuurNet\UDB3\ContactPoint;
10
use CultuurNet\UDB3\Description;
11
use CultuurNet\UDB3\Event\EventType;
12
use CultuurNet\UDB3\Label;
13
use CultuurNet\UDB3\LabelAwareAggregateRoot;
14
use CultuurNet\UDB3\LabelCollection;
15
use CultuurNet\UDB3\Media\Image;
16
use CultuurNet\UDB3\Media\ImageCollection;
17
use CultuurNet\UDB3\Offer\Commands\Image\AbstractUpdateImage;
18
use CultuurNet\UDB3\Language;
19
use CultuurNet\UDB3\Offer\Events\AbstractBookingInfoUpdated;
20
use CultuurNet\UDB3\Offer\Events\AbstractContactPointUpdated;
21
use CultuurNet\UDB3\Offer\Events\AbstractFacilitiesUpdated;
22
use CultuurNet\UDB3\Offer\Events\AbstractThemeUpdated;
23
use CultuurNet\UDB3\Offer\Events\AbstractTitleTranslated;
24
use CultuurNet\UDB3\Offer\Events\AbstractTitleUpdated;
25
use CultuurNet\UDB3\Offer\Events\AbstractDescriptionTranslated;
26
use CultuurNet\UDB3\Offer\Events\AbstractDescriptionUpdated;
27
use CultuurNet\UDB3\Offer\Events\AbstractLabelAdded;
28
use CultuurNet\UDB3\Offer\Events\AbstractLabelRemoved;
29
use CultuurNet\UDB3\Offer\Events\AbstractOfferDeleted;
30
use CultuurNet\UDB3\Offer\Events\AbstractOrganizerDeleted;
31
use CultuurNet\UDB3\Offer\Events\AbstractOrganizerUpdated;
32
use CultuurNet\UDB3\Offer\Events\AbstractPriceInfoUpdated;
33
use CultuurNet\UDB3\Offer\Events\AbstractTypeUpdated;
34
use CultuurNet\UDB3\Offer\Events\AbstractTypicalAgeRangeDeleted;
35
use CultuurNet\UDB3\Offer\Events\AbstractTypicalAgeRangeUpdated;
36
use CultuurNet\UDB3\Offer\Events\Image\AbstractImageAdded;
37
use CultuurNet\UDB3\Offer\Events\Image\AbstractImageRemoved;
38
use CultuurNet\UDB3\Offer\Events\Image\AbstractImagesEvent;
39
use CultuurNet\UDB3\Offer\Events\Image\AbstractImagesImportedFromUDB2;
40
use CultuurNet\UDB3\Offer\Events\Image\AbstractImagesUpdatedFromUDB2;
41
use CultuurNet\UDB3\Offer\Events\Image\AbstractImageUpdated;
42
use CultuurNet\UDB3\Offer\Events\Image\AbstractMainImageSelected;
43
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractApproved;
44
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractFlaggedAsDuplicate;
45
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractFlaggedAsInappropriate;
46
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractPublished;
47
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractRejected;
48
use CultuurNet\UDB3\PriceInfo\PriceInfo;
49
use CultuurNet\UDB3\Theme;
50
use CultuurNet\UDB3\Title;
51
use Exception;
52
use ValueObjects\Identity\UUID;
53
use ValueObjects\StringLiteral\StringLiteral;
54
55
abstract class Offer extends EventSourcedAggregateRoot implements LabelAwareAggregateRoot
56
{
57
    const DUPLICATE_REASON = 'duplicate';
58
    const INAPPROPRIATE_REASON = 'inappropriate';
59
60
    /**
61
     * @var LabelCollection
62
     */
63
    protected $labels;
64
65
    /**
66
     * @var ImageCollection
67
     */
68
    protected $images;
69
70
    /**
71
     * @var string
72
     *
73
     * Organizer ids can come from UDB2 which does not strictly use UUIDs.
74
     */
75
    protected $organizerId;
76
77
    /**
78
     * @var WorkflowStatus
79
     */
80
    protected $workflowStatus;
81
82
    /**
83
     * @var StringLiteral|null
84
     */
85
    protected $rejectedReason;
86
87
    /**
88
     * @var PriceInfo
89
     */
90
    protected $priceInfo;
91
92
    /**
93
     * @var StringLiteral[]
94
     */
95
    protected $titles;
96
97
    /**
98
     * @var Description[]
99
     */
100
    protected $descriptions;
101
102
    /**
103
     * @var Language
104
     */
105
    protected $mainLanguage;
106
107
    /**
108
     * @var string;
109
     */
110
    protected $typeId;
111
112
    /**
113
     * @var string;
114
     */
115
    protected $themeId;
116
117
    /**
118
     * Offer constructor.
119
     */
120
    public function __construct()
121
    {
122
        // For now the main language is hard coded on nl.
123
        // In the future it should be set on create.
124
        $this->mainLanguage = new Language('nl');
125
126
        $this->titles = [];
127
        $this->descriptions = [];
128
        $this->labels = new LabelCollection();
129
        $this->images = new ImageCollection();
130
    }
131
132
    /**
133
     * @param EventType $type
134
     */
135
    public function updateType(EventType $type)
136
    {
137
        if (!$this->typeId || $this->typeId !== $type->getId()) {
138
            $this->apply($this->createTypeUpdatedEvent($type));
139
        }
140
    }
141
142
    /**
143
     * @param Theme $theme
144
     */
145
    public function updateTheme(Theme $theme)
146
    {
147
        if (!$this->themeId || $this->themeId !== $theme->getId()) {
148
            $this->apply($this->createThemeUpdatedEvent($theme));
149
        }
150
    }
151
152
    /**
153
     * @param array $facilities
154
     */
155
    public function updateFacilities(array $facilities)
156
    {
157
        $this->apply($this->createFacilitiesUpdatedEvent($facilities));
158
    }
159
160
    /**
161
     * Get the id of the main image if one is selected for this offer.
162
     *
163
     * @return UUID|null
164
     */
165
    protected function getMainImageId()
166
    {
167
        $mainImage = $this->images->getMain();
168
        return isset($mainImage) ? $mainImage->getMediaObjectId() : null;
169
    }
170
171
    /**
172
     * @inheritdoc
173
     */
174
    public function addLabel(Label $label)
175
    {
176
        if (!$this->labels->contains($label)) {
177
            $this->apply(
178
                $this->createLabelAddedEvent($label)
179
            );
180
        }
181
    }
182
183
    /**
184
     * @inheritdoc
185
     */
186
    public function removeLabel(Label $label)
187
    {
188
        if ($this->labels->contains($label)) {
189
            $this->apply(
190
                $this->createLabelRemovedEvent($label)
191
            );
192
        }
193
    }
194
195
    /**
196
     * @param Language $language
197
     * @param Title $title
198
     */
199
    public function updateTitle(Language $language, Title $title)
200
    {
201
        if ($this->isTitleChanged($title, $language)) {
202
            if ($language->getCode() !== $this->mainLanguage->getCode()) {
203
                $event = $this->createTitleTranslatedEvent($language, $title);
204
            } else {
205
                $event = $this->createTitleUpdatedEvent($title);
206
            }
207
208
            $this->apply($event);
209
        }
210
    }
211
212
    /**
213
     * @param Description $description
214
     * @param Language $language
215
     */
216
    public function updateDescription(Description $description, Language $language)
217
    {
218
        if ($this->isDescriptionChanged($description, $language)) {
219
            if ($language->getCode() !== $this->mainLanguage->getCode()) {
220
                $event = $this->createDescriptionTranslatedEvent($language, $description);
221
            } else {
222
                $event = $this->createDescriptionUpdatedEvent((string) $description);
223
            }
224
225
            $this->apply($event);
226
        }
227
    }
228
229
    /**
230
     * @param Calendar $calendar
231
     */
232
    public function updateCalendar(Calendar $calendar)
233
    {
234
        // For now no special business rules for updating the calendar.
235
        $this->apply(
236
            $this->createCalendarUpdatedEvent($calendar)
237
        );
238
    }
239
240
    /**
241
     * @param string $typicalAgeRange
242
     */
243
    public function updateTypicalAgeRange($typicalAgeRange)
244
    {
245
        $this->apply(
246
            $this->createTypicalAgeRangeUpdatedEvent($typicalAgeRange)
247
        );
248
    }
249
250
    public function deleteTypicalAgeRange()
251
    {
252
        $this->apply(
253
            $this->createTypicalAgeRangeDeletedEvent()
254
        );
255
    }
256
257
    /**
258
     * @param string $organizerId
259
     */
260
    public function updateOrganizer($organizerId)
261
    {
262
        if ($this->organizerId !== $organizerId) {
263
            $this->apply(
264
                $this->createOrganizerUpdatedEvent($organizerId)
265
            );
266
        }
267
    }
268
269
    /**
270
     * Delete the given organizer.
271
     *
272
     * @param string $organizerId
273
     */
274
    public function deleteOrganizer($organizerId)
275
    {
276
        if ($this->organizerId === $organizerId) {
277
            $this->apply(
278
                $this->createOrganizerDeletedEvent($organizerId)
279
            );
280
        }
281
    }
282
283
    /**
284
     * Updated the contact info.
285
     * @param ContactPoint $contactPoint
286
     */
287
    public function updateContactPoint(ContactPoint $contactPoint)
288
    {
289
        $this->apply(
290
            $this->createContactPointUpdatedEvent($contactPoint)
291
        );
292
    }
293
294
    /**
295
     * Updated the booking info.
296
     *
297
     * @param BookingInfo $bookingInfo
298
     */
299
    public function updateBookingInfo(BookingInfo $bookingInfo)
300
    {
301
        $this->apply(
302
            $this->createBookingInfoUpdatedEvent($bookingInfo)
303
        );
304
    }
305
306
    /**
307
     * @param PriceInfo $priceInfo
308
     */
309
    public function updatePriceInfo(PriceInfo $priceInfo)
310
    {
311
        if (is_null($this->priceInfo) || $priceInfo->serialize() !== $this->priceInfo->serialize()) {
312
            $this->apply(
313
                $this->createPriceInfoUpdatedEvent($priceInfo)
314
            );
315
        }
316
    }
317
318
    /**
319
     * @param AbstractPriceInfoUpdated $priceInfoUpdated
320
     */
321
    protected function applyPriceInfoUpdated(AbstractPriceInfoUpdated $priceInfoUpdated)
322
    {
323
        $this->priceInfo = $priceInfoUpdated->getPriceInfo();
324
    }
325
326
    /**
327
     * @param AbstractLabelAdded $labelAdded
328
     */
329
    protected function applyLabelAdded(AbstractLabelAdded $labelAdded)
330
    {
331
        $this->labels = $this->labels->with($labelAdded->getLabel());
332
    }
333
334
    /**
335
     * @param AbstractLabelRemoved $labelRemoved
336
     */
337
    protected function applyLabelRemoved(AbstractLabelRemoved $labelRemoved)
338
    {
339
        $this->labels = $this->labels->without($labelRemoved->getLabel());
340
    }
341
342
    /**
343
     * @param AbstractThemeUpdated $themeUpdated
344
     */
345
    protected function applyThemeUpdated(AbstractThemeUpdated $themeUpdated)
346
    {
347
        $this->themeId = $themeUpdated->getTheme()->getId();
348
    }
349
350
    /**
351
     * @param AbstractTypeUpdated $themeUpdated
352
     */
353
    protected function applyTypeUpdated(AbstractTypeUpdated $themeUpdated)
354
    {
355
        $this->typeId = $themeUpdated->getType()->getId();
356
    }
357
358
    protected function applyDescriptionUpdated(AbstractDescriptionUpdated $descriptionUpdated)
359
    {
360
        $mainLanguageCode = $this->mainLanguage->getCode();
361
        $this->descriptions[$mainLanguageCode] = new Description($descriptionUpdated->getDescription());
362
    }
363
364
    protected function applyDescriptionTranslated(AbstractDescriptionTranslated $descriptionTranslated)
365
    {
366
        $languageCode = $descriptionTranslated->getLanguage()->getCode();
367
        $this->descriptions[$languageCode] = $descriptionTranslated->getDescription();
368
    }
369
370
    /**
371
     * Add a new image.
372
     *
373
     * @param Image $image
374
     */
375
    public function addImage(Image $image)
376
    {
377
        if (!$this->images->contains($image)) {
378
            $this->apply(
379
                $this->createImageAddedEvent($image)
380
            );
381
        }
382
    }
383
384
    /**
385
     * @param AbstractUpdateImage $updateImageCommand
386
     */
387
    public function updateImage(AbstractUpdateImage $updateImageCommand)
388
    {
389
        if ($this->images->findImageByUUID($updateImageCommand->getMediaObjectId())) {
390
            $this->apply(
391
                $this->createImageUpdatedEvent($updateImageCommand)
392
            );
393
        }
394
    }
395
396
    /**
397
     * Remove an image.
398
     *
399
     * @param Image $image
400
     */
401
    public function removeImage(Image $image)
402
    {
403
        if ($this->images->contains($image)) {
404
            $this->apply(
405
                $this->createImageRemovedEvent($image)
406
            );
407
        }
408
    }
409
410
    /**
411
     * Make an existing image of the item the main image.
412
     *
413
     * @param Image $image
414
     */
415
    public function selectMainImage(Image $image)
416
    {
417
        if (!$this->images->contains($image)) {
418
            throw new \InvalidArgumentException('You can not select a random image to be main, it has to be added to the item.');
419
        }
420
421
        $oldMainImage = $this->images->getMain();
422
423
        if (!isset($oldMainImage) || $oldMainImage->getMediaObjectId() !== $image->getMediaObjectId()) {
424
            $this->apply(
425
                $this->createMainImageSelectedEvent($image)
426
            );
427
        }
428
    }
429
430
    /**
431
     * Delete the offer.
432
     */
433
    public function delete()
434
    {
435
        $this->apply(
436
            $this->createOfferDeletedEvent()
437
        );
438
    }
439
440
    /**
441
     * @param CultureFeed_Cdb_Item_Base $cdbItem
442
     */
443
    protected function importWorkflowStatus(CultureFeed_Cdb_Item_Base $cdbItem)
444
    {
445
        try {
446
            $workflowStatus = WorkflowStatus::fromNative($cdbItem->getWfStatus());
447
        } catch (\InvalidArgumentException $exception) {
448
            $workflowStatus = WorkflowStatus::READY_FOR_VALIDATION();
449
        }
450
        $this->workflowStatus = $workflowStatus;
451
    }
452
453
    /**
454
     * Publish the offer when it has workflowstatus draft.
455
     * @param \DateTimeInterface $publicationDate
456
     */
457
    public function publish(\DateTimeInterface $publicationDate)
458
    {
459
        $this->guardPublish() ?: $this->apply(
460
            $this->createPublishedEvent($publicationDate)
461
        );
462
    }
463
464
    /**
465
     * @return bool
466
     * @throws Exception
467
     */
468 View Code Duplication
    private function guardPublish()
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...
469
    {
470
        if ($this->workflowStatus === WorkflowStatus::READY_FOR_VALIDATION()) {
471
            return true; // nothing left to do if the offer has already been published
472
        }
473
474
        if ($this->workflowStatus !== WorkflowStatus::DRAFT()) {
475
            throw new Exception('You can not publish an offer that is not draft');
476
        }
477
478
        return false;
479
    }
480
481
    /**
482
     * Approve the offer when it's waiting for validation.
483
     */
484
    public function approve()
485
    {
486
        $this->guardApprove() ?: $this->apply($this->createApprovedEvent());
487
    }
488
489
    /**
490
     * @return bool
491
     * @throws Exception
492
     */
493 View Code Duplication
    private function guardApprove()
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...
494
    {
495
        if ($this->workflowStatus === WorkflowStatus::APPROVED()) {
496
            return true; // nothing left to do if the offer has already been approved
497
        }
498
499
        if ($this->workflowStatus !== WorkflowStatus::READY_FOR_VALIDATION()) {
500
            throw new Exception('You can not approve an offer that is not ready for validation');
501
        }
502
503
        return false;
504
    }
505
506
    /**
507
     * Reject an offer that is waiting for validation with a given reason.
508
     * @param StringLiteral $reason
509
     */
510
    public function reject(StringLiteral $reason)
511
    {
512
        $this->guardRejection($reason) ?: $this->apply($this->createRejectedEvent($reason));
513
    }
514
515
    public function flagAsDuplicate()
516
    {
517
        $reason = new StringLiteral(self::DUPLICATE_REASON);
518
        $this->guardRejection($reason) ?: $this->apply($this->createFlaggedAsDuplicate());
519
    }
520
521
    public function flagAsInappropriate()
522
    {
523
        $reason = new StringLiteral(self::INAPPROPRIATE_REASON);
524
        $this->guardRejection($reason) ?: $this->apply($this->createFlaggedAsInappropriate());
525
    }
526
527
    /**
528
     * @param StringLiteral $reason
529
     * @return bool
530
     *  false when the offer can still be rejected, true when the offer is already rejected for the same reason
531
     * @throws Exception
532
     */
533
    private function guardRejection(StringLiteral $reason)
534
    {
535
        if ($this->workflowStatus === WorkflowStatus::REJECTED()) {
536
            if ($this->rejectedReason && $reason->sameValueAs($this->rejectedReason)) {
537
                return true; // nothing left to do if the offer has already been rejected for the same reason
538
            } else {
539
                throw new Exception('The offer has already been rejected for another reason: ' . $this->rejectedReason);
540
            }
541
        }
542
543
        if ($this->workflowStatus !== WorkflowStatus::READY_FOR_VALIDATION()) {
544
            throw new Exception('You can not reject an offer that is not ready for validation');
545
        }
546
547
        return false;
548
    }
549
550
    /**
551
     * @param Title $title
552
     * @param Language $language
553
     * @return bool
554
     */
555 View Code Duplication
    private function isTitleChanged(Title $title, Language $language)
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...
556
    {
557
        $languageCode = $language->getCode();
558
559
        return !isset($this->titles[$languageCode]) ||
560
            !$title->sameValueAs($this->titles[$languageCode]);
561
    }
562
563
    /**
564
     * @param Description $description
565
     * @param Language $language
566
     * @return bool
567
     */
568 View Code Duplication
    private function isDescriptionChanged(Description $description, Language $language)
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...
569
    {
570
        $languageCode = $language->getCode();
571
572
        return !isset($this->descriptions[$languageCode]) ||
573
            !$description->sameValueAs($this->descriptions[$languageCode]);
574
    }
575
576
    /**
577
     * Overwrites or resets the main image and all media objects
578
     * by importing a new collection of images from UDB2.
579
     *
580
     * @param ImageCollection $images
581
     */
582
    public function importImagesFromUDB2(ImageCollection $images)
583
    {
584
        $this->apply($this->createImagesImportedFromUDB2($images));
585
    }
586
587
    /**
588
     * Overwrites or resets the main image and all media objects
589
     * by updating with a new collection of images from UDB2.
590
     *
591
     * @param ImageCollection $images
592
     */
593
    public function updateImagesFromUDB2(ImageCollection $images)
594
    {
595
        $this->apply($this->createImagesUpdatedFromUDB2($images));
596
    }
597
598
    /**
599
     * @param AbstractPublished $published
600
     */
601
    protected function applyPublished(AbstractPublished $published)
0 ignored issues
show
Unused Code introduced by
The parameter $published 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...
602
    {
603
        $this->workflowStatus = WorkflowStatus::READY_FOR_VALIDATION();
604
    }
605
606
    /**
607
     * @param AbstractApproved $approved
608
     */
609
    protected function applyApproved(AbstractApproved $approved)
0 ignored issues
show
Unused Code introduced by
The parameter $approved 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...
610
    {
611
        $this->workflowStatus = WorkflowStatus::APPROVED();
612
    }
613
614
    /**
615
     * @param AbstractRejected $rejected
616
     */
617
    protected function applyRejected(AbstractRejected $rejected)
618
    {
619
        $this->rejectedReason = $rejected->getReason();
620
        $this->workflowStatus = WorkflowStatus::REJECTED();
621
    }
622
623
    /**
624
     * @param AbstractFlaggedAsDuplicate $flaggedAsDuplicate
625
     */
626
    protected function applyFlaggedAsDuplicate(AbstractFlaggedAsDuplicate $flaggedAsDuplicate)
0 ignored issues
show
Unused Code introduced by
The parameter $flaggedAsDuplicate 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...
627
    {
628
        $this->rejectedReason = new StringLiteral(self::DUPLICATE_REASON);
629
        $this->workflowStatus = WorkflowStatus::REJECTED();
630
    }
631
632
    /**
633
     * @param AbstractFlaggedAsInappropriate $flaggedAsInappropriate
634
     */
635
    protected function applyFlaggedAsInappropriate(AbstractFlaggedAsInappropriate $flaggedAsInappropriate)
0 ignored issues
show
Unused Code introduced by
The parameter $flaggedAsInappropriate 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...
636
    {
637
        $this->rejectedReason = new StringLiteral(self::INAPPROPRIATE_REASON);
638
        $this->workflowStatus = WorkflowStatus::REJECTED();
639
    }
640
641
    protected function applyImageAdded(AbstractImageAdded $imageAdded)
642
    {
643
        $this->images = $this->images->with($imageAdded->getImage());
644
    }
645
646
    protected function applyImageRemoved(AbstractImageRemoved $imageRemoved)
647
    {
648
        $this->images = $this->images->without($imageRemoved->getImage());
649
    }
650
651
    protected function applyMainImageSelected(AbstractMainImageSelected $mainImageSelected)
652
    {
653
        $this->images = $this->images->withMain($mainImageSelected->getImage());
654
    }
655
656
    protected function applyOrganizerUpdated(AbstractOrganizerUpdated $organizerUpdated)
657
    {
658
        $this->organizerId = $organizerUpdated->getOrganizerId();
659
    }
660
661
    protected function applyOrganizerDeleted(AbstractOrganizerDeleted $organizerDeleted)
0 ignored issues
show
Unused Code introduced by
The parameter $organizerDeleted 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...
662
    {
663
        $this->organizerId = null;
664
    }
665
666
    /**
667
     * @param AbstractImagesImportedFromUDB2 $imagesImportedFromUDB2
668
     */
669
    protected function applyImagesImportedFromUDB2(AbstractImagesImportedFromUDB2 $imagesImportedFromUDB2)
670
    {
671
        $this->applyUdb2ImagesEvent($imagesImportedFromUDB2);
672
    }
673
674
    /**
675
     * @param AbstractImagesUpdatedFromUDB2 $imagesUpdatedFromUDB2
676
     */
677
    protected function applyImagesUpdatedFromUDB2(AbstractImagesUpdatedFromUDB2 $imagesUpdatedFromUDB2)
678
    {
679
        $this->applyUdb2ImagesEvent($imagesUpdatedFromUDB2);
680
    }
681
682
    /**
683
     * This indirect apply method can be called internally to deal with images coming from UDB2.
684
     * Imports from UDB2 only contain the native Dutch content.
685
     * @see https://github.com/cultuurnet/udb3-udb2-bridge/blob/db0a7ab2444f55bb3faae3d59b82b39aaeba253b/test/Media/ImageCollectionFactoryTest.php#L79-L103
686
     * Because of this we have to make sure translated images are left in place.
687
     *
688
     * @param AbstractImagesEvent $imagesEvent
689
     */
690
    protected function applyUdb2ImagesEvent(AbstractImagesEvent $imagesEvent)
691
    {
692
        $newMainImage = $imagesEvent->getImages()->getMain();
693
        $dutchImagesList = $imagesEvent->getImages()->toArray();
694
        $translatedImagesList = array_filter(
695
            $this->images->toArray(),
696
            function (Image $image) {
697
                return $image->getLanguage()->getCode() !== 'nl';
698
            }
699
        );
700
701
        $imagesList = array_merge($dutchImagesList, $translatedImagesList);
702
        $images = ImageCollection::fromArray($imagesList);
703
704
        $this->images = isset($newMainImage) ? $images->withMain($newMainImage) : $images;
705
    }
706
707
    /**
708
     * @param Label $label
709
     * @return AbstractLabelAdded
710
     */
711
    abstract protected function createLabelAddedEvent(Label $label);
712
713
    /**
714
     * @param Label $label
715
     * @return AbstractLabelRemoved
716
     */
717
    abstract protected function createLabelRemovedEvent(Label $label);
718
719
    /**
720
     * @param Language $language
721
     * @param StringLiteral $title
722
     * @return AbstractTitleTranslated
723
     */
724
    abstract protected function createTitleTranslatedEvent(Language $language, StringLiteral $title);
725
726
    /**
727
     * @param Language $language
728
     * @param StringLiteral $description
729
     * @return AbstractDescriptionTranslated
730
     */
731
    abstract protected function createDescriptionTranslatedEvent(Language $language, StringLiteral $description);
732
733
    /**
734
     * @param Image $image
735
     * @return AbstractImageAdded
736
     */
737
    abstract protected function createImageAddedEvent(Image $image);
738
739
    /**
740
     * @param Image $image
741
     * @return AbstractImageRemoved
742
     */
743
    abstract protected function createImageRemovedEvent(Image $image);
744
745
    /**
746
     * @param AbstractUpdateImage $updateImageCommand
747
     * @return AbstractImageUpdated
748
     */
749
    abstract protected function createImageUpdatedEvent(
750
        AbstractUpdateImage $updateImageCommand
751
    );
752
753
    /**
754
     * @param Image $image
755
     * @return AbstractMainImageSelected
756
     */
757
    abstract protected function createMainImageSelectedEvent(Image $image);
758
759
    /**
760
     * @return AbstractOfferDeleted
761
     */
762
    abstract protected function createOfferDeletedEvent();
763
764
    /**
765
     * @param Title $title
766
     * @return AbstractTitleUpdated
767
     */
768
    abstract protected function createTitleUpdatedEvent(Title $title);
769
770
    /**
771
     * @param string $description
772
     * @return AbstractDescriptionUpdated
773
     */
774
    abstract protected function createDescriptionUpdatedEvent($description);
775
776
    /**
777
     * @param Calendar $calendar
778
     * @return AbstractCalendarUpdated
779
     */
780
    abstract protected function createCalendarUpdatedEvent(Calendar $calendar);
781
782
    /**
783
     * @param string $typicalAgeRange
784
     * @return AbstractTypicalAgeRangeUpdated
785
     */
786
    abstract protected function createTypicalAgeRangeUpdatedEvent($typicalAgeRange);
787
788
    /**
789
     * @return AbstractTypicalAgeRangeDeleted
790
     */
791
    abstract protected function createTypicalAgeRangeDeletedEvent();
792
793
    /**
794
     * @param string $organizerId
795
     * @return AbstractOrganizerUpdated
796
     */
797
    abstract protected function createOrganizerUpdatedEvent($organizerId);
798
799
    /**
800
     * @param string $organizerId
801
     * @return AbstractOrganizerDeleted
802
     */
803
    abstract protected function createOrganizerDeletedEvent($organizerId);
804
805
    /**
806
     * @param ContactPoint $contactPoint
807
     * @return AbstractContactPointUpdated
808
     */
809
    abstract protected function createContactPointUpdatedEvent(ContactPoint $contactPoint);
810
811
    /**
812
     * @param BookingInfo $bookingInfo
813
     * @return AbstractBookingInfoUpdated
814
     */
815
    abstract protected function createBookingInfoUpdatedEvent(BookingInfo $bookingInfo);
816
817
    /**
818
     * @param PriceInfo $priceInfo
819
     * @return AbstractPriceInfoUpdated
820
     */
821
    abstract protected function createPriceInfoUpdatedEvent(PriceInfo $priceInfo);
822
823
    /**
824
     * @param \DateTimeInterface $publicationDate
825
     * @return AbstractPublished
826
     */
827
    abstract protected function createPublishedEvent(\DateTimeInterface $publicationDate);
828
829
    /**
830
     * @return AbstractApproved
831
     */
832
    abstract protected function createApprovedEvent();
833
834
    /**
835
     * @param StringLiteral $reason
836
     * @return AbstractRejected
837
     */
838
    abstract protected function createRejectedEvent(StringLiteral $reason);
839
840
    /**
841
     * @return AbstractFlaggedAsDuplicate
842
     */
843
    abstract protected function createFlaggedAsDuplicate();
844
845
    /**
846
     * @return AbstractFlaggedAsInappropriate
847
     */
848
    abstract protected function createFlaggedAsInappropriate();
849
850
    /**
851
     * @param ImageCollection $images
852
     * @return AbstractImagesImportedFromUDB2
853
     */
854
    abstract protected function createImagesImportedFromUDB2(ImageCollection $images);
855
856
    /**
857
     * @param ImageCollection $images
858
     * @return AbstractImagesUpdatedFromUDB2
859
     */
860
    abstract protected function createImagesUpdatedFromUDB2(ImageCollection $images);
861
862
    /**
863
     * @param EventType $type
864
     * @return AbstractTypeUpdated
865
     */
866
    abstract protected function createTypeUpdatedEvent(EventType $type);
867
868
    /**
869
     * @param Theme $theme
870
     * @return AbstractThemeUpdated
871
     */
872
    abstract protected function createThemeUpdatedEvent(Theme $theme);
873
874
    /**
875
     * @param array $facilities
876
     * @return AbstractFacilitiesUpdated
877
     */
878
    abstract protected function createFacilitiesUpdatedEvent(array $facilities);
879
}
880