Completed
Pull Request — master (#342)
by Luc
04:51
created

Offer::importWorkflowStatus()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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