Completed
Pull Request — master (#342)
by Luc
12:45
created

Event::createImageAddedEvent()   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\Event;
4
5
use Broadway\EventSourcing\EventSourcedAggregateRoot;
6
use CultuurNet\Geocoding\Coordinate\Coordinates;
7
use CultuurNet\UDB3\BookingInfo;
8
use CultuurNet\UDB3\Calendar;
9
use CultuurNet\UDB3\CalendarInterface;
10
use CultuurNet\UDB3\Cdb\EventItemFactory;
11
use CultuurNet\UDB3\Cdb\UpdateableWithCdbXmlInterface;
12
use CultuurNet\UDB3\ContactPoint;
13
use CultuurNet\UDB3\Event\Events\AudienceUpdated;
14
use CultuurNet\UDB3\Event\Events\BookingInfoUpdated;
15
use CultuurNet\UDB3\Event\Events\CalendarUpdated;
16
use CultuurNet\UDB3\Event\Events\Concluded;
17
use CultuurNet\UDB3\Event\Events\ContactPointUpdated;
18
use CultuurNet\UDB3\Event\Events\DescriptionTranslated;
19
use CultuurNet\UDB3\Event\Events\DescriptionUpdated;
20
use CultuurNet\UDB3\Event\Events\EventCdbXMLInterface;
21
use CultuurNet\UDB3\Event\Events\EventCopied;
22
use CultuurNet\UDB3\Event\Events\EventCreated;
23
use CultuurNet\UDB3\Event\Events\EventDeleted;
24
use CultuurNet\UDB3\Event\Events\EventImportedFromUDB2;
25
use CultuurNet\UDB3\Event\Events\EventUpdatedFromUDB2;
26
use CultuurNet\UDB3\Event\Events\FacilitiesUpdated;
27
use CultuurNet\UDB3\Event\Events\GeoCoordinatesUpdated;
28
use CultuurNet\UDB3\Event\Events\ImageAdded;
29
use CultuurNet\UDB3\Event\Events\ImageRemoved;
30
use CultuurNet\UDB3\Event\Events\Image\ImagesImportedFromUDB2;
31
use CultuurNet\UDB3\Event\Events\Image\ImagesUpdatedFromUDB2;
32
use CultuurNet\UDB3\Event\Events\ImageUpdated;
33
use CultuurNet\UDB3\Event\Events\LabelAdded;
34
use CultuurNet\UDB3\Event\Events\LabelRemoved;
35
use CultuurNet\UDB3\Event\Events\LocationUpdated;
36
use CultuurNet\UDB3\Event\Events\MainImageSelected;
37
use CultuurNet\UDB3\Event\Events\MajorInfoUpdated;
38
use CultuurNet\UDB3\Event\Events\Moderation\Approved;
39
use CultuurNet\UDB3\Event\Events\Moderation\FlaggedAsDuplicate;
40
use CultuurNet\UDB3\Event\Events\Moderation\FlaggedAsInappropriate;
41
use CultuurNet\UDB3\Event\Events\Moderation\Published;
42
use CultuurNet\UDB3\Event\Events\Moderation\Rejected;
43
use CultuurNet\UDB3\Event\Events\OrganizerDeleted;
44
use CultuurNet\UDB3\Event\Events\OrganizerUpdated;
45
use CultuurNet\UDB3\Event\Events\PriceInfoUpdated;
46
use CultuurNet\UDB3\Event\Events\ThemeUpdated;
47
use CultuurNet\UDB3\Event\Events\TitleTranslated;
48
use CultuurNet\UDB3\Event\Events\TitleUpdated;
49
use CultuurNet\UDB3\Event\Events\TypeUpdated;
50
use CultuurNet\UDB3\Event\Events\TypicalAgeRangeDeleted;
51
use CultuurNet\UDB3\Event\Events\TypicalAgeRangeUpdated;
52
use CultuurNet\UDB3\Event\ValueObjects\Audience;
53
use CultuurNet\UDB3\Label;
54
use CultuurNet\UDB3\LabelCollection;
55
use CultuurNet\UDB3\Language;
56
use CultuurNet\UDB3\Location\Location;
57
use CultuurNet\UDB3\Location\LocationId;
58
use CultuurNet\UDB3\Media\ImageCollection;
59
use CultuurNet\UDB3\Media\Image;
60
use CultuurNet\UDB3\Offer\Commands\Image\AbstractUpdateImage;
61
use CultuurNet\UDB3\Offer\Offer;
62
use CultuurNet\UDB3\Offer\WorkflowStatus;
63
use CultuurNet\UDB3\PriceInfo\PriceInfo;
64
use CultuurNet\UDB3\Theme;
65
use CultuurNet\UDB3\Title;
66
use ValueObjects\Identity\UUID;
67
use ValueObjects\StringLiteral\StringLiteral;
68
69
class Event extends Offer implements UpdateableWithCdbXmlInterface
70
{
71
    /**
72
     * @var string
73
     */
74
    protected $eventId;
75
76
    /**
77
     * @var Audience
78
     */
79
    private $audience;
80
81
    /**
82
     * @var LocationId
83
     */
84
    private $locationId;
85
86
    /**
87
     * @var boolean
88
     */
89
    private $concluded = false;
90
91
    public function __construct()
92
    {
93
        parent::__construct();
94
    }
95
96
    /**
97
     * Factory method to create a new event.
98
     *
99
     * @param $eventId
100
     * @param Language $mainLanguage
101
     * @param Title $title
102
     * @param EventType $eventType
103
     * @param Location $location
104
     * @param CalendarInterface $calendar
105
     * @param Theme|null $theme
106
     * @param \DateTimeImmutable|null $publicationDate
107
     * @return Event
108
     */
109 View Code Duplication
    public static function create(
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...
110
        $eventId,
111
        Language $mainLanguage,
112
        Title $title,
113
        EventType $eventType,
114
        Location $location,
115
        CalendarInterface $calendar,
116
        Theme $theme = null,
117
        \DateTimeImmutable $publicationDate = null
118
    ) {
119
        $event = new self();
120
121
        $event->apply(
122
            new EventCreated(
123
                $eventId,
124
                $mainLanguage,
125
                $title,
126
                $eventType,
127
                $location,
128
                $calendar,
129
                $theme,
130
                $publicationDate
131
            )
132
        );
133
134
        return $event;
135
    }
136
137
    /**
138
     * @param string $newEventId
139
     * @param CalendarInterface $calendar
140
     *
141
     * @return Event
142
     */
143
    public function copy($newEventId, CalendarInterface $calendar)
144
    {
145
        if ($this->hasUncommittedEvents()) {
146
            throw new \RuntimeException('I refuse to copy, there are uncommitted events present.');
147
        }
148
149
        // The copied event will have a playhead of the original event + 1
150
        $copy = clone $this;
151
152
        $copy->apply(
153
            new EventCopied(
154
                $newEventId,
155
                $this->eventId,
156
                $calendar
157
            )
158
        );
159
160
        return $copy;
161
    }
162
163
    /**
164
     * @param string $eventId
165
     * @param string $cdbXml
166
     * @param string $cdbXmlNamespaceUri
167
     * @return Event
168
     */
169
    public static function importFromUDB2(
170
        $eventId,
171
        $cdbXml,
172
        $cdbXmlNamespaceUri
173
    ) {
174
        $event = new self();
175
        $event->apply(
176
            new EventImportedFromUDB2(
177
                $eventId,
178
                $cdbXml,
179
                $cdbXmlNamespaceUri
180
            )
181
        );
182
183
        return $event;
184
    }
185
186
    /**
187
     * @param ImageCollection $images
188
     */
189
    public function updateImagesFromUDB2(ImageCollection $images)
190
    {
191
        $this->apply(new ImagesUpdatedFromUDB2($this->eventId, $images));
192
    }
193
194
    /**
195
     * @param ImageCollection $images
196
     */
197
    public function importImagesFromUDB2(ImageCollection $images)
198
    {
199
        $this->apply(new ImagesImportedFromUDB2($this->eventId, $images));
200
    }
201
202
    /**
203
     * {@inheritdoc}
204
     */
205
    public function getAggregateRootId()
206
    {
207
        return $this->eventId;
208
    }
209
210
    /**
211
     * @return UUID[]
212
     */
213
    public function getMediaObjects()
214
    {
215
        return $this->mediaObjects;
0 ignored issues
show
Bug introduced by
The property mediaObjects does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
216
    }
217
218
    protected function applyEventCreated(EventCreated $eventCreated)
219
    {
220
        $this->eventId = $eventCreated->getEventId();
221
        $this->locationId = new LocationId($eventCreated->getLocation()->getCdbid());
222
        $this->mainLanguage = $eventCreated->getMainLanguage();
223
        $this->workflowStatus = WorkflowStatus::DRAFT();
224
    }
225
226
    /**
227
     * @param EventCopied $eventCopied
228
     */
229
    protected function applyEventCopied(EventCopied $eventCopied)
230
    {
231
        $this->eventId = $eventCopied->getItemId();
232
        $this->workflowStatus = WorkflowStatus::DRAFT();
233
        $this->labels = new LabelCollection();
234
    }
235
236
    protected function applyEventImportedFromUDB2(
237
        EventImportedFromUDB2 $eventImported
238
    ) {
239
        $this->eventId = $eventImported->getEventId();
240
        // When importing from UDB2 the default main language is always 'nl'.
241
        $this->mainLanguage = new Language('nl');
242
        $this->setUDB2Data($eventImported);
243
    }
244
245
    /**
246
     * @param EventUpdatedFromUDB2 $eventUpdated
247
     */
248
    protected function applyEventUpdatedFromUDB2(
249
        EventUpdatedFromUDB2 $eventUpdated
250
    ) {
251
        // Note: when updating from UDB2 never change the main language.
252
        $this->setUDB2Data($eventUpdated);
253
    }
254
255
    /**
256
     * @param EventCdbXMLInterface $eventCdbXML
257
     */
258 View Code Duplication
    protected function setUDB2Data(
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...
259
        EventCdbXMLInterface $eventCdbXML
260
    ) {
261
        $udb2Event = EventItemFactory::createEventFromCdbXml(
262
            $eventCdbXML->getCdbXmlNamespaceUri(),
263
            $eventCdbXML->getCdbXml()
264
        );
265
266
        // Just clear the facilities.
267
        $this->facilities = [];
268
269
        // Just clear the location id after an import or update.
270
        $this->locationId = null;
271
272
        // Just clear the contact point.
273
        $this->contactPoint = null;
274
275
        // Just clear the calendar.
276
        $this->calendar = null;
277
278
        // Just clear typical age range.
279
        $this->typicalAgeRange = null;
280
281
        $this->importWorkflowStatus($udb2Event);
282
        $this->labels = LabelCollection::fromKeywords($udb2Event->getKeywords(true));
283
    }
284
285
    /**
286
     * Update the major info.
287
     *
288
     * @param Title $title
289
     * @param EventType $eventType
290
     * @param Location $location
291
     * @param CalendarInterface $calendar
292
     * @param Theme|null $theme
293
     */
294
    public function updateMajorInfo(
295
        Title $title,
296
        EventType $eventType,
297
        Location $location,
298
        CalendarInterface $calendar,
299
        Theme $theme = null
300
    ) {
301
        $this->apply(new MajorInfoUpdated($this->eventId, $title, $eventType, $location, $calendar, $theme));
302
    }
303
304
    /**
305
     * @param LocationId $locationId
306
     */
307
    public function updateLocation(LocationId $locationId)
308
    {
309
        if (is_null($this->locationId) || !$this->locationId->sameValueAs($locationId)) {
310
            $this->apply(new LocationUpdated($this->eventId, $locationId));
311
        }
312
    }
313
314
    /**
315
     * @param LocationUpdated $locationUpdated
316
     */
317
    public function applyLocationUpdated(LocationUpdated $locationUpdated)
318
    {
319
        $this->locationId = $locationUpdated->getLocationId();
320
    }
321
322
    /**
323
     * @param Audience $audience
324
     */
325
    public function updateAudience(
326
        Audience $audience
327
    ) {
328
        if (is_null($this->audience) || !$this->audience->equals($audience)) {
329
            $this->apply(new AudienceUpdated(
330
                $this->eventId,
331
                $audience
332
            ));
333
        }
334
    }
335
336
    /**
337
     * @param AudienceUpdated $audienceUpdated
338
     */
339
    public function applyAudienceUpdated(AudienceUpdated $audienceUpdated)
340
    {
341
        $this->audience= $audienceUpdated->getAudience();
342
    }
343
344
    /**
345
     * @inheritDoc
346
     * @return ImagesImportedFromUDB2
347
     */
348
    protected function createImagesImportedFromUDB2(ImageCollection $images)
349
    {
350
        return new ImagesImportedFromUDB2($this->eventId, $images);
351
    }
352
353
    /**
354
     * @inheritDoc
355
     * @return ImagesUpdatedFromUDB2
356
     */
357
    protected function createImagesUpdatedFromUDB2(ImageCollection $images)
358
    {
359
        return new ImagesUpdatedFromUDB2($this->eventId, $images);
360
    }
361
362
    /**
363
     * @inheritdoc
364
     */
365
    public function updateWithCdbXml($cdbXml, $cdbXmlNamespaceUri)
366
    {
367
        $this->apply(
368
            new EventUpdatedFromUDB2(
369
                $this->eventId,
370
                $cdbXml,
371
                $cdbXmlNamespaceUri
372
            )
373
        );
374
    }
375
376
    /**
377
     * @param Label $label
378
     * @return LabelAdded
379
     */
380
    protected function createLabelAddedEvent(Label $label)
381
    {
382
        return new LabelAdded($this->eventId, $label);
383
    }
384
385
    /**
386
     * @param Label $label
387
     * @return LabelRemoved
388
     */
389
    protected function createLabelRemovedEvent(Label $label)
390
    {
391
        return new LabelRemoved($this->eventId, $label);
392
    }
393
394
    /**
395
     * @param Image $image
396
     * @return ImageAdded
397
     */
398
    protected function createImageAddedEvent(Image $image)
399
    {
400
        return new ImageAdded($this->eventId, $image);
401
    }
402
403
    /**
404
     * @param Image $image
405
     * @return ImageRemoved
406
     */
407
    protected function createImageRemovedEvent(Image $image)
408
    {
409
        return new ImageRemoved($this->eventId, $image);
410
    }
411
412
    /**
413
     * @param AbstractUpdateImage $updateImageCommand
414
     * @return ImageUpdated
415
     */
416
    protected function createImageUpdatedEvent(
417
        AbstractUpdateImage $updateImageCommand
418
    ) {
419
        return new ImageUpdated(
420
            $this->eventId,
421
            $updateImageCommand->getMediaObjectId(),
422
            $updateImageCommand->getDescription(),
423
            $updateImageCommand->getCopyrightHolder()
424
        );
425
    }
426
427
    /**
428
     * @param Image $image
429
     * @return MainImageSelected
430
     */
431
    protected function createMainImageSelectedEvent(Image $image)
432
    {
433
        return new MainImageSelected($this->eventId, $image);
434
    }
435
436
    /**
437
     * @param Language $language
438
     * @param StringLiteral $title
439
     * @return TitleTranslated
440
     */
441
    protected function createTitleTranslatedEvent(Language $language, StringLiteral $title)
442
    {
443
        return new TitleTranslated($this->eventId, $language, $title);
444
    }
445
446
    /**
447
     * @param Title $title
448
     * @return TitleUpdated
449
     */
450
    protected function createTitleUpdatedEvent(Title $title)
451
    {
452
        return new TitleUpdated($this->eventId, $title);
453
    }
454
455
    /**
456
     * @param Language $language
457
     * @param StringLiteral $description
458
     * @return DescriptionTranslated
459
     */
460
    protected function createDescriptionTranslatedEvent(Language $language, StringLiteral $description)
461
    {
462
        return new DescriptionTranslated($this->eventId, $language, $description);
463
    }
464
465
    /**
466
     * @param string $description
467
     * @return DescriptionUpdated
468
     */
469
    protected function createDescriptionUpdatedEvent($description)
470
    {
471
        return new DescriptionUpdated($this->eventId, $description);
472
    }
473
474
    /**
475
     * @inheritdoc
476
     */
477
    protected function createCalendarUpdatedEvent(Calendar $calendar)
478
    {
479
        return new CalendarUpdated($this->eventId, $calendar);
480
    }
481
482
    /**
483
     * @param string $typicalAgeRange
484
     * @return TypicalAgeRangeUpdated
485
     */
486
    protected function createTypicalAgeRangeUpdatedEvent($typicalAgeRange)
487
    {
488
        return new TypicalAgeRangeUpdated($this->eventId, $typicalAgeRange);
0 ignored issues
show
Documentation introduced by
$typicalAgeRange is of type string, but the function expects a object<CultuurNet\UDB3\Offer\AgeRange>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
489
    }
490
491
    /**
492
     * @return TypicalAgeRangeDeleted
493
     */
494
    protected function createTypicalAgeRangeDeletedEvent()
495
    {
496
        return new TypicalAgeRangeDeleted($this->eventId);
497
    }
498
499
    /**
500
     * @param string $organizerId
501
     * @return OrganizerUpdated
502
     */
503
    protected function createOrganizerUpdatedEvent($organizerId)
504
    {
505
        return new OrganizerUpdated($this->eventId, $organizerId);
506
    }
507
508
    /**
509
     * @param string $organizerId
510
     * @return OrganizerDeleted
511
     */
512
    protected function createOrganizerDeletedEvent($organizerId)
513
    {
514
        return new OrganizerDeleted($this->eventId, $organizerId);
515
    }
516
517
    /**
518
     * @param ContactPoint $contactPoint
519
     * @return ContactPointUpdated
520
     */
521
    protected function createContactPointUpdatedEvent(ContactPoint $contactPoint)
522
    {
523
        return new ContactPointUpdated($this->eventId, $contactPoint);
524
    }
525
526
    /**
527
     * @inheritdoc
528
     */
529
    protected function createGeoCoordinatesUpdatedEvent(Coordinates $coordinates)
530
    {
531
        return new GeoCoordinatesUpdated($this->eventId, $coordinates);
532
    }
533
534
    /**
535
     * @param BookingInfo $bookingInfo
536
     * @return BookingInfoUpdated
537
     */
538
    protected function createBookingInfoUpdatedEvent(BookingInfo $bookingInfo)
539
    {
540
        return new BookingInfoUpdated($this->eventId, $bookingInfo);
541
    }
542
543
    /**
544
     * @param PriceInfo $priceInfo
545
     * @return PriceInfoUpdated
546
     */
547
    protected function createPriceInfoUpdatedEvent(PriceInfo $priceInfo)
548
    {
549
        return new PriceInfoUpdated($this->eventId, $priceInfo);
550
    }
551
552
    /**
553
     * @return EventDeleted
554
     */
555
    protected function createOfferDeletedEvent()
556
    {
557
        return new EventDeleted($this->eventId);
558
    }
559
560
    /**
561
     * @inheritdoc
562
     */
563
    protected function createPublishedEvent(\DateTimeInterface $publicationDate)
564
    {
565
        return new Published($this->eventId, $publicationDate);
566
    }
567
568
    /**
569
     * @inheritdoc
570
     */
571
    protected function createApprovedEvent()
572
    {
573
        return new Approved($this->eventId);
574
    }
575
576
    /**
577
     * @inheritdoc
578
     */
579
    protected function createRejectedEvent(StringLiteral $reason)
580
    {
581
        return new Rejected($this->eventId, $reason);
582
    }
583
584
    /**
585
     * @inheritDoc
586
     */
587
    protected function createFlaggedAsDuplicate()
588
    {
589
        return new FlaggedAsDuplicate($this->eventId);
590
    }
591
592
    /**
593
     * @inheritDoc
594
     */
595
    protected function createFlaggedAsInappropriate()
596
    {
597
        return new FlaggedAsInappropriate($this->eventId);
598
    }
599
600
    /**
601
     * @inheritdoc
602
     */
603
    protected function createTypeUpdatedEvent(EventType $type)
604
    {
605
        return new TypeUpdated($this->eventId, $type);
606
    }
607
608
    /**
609
     * @inheritdoc
610
     */
611
    protected function createThemeUpdatedEvent(Theme $theme)
612
    {
613
        return new ThemeUpdated($this->eventId, $theme);
614
    }
615
616
    /**
617
     * @inheritdoc
618
     */
619
    protected function createFacilitiesUpdatedEvent(array $facilities)
620
    {
621
        return new FacilitiesUpdated($this->eventId, $facilities);
622
    }
623
624
    /**
625
     * Use reflection to get check if the aggregate has uncommitted events.
626
     * @return bool
627
     */
628
    private function hasUncommittedEvents()
629
    {
630
        $reflector = new \ReflectionClass(EventSourcedAggregateRoot::class);
631
        $property = $reflector->getProperty('uncommittedEvents');
632
633
        $property->setAccessible(true);
634
        $uncommittedEvents = $property->getValue($this);
635
636
        return !empty($uncommittedEvents);
637
    }
638
639
    public function conclude()
640
    {
641
        if (!$this->concluded) {
642
            $this->apply(new Concluded($this->eventId));
643
        }
644
    }
645
646
    /**
647
     * @param Concluded $concluded
648
     */
649
    protected function applyConcluded(Concluded $concluded)
0 ignored issues
show
Unused Code introduced by
The parameter $concluded 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...
650
    {
651
        $this->concluded = true;
652
    }
653
}
654