Completed
Pull Request — master (#328)
by Luc
04:54
created

Offer::applyThemeUpdated()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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