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\Media\Properties\CopyrightHolder; |
20
|
|
|
use \CultuurNet\UDB3\Media\Properties\Description as ImageDescription; |
21
|
|
|
use CultuurNet\UDB3\Model\ValueObject\Taxonomy\Label\LabelName; |
22
|
|
|
use CultuurNet\UDB3\Model\ValueObject\Taxonomy\Label\Labels; |
23
|
|
|
use CultuurNet\UDB3\Language; |
24
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractBookingInfoUpdated; |
25
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractCalendarUpdated; |
26
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractContactPointUpdated; |
27
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractFacilitiesUpdated; |
28
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractGeoCoordinatesUpdated; |
29
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractLabelsImported; |
30
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractThemeUpdated; |
31
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractTitleTranslated; |
32
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractTitleUpdated; |
33
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractDescriptionTranslated; |
34
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractDescriptionUpdated; |
35
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractLabelAdded; |
36
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractLabelRemoved; |
37
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractOfferDeleted; |
38
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractOrganizerDeleted; |
39
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractOrganizerUpdated; |
40
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractPriceInfoUpdated; |
41
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractTypeUpdated; |
42
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractTypicalAgeRangeDeleted; |
43
|
|
|
use CultuurNet\UDB3\Offer\Events\AbstractTypicalAgeRangeUpdated; |
44
|
|
|
use CultuurNet\UDB3\Offer\Events\Image\AbstractImageAdded; |
45
|
|
|
use CultuurNet\UDB3\Offer\Events\Image\AbstractImageRemoved; |
46
|
|
|
use CultuurNet\UDB3\Offer\Events\Image\AbstractImagesEvent; |
47
|
|
|
use CultuurNet\UDB3\Offer\Events\Image\AbstractImagesImportedFromUDB2; |
48
|
|
|
use CultuurNet\UDB3\Offer\Events\Image\AbstractImagesUpdatedFromUDB2; |
49
|
|
|
use CultuurNet\UDB3\Offer\Events\Image\AbstractImageUpdated; |
50
|
|
|
use CultuurNet\UDB3\Offer\Events\Image\AbstractMainImageSelected; |
51
|
|
|
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractApproved; |
52
|
|
|
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractFlaggedAsDuplicate; |
53
|
|
|
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractFlaggedAsInappropriate; |
54
|
|
|
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractPublished; |
55
|
|
|
use CultuurNet\UDB3\Offer\Events\Moderation\AbstractRejected; |
56
|
|
|
use CultuurNet\UDB3\PriceInfo\PriceInfo; |
57
|
|
|
use CultuurNet\UDB3\Theme; |
58
|
|
|
use CultuurNet\UDB3\Title; |
59
|
|
|
use Exception; |
60
|
|
|
use TwoDotsTwice\Collection\Exception\CollectionItemNotFoundException; |
61
|
|
|
use ValueObjects\Identity\UUID; |
62
|
|
|
use ValueObjects\StringLiteral\StringLiteral; |
63
|
|
|
|
64
|
|
|
abstract class Offer extends EventSourcedAggregateRoot implements LabelAwareAggregateRoot |
65
|
|
|
{ |
66
|
|
|
const DUPLICATE_REASON = 'duplicate'; |
67
|
|
|
const INAPPROPRIATE_REASON = 'inappropriate'; |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @var LabelCollection |
71
|
|
|
*/ |
72
|
|
|
protected $labels; |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @var ImageCollection |
76
|
|
|
*/ |
77
|
|
|
protected $images; |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @var string |
81
|
|
|
* |
82
|
|
|
* Organizer ids can come from UDB2 which does not strictly use UUIDs. |
83
|
|
|
*/ |
84
|
|
|
protected $organizerId; |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* @var WorkflowStatus |
88
|
|
|
*/ |
89
|
|
|
protected $workflowStatus; |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* @var StringLiteral|null |
93
|
|
|
*/ |
94
|
|
|
protected $rejectedReason; |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @var PriceInfo |
98
|
|
|
*/ |
99
|
|
|
protected $priceInfo; |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @var StringLiteral[] |
103
|
|
|
*/ |
104
|
|
|
protected $titles; |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @var Description[] |
108
|
|
|
*/ |
109
|
|
|
protected $descriptions; |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @var Language |
113
|
|
|
*/ |
114
|
|
|
protected $mainLanguage; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @var string; |
118
|
|
|
*/ |
119
|
|
|
protected $typeId; |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* @var string; |
123
|
|
|
*/ |
124
|
|
|
protected $themeId; |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @var array |
128
|
|
|
*/ |
129
|
|
|
protected $facilities; |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* @var ContactPoint |
133
|
|
|
*/ |
134
|
|
|
protected $contactPoint; |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* @var Calendar |
138
|
|
|
*/ |
139
|
|
|
protected $calendar; |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* @var AgeRange |
143
|
|
|
*/ |
144
|
|
|
protected $typicalAgeRange; |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* @var BookingInfo |
148
|
|
|
*/ |
149
|
|
|
protected $bookingInfo; |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* @var bool |
153
|
|
|
*/ |
154
|
|
|
protected $isDeleted = false; |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Offer constructor. |
158
|
|
|
*/ |
159
|
|
|
public function __construct() |
160
|
|
|
{ |
161
|
|
|
$this->titles = []; |
162
|
|
|
$this->descriptions = []; |
163
|
|
|
$this->labels = new LabelCollection(); |
164
|
|
|
$this->images = new ImageCollection(); |
165
|
|
|
$this->facilities = []; |
166
|
|
|
$this->contactPoint = null; |
167
|
|
|
$this->calendar = null; |
168
|
|
|
$this->typicalAgeRange = null; |
169
|
|
|
$this->bookingInfo = null; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* @param EventType $type |
174
|
|
|
*/ |
175
|
|
|
public function updateType(EventType $type) |
176
|
|
|
{ |
177
|
|
|
if (!$this->typeId || $this->typeId !== $type->getId()) { |
178
|
|
|
$this->apply($this->createTypeUpdatedEvent($type)); |
179
|
|
|
} |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* @param Theme $theme |
184
|
|
|
*/ |
185
|
|
|
public function updateTheme(Theme $theme) |
186
|
|
|
{ |
187
|
|
|
if (!$this->themeId || $this->themeId !== $theme->getId()) { |
188
|
|
|
$this->apply($this->createThemeUpdatedEvent($theme)); |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* @param array $facilities |
194
|
|
|
*/ |
195
|
|
|
public function updateFacilities(array $facilities) |
196
|
|
|
{ |
197
|
|
|
if (empty($this->facilities) || !$this->sameFacilities($this->facilities, $facilities)) { |
198
|
|
|
$this->apply($this->createFacilitiesUpdatedEvent($facilities)); |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* @param AbstractFacilitiesUpdated $facilitiesUpdated |
204
|
|
|
*/ |
205
|
|
|
protected function applyFacilitiesUpdated(AbstractFacilitiesUpdated $facilitiesUpdated) |
206
|
|
|
{ |
207
|
|
|
$this->facilities = $facilitiesUpdated->getFacilities(); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* @param array $facilities1 |
212
|
|
|
* @param array $facilities2 |
213
|
|
|
* @return bool |
214
|
|
|
*/ |
215
|
|
|
private function sameFacilities($facilities1, $facilities2) |
216
|
|
|
{ |
217
|
|
|
if (count($facilities1) !== count($facilities2)) { |
218
|
|
|
return false; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
$sameFacilities = array_uintersect( |
222
|
|
|
$facilities1, |
223
|
|
|
$facilities2, |
224
|
|
|
function (Facility $facility1, Facility $facility2) { |
225
|
|
|
return strcmp($facility1->getId(), $facility2->getId()); |
226
|
|
|
} |
227
|
|
|
); |
228
|
|
|
|
229
|
|
|
return count($sameFacilities) === count($facilities2); |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
/** |
233
|
|
|
* Get the id of the main image if one is selected for this offer. |
234
|
|
|
* |
235
|
|
|
* @return UUID|null |
236
|
|
|
*/ |
237
|
|
|
protected function getMainImageId() |
238
|
|
|
{ |
239
|
|
|
$mainImage = $this->images->getMain(); |
240
|
|
|
return isset($mainImage) ? $mainImage->getMediaObjectId() : null; |
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
/** |
244
|
|
|
* @inheritdoc |
245
|
|
|
*/ |
246
|
|
|
public function addLabel(Label $label) |
247
|
|
|
{ |
248
|
|
|
if (!$this->labels->contains($label)) { |
249
|
|
|
$this->apply( |
250
|
|
|
$this->createLabelAddedEvent($label) |
251
|
|
|
); |
252
|
|
|
} |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* @inheritdoc |
257
|
|
|
*/ |
258
|
|
|
public function removeLabel(Label $label) |
259
|
|
|
{ |
260
|
|
|
if ($this->labels->contains($label)) { |
261
|
|
|
$this->apply( |
262
|
|
|
$this->createLabelRemovedEvent($label) |
263
|
|
|
); |
264
|
|
|
} |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* @param Labels $labels |
269
|
|
|
* @param Labels $labelsToKeepIfAlreadyOnOffer |
270
|
|
|
*/ |
271
|
|
|
public function importLabels(Labels $labels, Labels $labelsToKeepIfAlreadyOnOffer, Labels $labelsToRemoveWhenOnOffer) |
272
|
|
|
{ |
273
|
|
|
$convertLabelClass = function (\CultuurNet\UDB3\Model\ValueObject\Taxonomy\Label\Label $label) { |
274
|
|
|
return new Label( |
275
|
|
|
$label->getName()->toString(), |
276
|
|
|
$label->isVisible() |
277
|
|
|
); |
278
|
|
|
}; |
279
|
|
|
|
280
|
|
|
// Convert the imported labels to label collection. |
281
|
|
|
$importLabelsCollection = new LabelCollection( |
282
|
|
|
array_map($convertLabelClass, $labels->toArray()) |
283
|
|
|
); |
284
|
|
|
|
285
|
|
|
// Convert the labels to keep if already applied. |
286
|
|
|
$keepLabelsCollection = new LabelCollection( |
287
|
|
|
array_map($convertLabelClass, $labelsToKeepIfAlreadyOnOffer->toArray()) |
288
|
|
|
); |
289
|
|
|
|
290
|
|
|
// Convert the labels to remove when on offer. |
291
|
|
|
$removeLabelsCollection = new LabelCollection( |
292
|
|
|
array_map($convertLabelClass, $labelsToRemoveWhenOnOffer->toArray()) |
293
|
|
|
); |
294
|
|
|
|
295
|
|
|
// What are the added labels? |
296
|
|
|
// Labels which are not inside the internal state but inside the imported labels |
297
|
|
|
$addedLabels = new LabelCollection(); |
298
|
|
|
foreach ($importLabelsCollection->asArray() as $label) { |
299
|
|
|
if (!$this->labels->contains($label)) { |
300
|
|
|
$addedLabels = $addedLabels->with($label); |
301
|
|
|
} |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
// Fire a LabelsImported for all new labels. |
305
|
|
|
$importLabels = new Labels(); |
306
|
|
View Code Duplication |
foreach ($addedLabels->asArray() as $addedLabel) { |
|
|
|
|
307
|
|
|
$importLabels = $importLabels->with( |
308
|
|
|
new \CultuurNet\UDB3\Model\ValueObject\Taxonomy\Label\Label( |
309
|
|
|
new LabelName((string) $addedLabel), |
310
|
|
|
$addedLabel->isVisible() |
311
|
|
|
) |
312
|
|
|
); |
313
|
|
|
} |
314
|
|
|
if ($importLabels->count() > 0) { |
315
|
|
|
$this->apply($this->createLabelsImportedEvent($importLabels)); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
// For each added label fire a LabelAdded event. |
319
|
|
|
foreach ($addedLabels->asArray() as $label) { |
320
|
|
|
$this->apply($this->createLabelAddedEvent($label)); |
321
|
|
|
} |
322
|
|
|
|
323
|
|
|
// What are the deleted labels? |
324
|
|
|
// Labels which are inside the internal state but not inside imported labels or labels to keep. |
325
|
|
|
// For each deleted label fire a LabelDeleted event. |
326
|
|
|
foreach ($this->labels->asArray() as $label) { |
327
|
|
|
if (!$importLabelsCollection->contains($label) && !$keepLabelsCollection->contains($label) && $removeLabelsCollection->contains($label)) { |
328
|
|
|
$this->apply($this->createLabelRemovedEvent($label)); |
329
|
|
|
} |
330
|
|
|
} |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
/** |
334
|
|
|
* @param Language $language |
335
|
|
|
* @param Title $title |
336
|
|
|
*/ |
337
|
|
|
public function updateTitle(Language $language, Title $title) |
338
|
|
|
{ |
339
|
|
|
if ($this->isTitleChanged($title, $language)) { |
340
|
|
|
if ($language->getCode() !== $this->mainLanguage->getCode()) { |
341
|
|
|
$event = $this->createTitleTranslatedEvent($language, $title); |
342
|
|
|
} else { |
343
|
|
|
$event = $this->createTitleUpdatedEvent($title); |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
$this->apply($event); |
347
|
|
|
} |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* @param AbstractTitleTranslated $titleTranslated |
352
|
|
|
*/ |
353
|
|
|
public function applyTitleTranslated(AbstractTitleTranslated $titleTranslated) |
354
|
|
|
{ |
355
|
|
|
$this->titles[$titleTranslated->getLanguage()->getCode()] = $titleTranslated->getTitle(); |
356
|
|
|
} |
357
|
|
|
|
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* @param AbstractTitleUpdated $titleUpdated |
361
|
|
|
*/ |
362
|
|
|
public function applyTitleUpdated(AbstractTitleUpdated $titleUpdated) |
363
|
|
|
{ |
364
|
|
|
$this->titles[$this->mainLanguage->getCode()] = $titleUpdated->getTitle(); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
/** |
368
|
|
|
* @param Description $description |
369
|
|
|
* @param Language $language |
370
|
|
|
*/ |
371
|
|
|
public function updateDescription(Description $description, Language $language) |
372
|
|
|
{ |
373
|
|
|
if ($this->isDescriptionChanged($description, $language)) { |
374
|
|
|
if ($language->getCode() !== $this->mainLanguage->getCode()) { |
375
|
|
|
$event = $this->createDescriptionTranslatedEvent($language, $description); |
376
|
|
|
} else { |
377
|
|
|
$event = $this->createDescriptionUpdatedEvent($description); |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
$this->apply($event); |
381
|
|
|
} |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
/** |
385
|
|
|
* @param Calendar $calendar |
386
|
|
|
*/ |
387
|
|
|
public function updateCalendar(Calendar $calendar) |
388
|
|
|
{ |
389
|
|
|
if (is_null($this->calendar) || !$this->calendar->sameAs($calendar)) { |
390
|
|
|
$this->apply( |
391
|
|
|
$this->createCalendarUpdatedEvent($calendar) |
392
|
|
|
); |
393
|
|
|
} |
394
|
|
|
} |
395
|
|
|
|
396
|
|
|
/** |
397
|
|
|
* @param AbstractCalendarUpdated $calendarUpdated |
398
|
|
|
*/ |
399
|
|
|
protected function applyCalendarUpdated(AbstractCalendarUpdated $calendarUpdated) |
400
|
|
|
{ |
401
|
|
|
$this->calendar = $calendarUpdated->getCalendar(); |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
/** |
405
|
|
|
* @param AgeRange $typicalAgeRange |
406
|
|
|
*/ |
407
|
|
|
public function updateTypicalAgeRange(AgeRange $typicalAgeRange) |
408
|
|
|
{ |
409
|
|
|
$typicalAgeRangeUpdatedEvent = $this->createTypicalAgeRangeUpdatedEvent($typicalAgeRange); |
410
|
|
|
|
411
|
|
|
if (empty($this->typicalAgeRange) || !$this->typicalAgeRange->sameAs($typicalAgeRangeUpdatedEvent->getTypicalAgeRange())) { |
412
|
|
|
$this->apply($typicalAgeRangeUpdatedEvent); |
413
|
|
|
} |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
/** |
417
|
|
|
* @param AbstractTypicalAgeRangeUpdated $typicalAgeRangeUpdated |
418
|
|
|
*/ |
419
|
|
|
protected function applyTypicalAgeRangeUpdated(AbstractTypicalAgeRangeUpdated $typicalAgeRangeUpdated) |
420
|
|
|
{ |
421
|
|
|
$this->typicalAgeRange = $typicalAgeRangeUpdated->getTypicalAgeRange(); |
422
|
|
|
} |
423
|
|
|
|
424
|
|
|
public function deleteTypicalAgeRange() |
425
|
|
|
{ |
426
|
|
|
if (!is_null($this->typicalAgeRange)) { |
427
|
|
|
$this->apply( |
428
|
|
|
$this->createTypicalAgeRangeDeletedEvent() |
429
|
|
|
); |
430
|
|
|
} |
431
|
|
|
} |
432
|
|
|
|
433
|
|
|
/** |
434
|
|
|
* @param AbstractTypicalAgeRangeDeleted $typicalAgeRangeDeleted |
435
|
|
|
*/ |
436
|
|
|
public function applyTypicalAgeRangeDeleted(AbstractTypicalAgeRangeDeleted $typicalAgeRangeDeleted) |
|
|
|
|
437
|
|
|
{ |
438
|
|
|
$this->typicalAgeRange = null; |
439
|
|
|
} |
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* @param string $organizerId |
443
|
|
|
*/ |
444
|
|
|
public function updateOrganizer($organizerId) |
445
|
|
|
{ |
446
|
|
|
if ($this->organizerId !== $organizerId) { |
447
|
|
|
$this->apply( |
448
|
|
|
$this->createOrganizerUpdatedEvent($organizerId) |
449
|
|
|
); |
450
|
|
|
} |
451
|
|
|
} |
452
|
|
|
|
453
|
|
|
/** |
454
|
|
|
* Delete the given organizer. |
455
|
|
|
* |
456
|
|
|
* @param string $organizerId |
457
|
|
|
*/ |
458
|
|
|
public function deleteOrganizer($organizerId) |
459
|
|
|
{ |
460
|
|
|
if ($this->organizerId === $organizerId) { |
461
|
|
|
$this->apply( |
462
|
|
|
$this->createOrganizerDeletedEvent($organizerId) |
463
|
|
|
); |
464
|
|
|
} |
465
|
|
|
} |
466
|
|
|
|
467
|
|
|
/** |
468
|
|
|
* Delete the current organizer regardless of the id. |
469
|
|
|
*/ |
470
|
|
|
public function deleteCurrentOrganizer() |
471
|
|
|
{ |
472
|
|
|
if (!is_null($this->organizerId)) { |
473
|
|
|
$this->apply( |
474
|
|
|
$this->createOrganizerDeletedEvent($this->organizerId) |
475
|
|
|
); |
476
|
|
|
} |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
/** |
480
|
|
|
* Updated the contact info. |
481
|
|
|
* @param ContactPoint $contactPoint |
482
|
|
|
*/ |
483
|
|
|
public function updateContactPoint(ContactPoint $contactPoint) |
484
|
|
|
{ |
485
|
|
|
if (is_null($this->contactPoint) || !$this->contactPoint->sameAs($contactPoint)) { |
486
|
|
|
$this->apply( |
487
|
|
|
$this->createContactPointUpdatedEvent($contactPoint) |
488
|
|
|
); |
489
|
|
|
} |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
/** |
493
|
|
|
* @param AbstractContactPointUpdated $contactPointUpdated |
494
|
|
|
*/ |
495
|
|
|
protected function applyContactPointUpdated(AbstractContactPointUpdated $contactPointUpdated) |
496
|
|
|
{ |
497
|
|
|
$this->contactPoint = $contactPointUpdated->getContactPoint(); |
498
|
|
|
} |
499
|
|
|
|
500
|
|
|
/** |
501
|
|
|
* @param Coordinates $coordinates |
502
|
|
|
*/ |
503
|
|
|
public function updateGeoCoordinates(Coordinates $coordinates) |
504
|
|
|
{ |
505
|
|
|
// Note: DON'T compare to previous coordinates and apply only on |
506
|
|
|
// changes. Various projectors expect GeoCoordinatesUpdated after |
507
|
|
|
// MajorInfoUpdated and PlaceUpdatedFromUDB2, even if the address |
508
|
|
|
// and thus the coordinates haven't actually changed. |
509
|
|
|
$this->apply( |
510
|
|
|
$this->createGeoCoordinatesUpdatedEvent($coordinates) |
511
|
|
|
); |
512
|
|
|
} |
513
|
|
|
|
514
|
|
|
/** |
515
|
|
|
* Updated the booking info. |
516
|
|
|
* |
517
|
|
|
* @param BookingInfo $bookingInfo |
518
|
|
|
*/ |
519
|
|
|
public function updateBookingInfo(BookingInfo $bookingInfo) |
520
|
|
|
{ |
521
|
|
|
if (is_null($this->bookingInfo) || !$this->bookingInfo->sameAs($bookingInfo)) { |
522
|
|
|
$this->apply( |
523
|
|
|
$this->createBookingInfoUpdatedEvent($bookingInfo) |
524
|
|
|
); |
525
|
|
|
} |
526
|
|
|
} |
527
|
|
|
|
528
|
|
|
/** |
529
|
|
|
* @param AbstractBookingInfoUpdated $bookingInfoUpdated |
530
|
|
|
*/ |
531
|
|
|
public function applyBookingInfoUpdated(AbstractBookingInfoUpdated $bookingInfoUpdated) |
532
|
|
|
{ |
533
|
|
|
$this->bookingInfo = $bookingInfoUpdated->getBookingInfo(); |
534
|
|
|
} |
535
|
|
|
|
536
|
|
|
/** |
537
|
|
|
* @param PriceInfo $priceInfo |
538
|
|
|
*/ |
539
|
|
|
public function updatePriceInfo(PriceInfo $priceInfo) |
540
|
|
|
{ |
541
|
|
|
if (is_null($this->priceInfo) || $priceInfo->serialize() !== $this->priceInfo->serialize()) { |
542
|
|
|
$this->apply( |
543
|
|
|
$this->createPriceInfoUpdatedEvent($priceInfo) |
544
|
|
|
); |
545
|
|
|
} |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
/** |
549
|
|
|
* @param AbstractPriceInfoUpdated $priceInfoUpdated |
550
|
|
|
*/ |
551
|
|
|
protected function applyPriceInfoUpdated(AbstractPriceInfoUpdated $priceInfoUpdated) |
552
|
|
|
{ |
553
|
|
|
$this->priceInfo = $priceInfoUpdated->getPriceInfo(); |
554
|
|
|
} |
555
|
|
|
|
556
|
|
|
/** |
557
|
|
|
* @param AbstractLabelAdded $labelAdded |
558
|
|
|
*/ |
559
|
|
|
protected function applyLabelAdded(AbstractLabelAdded $labelAdded) |
560
|
|
|
{ |
561
|
|
|
$this->labels = $this->labels->with($labelAdded->getLabel()); |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
/** |
565
|
|
|
* @param AbstractLabelRemoved $labelRemoved |
566
|
|
|
*/ |
567
|
|
|
protected function applyLabelRemoved(AbstractLabelRemoved $labelRemoved) |
568
|
|
|
{ |
569
|
|
|
$this->labels = $this->labels->without($labelRemoved->getLabel()); |
570
|
|
|
} |
571
|
|
|
|
572
|
|
|
/** |
573
|
|
|
* @param AbstractThemeUpdated $themeUpdated |
574
|
|
|
*/ |
575
|
|
|
protected function applyThemeUpdated(AbstractThemeUpdated $themeUpdated) |
576
|
|
|
{ |
577
|
|
|
$this->themeId = $themeUpdated->getTheme()->getId(); |
578
|
|
|
} |
579
|
|
|
|
580
|
|
|
/** |
581
|
|
|
* @param AbstractTypeUpdated $themeUpdated |
582
|
|
|
*/ |
583
|
|
|
protected function applyTypeUpdated(AbstractTypeUpdated $themeUpdated) |
584
|
|
|
{ |
585
|
|
|
$this->typeId = $themeUpdated->getType()->getId(); |
586
|
|
|
} |
587
|
|
|
|
588
|
|
|
protected function applyDescriptionUpdated(AbstractDescriptionUpdated $descriptionUpdated) |
589
|
|
|
{ |
590
|
|
|
$mainLanguageCode = $this->mainLanguage->getCode(); |
591
|
|
|
$this->descriptions[$mainLanguageCode] = $descriptionUpdated->getDescription(); |
592
|
|
|
} |
593
|
|
|
|
594
|
|
|
protected function applyDescriptionTranslated(AbstractDescriptionTranslated $descriptionTranslated) |
595
|
|
|
{ |
596
|
|
|
$languageCode = $descriptionTranslated->getLanguage()->getCode(); |
597
|
|
|
$this->descriptions[$languageCode] = $descriptionTranslated->getDescription(); |
598
|
|
|
} |
599
|
|
|
|
600
|
|
|
/** |
601
|
|
|
* Add a new image. |
602
|
|
|
* |
603
|
|
|
* @param Image $image |
604
|
|
|
*/ |
605
|
|
|
public function addImage(Image $image) |
606
|
|
|
{ |
607
|
|
|
// Find the image based on UUID inside the internal state. |
608
|
|
|
$existingImage = $this->images->findImageByUUID($image->getMediaObjectId()); |
609
|
|
|
|
610
|
|
|
if ($existingImage === null) { |
611
|
|
|
$this->apply( |
612
|
|
|
$this->createImageAddedEvent($image) |
613
|
|
|
); |
614
|
|
|
} |
615
|
|
|
} |
616
|
|
|
|
617
|
|
|
/** |
618
|
|
|
* @param UUID $mediaObjectId |
619
|
|
|
* @param StringLiteral $description |
620
|
|
|
* @param StringLiteral $copyrightHolder |
621
|
|
|
*/ |
622
|
|
|
public function updateImage( |
623
|
|
|
UUID $mediaObjectId, |
624
|
|
|
StringLiteral $description, |
625
|
|
|
StringLiteral $copyrightHolder |
626
|
|
|
) { |
627
|
|
|
if ($this->updateImageAllowed($mediaObjectId, $description, $copyrightHolder)) { |
628
|
|
|
$this->apply( |
629
|
|
|
$this->createImageUpdatedEvent( |
630
|
|
|
$mediaObjectId, |
631
|
|
|
$description, |
632
|
|
|
$copyrightHolder |
633
|
|
|
) |
634
|
|
|
); |
635
|
|
|
} |
636
|
|
|
} |
637
|
|
|
|
638
|
|
|
/** |
639
|
|
|
* @param UUID $mediaObjectId |
640
|
|
|
* @param StringLiteral $description |
641
|
|
|
* @param StringLiteral $copyrightHolder |
642
|
|
|
* @return bool |
643
|
|
|
*/ |
644
|
|
|
private function updateImageAllowed( |
645
|
|
|
UUID $mediaObjectId, |
646
|
|
|
StringLiteral $description, |
647
|
|
|
StringLiteral $copyrightHolder |
648
|
|
|
) { |
649
|
|
|
$image = $this->images->findImageByUUID($mediaObjectId); |
650
|
|
|
|
651
|
|
|
// Don't update if the image is not found based on UUID. |
652
|
|
|
if (!$image) { |
653
|
|
|
return false; |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
// Update when copyright or description is changed. |
657
|
|
|
return !$copyrightHolder->sameValueAs($image->getCopyrightHolder()) || |
658
|
|
|
!$description->sameValueAs($image->getDescription()); |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
/** |
662
|
|
|
* Remove an image. |
663
|
|
|
* |
664
|
|
|
* @param Image $image |
665
|
|
|
*/ |
666
|
|
|
public function removeImage(Image $image) |
667
|
|
|
{ |
668
|
|
|
// Find the image based on UUID inside the internal state. |
669
|
|
|
// Use the image from the internal state. |
670
|
|
|
$existingImage = $this->images->findImageByUUID($image->getMediaObjectId()); |
671
|
|
|
|
672
|
|
|
if ($existingImage) { |
673
|
|
|
$this->apply( |
674
|
|
|
$this->createImageRemovedEvent($existingImage) |
675
|
|
|
); |
676
|
|
|
} |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
/** |
680
|
|
|
* Make an existing image of the item the main image. |
681
|
|
|
* |
682
|
|
|
* @param Image $image |
683
|
|
|
*/ |
684
|
|
|
public function selectMainImage(Image $image) |
685
|
|
|
{ |
686
|
|
|
if (!$this->images->findImageByUUID($image->getMediaObjectId())) { |
687
|
|
|
throw new \InvalidArgumentException('You can not select a random image to be main, it has to be added to the item.'); |
688
|
|
|
} |
689
|
|
|
|
690
|
|
|
$oldMainImage = $this->images->getMain(); |
691
|
|
|
|
692
|
|
|
if (!isset($oldMainImage) || $oldMainImage->getMediaObjectId() !== $image->getMediaObjectId()) { |
693
|
|
|
$this->apply( |
694
|
|
|
$this->createMainImageSelectedEvent($image) |
695
|
|
|
); |
696
|
|
|
} |
697
|
|
|
} |
698
|
|
|
|
699
|
|
|
/** |
700
|
|
|
* @param ImageCollection $imageCollection |
701
|
|
|
*/ |
702
|
|
|
public function importImages(ImageCollection $imageCollection) |
703
|
|
|
{ |
704
|
|
|
$currentImageCollection = $this->images; |
705
|
|
|
$newMainImage = $imageCollection->getMain(); |
706
|
|
|
|
707
|
|
|
$importImages = $imageCollection->toArray(); |
708
|
|
|
$currentImages = $currentImageCollection->toArray(); |
709
|
|
|
|
710
|
|
|
$compareImages = function (Image $a, Image $b) { |
711
|
|
|
$idA = $a->getMediaObjectId()->toNative(); |
712
|
|
|
$idB = $b->getMediaObjectId()->toNative(); |
713
|
|
|
return strcmp($idA, $idB); |
714
|
|
|
}; |
715
|
|
|
|
716
|
|
|
/* @var Image[] $addedImages */ |
717
|
|
|
$addedImages = array_udiff($importImages, $currentImages, $compareImages); |
718
|
|
|
|
719
|
|
|
/* @var Image[] $updatedImages */ |
720
|
|
|
$updatedImages = array_uintersect($importImages, $currentImages, $compareImages); |
721
|
|
|
|
722
|
|
|
/* @var Image[] $removedImages */ |
723
|
|
|
$removedImages = array_udiff($currentImages, $importImages, $compareImages); |
724
|
|
|
|
725
|
|
|
foreach ($addedImages as $addedImage) { |
726
|
|
|
$this->apply($this->createImageAddedEvent($addedImage)); |
727
|
|
|
} |
728
|
|
|
|
729
|
|
|
foreach ($updatedImages as $updatedImage) { |
730
|
|
|
$this->apply( |
731
|
|
|
$this->createImageUpdatedEvent( |
732
|
|
|
$updatedImage->getMediaObjectId(), |
733
|
|
|
$updatedImage->getDescription(), |
734
|
|
|
$updatedImage->getCopyrightHolder() |
735
|
|
|
) |
736
|
|
|
); |
737
|
|
|
} |
738
|
|
|
|
739
|
|
|
foreach ($removedImages as $removedImage) { |
740
|
|
|
$this->apply($this->createImageRemovedEvent($removedImage)); |
741
|
|
|
} |
742
|
|
|
|
743
|
|
|
if ($newMainImage) { |
744
|
|
|
$this->apply($this->createMainImageSelectedEvent($newMainImage)); |
745
|
|
|
} |
746
|
|
|
} |
747
|
|
|
|
748
|
|
|
/** |
749
|
|
|
* Delete the offer. |
750
|
|
|
*/ |
751
|
|
|
public function delete() |
752
|
|
|
{ |
753
|
|
|
$this->apply( |
754
|
|
|
$this->createOfferDeletedEvent() |
755
|
|
|
); |
756
|
|
|
} |
757
|
|
|
|
758
|
|
|
/** |
759
|
|
|
* @param CultureFeed_Cdb_Item_Base $cdbItem |
760
|
|
|
*/ |
761
|
|
|
protected function importWorkflowStatus(CultureFeed_Cdb_Item_Base $cdbItem) |
762
|
|
|
{ |
763
|
|
|
try { |
764
|
|
|
$workflowStatus = WorkflowStatus::fromNative($cdbItem->getWfStatus()); |
765
|
|
|
} catch (\InvalidArgumentException $exception) { |
766
|
|
|
$workflowStatus = WorkflowStatus::READY_FOR_VALIDATION(); |
767
|
|
|
} |
768
|
|
|
$this->workflowStatus = $workflowStatus; |
769
|
|
|
} |
770
|
|
|
|
771
|
|
|
/** |
772
|
|
|
* Publish the offer when it has workflowstatus draft. |
773
|
|
|
* @param \DateTimeInterface $publicationDate |
774
|
|
|
*/ |
775
|
|
|
public function publish(\DateTimeInterface $publicationDate) |
776
|
|
|
{ |
777
|
|
|
$this->guardPublish() ?: $this->apply( |
778
|
|
|
$this->createPublishedEvent($publicationDate) |
779
|
|
|
); |
780
|
|
|
} |
781
|
|
|
|
782
|
|
|
/** |
783
|
|
|
* @return bool |
784
|
|
|
* @throws Exception |
785
|
|
|
*/ |
786
|
|
View Code Duplication |
private function guardPublish() |
|
|
|
|
787
|
|
|
{ |
788
|
|
|
if ($this->workflowStatus === WorkflowStatus::READY_FOR_VALIDATION()) { |
789
|
|
|
return true; // nothing left to do if the offer has already been published |
790
|
|
|
} |
791
|
|
|
|
792
|
|
|
if ($this->workflowStatus !== WorkflowStatus::DRAFT()) { |
793
|
|
|
throw new Exception('You can not publish an offer that is not draft'); |
794
|
|
|
} |
795
|
|
|
|
796
|
|
|
return false; |
797
|
|
|
} |
798
|
|
|
|
799
|
|
|
/** |
800
|
|
|
* Approve the offer when it's waiting for validation. |
801
|
|
|
*/ |
802
|
|
|
public function approve() |
803
|
|
|
{ |
804
|
|
|
$this->guardApprove() ?: $this->apply($this->createApprovedEvent()); |
805
|
|
|
} |
806
|
|
|
|
807
|
|
|
/** |
808
|
|
|
* @return bool |
809
|
|
|
* @throws Exception |
810
|
|
|
*/ |
811
|
|
View Code Duplication |
private function guardApprove() |
|
|
|
|
812
|
|
|
{ |
813
|
|
|
if ($this->workflowStatus === WorkflowStatus::APPROVED()) { |
814
|
|
|
return true; // nothing left to do if the offer has already been approved |
815
|
|
|
} |
816
|
|
|
|
817
|
|
|
if ($this->workflowStatus !== WorkflowStatus::READY_FOR_VALIDATION()) { |
818
|
|
|
throw new Exception('You can not approve an offer that is not ready for validation'); |
819
|
|
|
} |
820
|
|
|
|
821
|
|
|
return false; |
822
|
|
|
} |
823
|
|
|
|
824
|
|
|
/** |
825
|
|
|
* Reject an offer that is waiting for validation with a given reason. |
826
|
|
|
* @param StringLiteral $reason |
827
|
|
|
*/ |
828
|
|
|
public function reject(StringLiteral $reason) |
829
|
|
|
{ |
830
|
|
|
$this->guardRejection($reason) ?: $this->apply($this->createRejectedEvent($reason)); |
831
|
|
|
} |
832
|
|
|
|
833
|
|
|
public function flagAsDuplicate() |
834
|
|
|
{ |
835
|
|
|
$reason = new StringLiteral(self::DUPLICATE_REASON); |
836
|
|
|
$this->guardRejection($reason) ?: $this->apply($this->createFlaggedAsDuplicate()); |
837
|
|
|
} |
838
|
|
|
|
839
|
|
|
public function flagAsInappropriate() |
840
|
|
|
{ |
841
|
|
|
$reason = new StringLiteral(self::INAPPROPRIATE_REASON); |
842
|
|
|
$this->guardRejection($reason) ?: $this->apply($this->createFlaggedAsInappropriate()); |
843
|
|
|
} |
844
|
|
|
|
845
|
|
|
/** |
846
|
|
|
* @param StringLiteral $reason |
847
|
|
|
* @return bool |
848
|
|
|
* false when the offer can still be rejected, true when the offer is already rejected for the same reason |
849
|
|
|
* @throws Exception |
850
|
|
|
*/ |
851
|
|
|
private function guardRejection(StringLiteral $reason) |
852
|
|
|
{ |
853
|
|
|
if ($this->workflowStatus === WorkflowStatus::REJECTED()) { |
854
|
|
|
if ($this->rejectedReason && $reason->sameValueAs($this->rejectedReason)) { |
855
|
|
|
return true; // nothing left to do if the offer has already been rejected for the same reason |
856
|
|
|
} else { |
857
|
|
|
throw new Exception('The offer has already been rejected for another reason: ' . $this->rejectedReason); |
858
|
|
|
} |
859
|
|
|
} |
860
|
|
|
|
861
|
|
|
if ($this->workflowStatus !== WorkflowStatus::READY_FOR_VALIDATION()) { |
862
|
|
|
throw new Exception('You can not reject an offer that is not ready for validation'); |
863
|
|
|
} |
864
|
|
|
|
865
|
|
|
return false; |
866
|
|
|
} |
867
|
|
|
|
868
|
|
|
/** |
869
|
|
|
* @param Title $title |
870
|
|
|
* @param Language $language |
871
|
|
|
* @return bool |
872
|
|
|
*/ |
873
|
|
View Code Duplication |
private function isTitleChanged(Title $title, Language $language) |
|
|
|
|
874
|
|
|
{ |
875
|
|
|
$languageCode = $language->getCode(); |
876
|
|
|
|
877
|
|
|
return !isset($this->titles[$languageCode]) || |
878
|
|
|
!$title->sameValueAs($this->titles[$languageCode]); |
879
|
|
|
} |
880
|
|
|
|
881
|
|
|
/** |
882
|
|
|
* @param Description $description |
883
|
|
|
* @param Language $language |
884
|
|
|
* @return bool |
885
|
|
|
*/ |
886
|
|
View Code Duplication |
private function isDescriptionChanged(Description $description, Language $language) |
|
|
|
|
887
|
|
|
{ |
888
|
|
|
$languageCode = $language->getCode(); |
889
|
|
|
|
890
|
|
|
return !isset($this->descriptions[$languageCode]) || |
891
|
|
|
!$description->sameValueAs($this->descriptions[$languageCode]); |
892
|
|
|
} |
893
|
|
|
|
894
|
|
|
/** |
895
|
|
|
* Overwrites or resets the main image and all media objects |
896
|
|
|
* by importing a new collection of images from UDB2. |
897
|
|
|
* |
898
|
|
|
* @param ImageCollection $images |
899
|
|
|
*/ |
900
|
|
|
public function importImagesFromUDB2(ImageCollection $images) |
901
|
|
|
{ |
902
|
|
|
$this->apply($this->createImagesImportedFromUDB2($images)); |
903
|
|
|
} |
904
|
|
|
|
905
|
|
|
/** |
906
|
|
|
* Overwrites or resets the main image and all media objects |
907
|
|
|
* by updating with a new collection of images from UDB2. |
908
|
|
|
* |
909
|
|
|
* @param ImageCollection $images |
910
|
|
|
*/ |
911
|
|
|
public function updateImagesFromUDB2(ImageCollection $images) |
912
|
|
|
{ |
913
|
|
|
$this->apply($this->createImagesUpdatedFromUDB2($images)); |
914
|
|
|
} |
915
|
|
|
|
916
|
|
|
/** |
917
|
|
|
* @param AbstractPublished $published |
918
|
|
|
*/ |
919
|
|
|
protected function applyPublished(AbstractPublished $published) |
|
|
|
|
920
|
|
|
{ |
921
|
|
|
$this->workflowStatus = WorkflowStatus::READY_FOR_VALIDATION(); |
922
|
|
|
} |
923
|
|
|
|
924
|
|
|
/** |
925
|
|
|
* @param AbstractApproved $approved |
926
|
|
|
*/ |
927
|
|
|
protected function applyApproved(AbstractApproved $approved) |
|
|
|
|
928
|
|
|
{ |
929
|
|
|
$this->workflowStatus = WorkflowStatus::APPROVED(); |
930
|
|
|
} |
931
|
|
|
|
932
|
|
|
/** |
933
|
|
|
* @param AbstractRejected $rejected |
934
|
|
|
*/ |
935
|
|
|
protected function applyRejected(AbstractRejected $rejected) |
936
|
|
|
{ |
937
|
|
|
$this->rejectedReason = $rejected->getReason(); |
938
|
|
|
$this->workflowStatus = WorkflowStatus::REJECTED(); |
939
|
|
|
} |
940
|
|
|
|
941
|
|
|
/** |
942
|
|
|
* @param AbstractFlaggedAsDuplicate $flaggedAsDuplicate |
943
|
|
|
*/ |
944
|
|
|
protected function applyFlaggedAsDuplicate(AbstractFlaggedAsDuplicate $flaggedAsDuplicate) |
|
|
|
|
945
|
|
|
{ |
946
|
|
|
$this->rejectedReason = new StringLiteral(self::DUPLICATE_REASON); |
947
|
|
|
$this->workflowStatus = WorkflowStatus::REJECTED(); |
948
|
|
|
} |
949
|
|
|
|
950
|
|
|
/** |
951
|
|
|
* @param AbstractFlaggedAsInappropriate $flaggedAsInappropriate |
952
|
|
|
*/ |
953
|
|
|
protected function applyFlaggedAsInappropriate(AbstractFlaggedAsInappropriate $flaggedAsInappropriate) |
|
|
|
|
954
|
|
|
{ |
955
|
|
|
$this->rejectedReason = new StringLiteral(self::INAPPROPRIATE_REASON); |
956
|
|
|
$this->workflowStatus = WorkflowStatus::REJECTED(); |
957
|
|
|
} |
958
|
|
|
|
959
|
|
|
protected function applyImageAdded(AbstractImageAdded $imageAdded) |
960
|
|
|
{ |
961
|
|
|
$this->images = $this->images->with($imageAdded->getImage()); |
962
|
|
|
} |
963
|
|
|
|
964
|
|
|
protected function applyImageUpdated(AbstractImageUpdated $imageUpdated) |
965
|
|
|
{ |
966
|
|
|
$image = $this->images->findImageByUUID($imageUpdated->getMediaObjectId()); |
967
|
|
|
|
968
|
|
|
$updatedImage = new Image( |
969
|
|
|
$image->getMediaObjectId(), |
970
|
|
|
$image->getMimeType(), |
971
|
|
|
new ImageDescription($imageUpdated->getDescription()->toNative()), |
972
|
|
|
new CopyrightHolder($imageUpdated->getCopyrightHolder()->toNative()), |
973
|
|
|
$image->getSourceLocation(), |
974
|
|
|
$image->getLanguage() |
975
|
|
|
); |
976
|
|
|
|
977
|
|
|
// Currently no other option to update an item inside a collection. |
978
|
|
|
$this->images = $this->images->without($image); |
979
|
|
|
$this->images = $this->images->with($updatedImage); |
980
|
|
|
} |
981
|
|
|
|
982
|
|
|
protected function applyImageRemoved(AbstractImageRemoved $imageRemoved) |
983
|
|
|
{ |
984
|
|
|
try { |
985
|
|
|
$this->images = $this->images->without($imageRemoved->getImage()); |
986
|
|
|
} catch (CollectionItemNotFoundException $exception) { |
|
|
|
|
987
|
|
|
} |
988
|
|
|
} |
989
|
|
|
|
990
|
|
|
protected function applyMainImageSelected(AbstractMainImageSelected $mainImageSelected) |
991
|
|
|
{ |
992
|
|
|
$this->images = $this->images->withMain($mainImageSelected->getImage()); |
993
|
|
|
} |
994
|
|
|
|
995
|
|
|
protected function applyOrganizerUpdated(AbstractOrganizerUpdated $organizerUpdated) |
996
|
|
|
{ |
997
|
|
|
$this->organizerId = $organizerUpdated->getOrganizerId(); |
998
|
|
|
} |
999
|
|
|
|
1000
|
|
|
protected function applyOrganizerDeleted(AbstractOrganizerDeleted $organizerDeleted) |
|
|
|
|
1001
|
|
|
{ |
1002
|
|
|
$this->organizerId = null; |
1003
|
|
|
} |
1004
|
|
|
|
1005
|
|
|
/** |
1006
|
|
|
* @param AbstractImagesImportedFromUDB2 $imagesImportedFromUDB2 |
1007
|
|
|
*/ |
1008
|
|
|
protected function applyImagesImportedFromUDB2(AbstractImagesImportedFromUDB2 $imagesImportedFromUDB2) |
1009
|
|
|
{ |
1010
|
|
|
$this->applyUdb2ImagesEvent($imagesImportedFromUDB2); |
1011
|
|
|
} |
1012
|
|
|
|
1013
|
|
|
/** |
1014
|
|
|
* @param AbstractImagesUpdatedFromUDB2 $imagesUpdatedFromUDB2 |
1015
|
|
|
*/ |
1016
|
|
|
protected function applyImagesUpdatedFromUDB2(AbstractImagesUpdatedFromUDB2 $imagesUpdatedFromUDB2) |
1017
|
|
|
{ |
1018
|
|
|
$this->applyUdb2ImagesEvent($imagesUpdatedFromUDB2); |
1019
|
|
|
} |
1020
|
|
|
|
1021
|
|
|
/** |
1022
|
|
|
* This indirect apply method can be called internally to deal with images coming from UDB2. |
1023
|
|
|
* Imports from UDB2 only contain the native Dutch content. |
1024
|
|
|
* @see https://github.com/cultuurnet/udb3-udb2-bridge/blob/db0a7ab2444f55bb3faae3d59b82b39aaeba253b/test/Media/ImageCollectionFactoryTest.php#L79-L103 |
1025
|
|
|
* Because of this we have to make sure translated images are left in place. |
1026
|
|
|
* |
1027
|
|
|
* @param AbstractImagesEvent $imagesEvent |
1028
|
|
|
*/ |
1029
|
|
|
protected function applyUdb2ImagesEvent(AbstractImagesEvent $imagesEvent) |
1030
|
|
|
{ |
1031
|
|
|
$newMainImage = $imagesEvent->getImages()->getMain(); |
1032
|
|
|
$dutchImagesList = $imagesEvent->getImages()->toArray(); |
1033
|
|
|
$translatedImagesList = array_filter( |
1034
|
|
|
$this->images->toArray(), |
1035
|
|
|
function (Image $image) { |
1036
|
|
|
return $image->getLanguage()->getCode() !== 'nl'; |
1037
|
|
|
} |
1038
|
|
|
); |
1039
|
|
|
|
1040
|
|
|
$imagesList = array_merge($dutchImagesList, $translatedImagesList); |
1041
|
|
|
$images = ImageCollection::fromArray($imagesList); |
1042
|
|
|
|
1043
|
|
|
$this->images = isset($newMainImage) ? $images->withMain($newMainImage) : $images; |
1044
|
|
|
} |
1045
|
|
|
|
1046
|
|
|
/** |
1047
|
|
|
* @param Label $label |
1048
|
|
|
* @return AbstractLabelAdded |
1049
|
|
|
*/ |
1050
|
|
|
abstract protected function createLabelAddedEvent(Label $label); |
1051
|
|
|
|
1052
|
|
|
/** |
1053
|
|
|
* @param Label $label |
1054
|
|
|
* @return AbstractLabelRemoved |
1055
|
|
|
*/ |
1056
|
|
|
abstract protected function createLabelRemovedEvent(Label $label); |
1057
|
|
|
|
1058
|
|
|
/** |
1059
|
|
|
* @param Labels $labels |
1060
|
|
|
* @return AbstractLabelsImported |
1061
|
|
|
*/ |
1062
|
|
|
abstract protected function createLabelsImportedEvent(Labels $labels); |
1063
|
|
|
|
1064
|
|
|
/** |
1065
|
|
|
* @param Language $language |
1066
|
|
|
* @param Title $title |
1067
|
|
|
* @return AbstractTitleTranslated |
1068
|
|
|
*/ |
1069
|
|
|
abstract protected function createTitleTranslatedEvent(Language $language, Title $title); |
1070
|
|
|
|
1071
|
|
|
/** |
1072
|
|
|
* @param Language $language |
1073
|
|
|
* @param Description $description |
1074
|
|
|
* @return AbstractDescriptionTranslated |
1075
|
|
|
*/ |
1076
|
|
|
abstract protected function createDescriptionTranslatedEvent(Language $language, Description $description); |
1077
|
|
|
|
1078
|
|
|
/** |
1079
|
|
|
* @param Image $image |
1080
|
|
|
* @return AbstractImageAdded |
1081
|
|
|
*/ |
1082
|
|
|
abstract protected function createImageAddedEvent(Image $image); |
1083
|
|
|
|
1084
|
|
|
/** |
1085
|
|
|
* @param Image $image |
1086
|
|
|
* @return AbstractImageRemoved |
1087
|
|
|
*/ |
1088
|
|
|
abstract protected function createImageRemovedEvent(Image $image); |
1089
|
|
|
|
1090
|
|
|
/** |
1091
|
|
|
* @param UUID $uuid |
1092
|
|
|
* @param StringLiteral $description |
1093
|
|
|
* @param StringLiteral $copyrightHolder |
1094
|
|
|
* @return AbstractImageUpdated |
1095
|
|
|
*/ |
1096
|
|
|
abstract protected function createImageUpdatedEvent( |
1097
|
|
|
UUID $uuid, |
1098
|
|
|
StringLiteral $description, |
1099
|
|
|
StringLiteral $copyrightHolder |
1100
|
|
|
); |
1101
|
|
|
|
1102
|
|
|
/** |
1103
|
|
|
* @param Image $image |
1104
|
|
|
* @return AbstractMainImageSelected |
1105
|
|
|
*/ |
1106
|
|
|
abstract protected function createMainImageSelectedEvent(Image $image); |
1107
|
|
|
|
1108
|
|
|
/** |
1109
|
|
|
* @return AbstractOfferDeleted |
1110
|
|
|
*/ |
1111
|
|
|
abstract protected function createOfferDeletedEvent(); |
1112
|
|
|
|
1113
|
|
|
/** |
1114
|
|
|
* @param Title $title |
1115
|
|
|
* @return AbstractTitleUpdated |
1116
|
|
|
*/ |
1117
|
|
|
abstract protected function createTitleUpdatedEvent(Title $title); |
1118
|
|
|
|
1119
|
|
|
/** |
1120
|
|
|
* @param Description $description |
1121
|
|
|
* @return AbstractDescriptionUpdated |
1122
|
|
|
*/ |
1123
|
|
|
abstract protected function createDescriptionUpdatedEvent(Description $description); |
1124
|
|
|
|
1125
|
|
|
/** |
1126
|
|
|
* @param Calendar $calendar |
1127
|
|
|
* @return AbstractCalendarUpdated |
1128
|
|
|
*/ |
1129
|
|
|
abstract protected function createCalendarUpdatedEvent(Calendar $calendar); |
1130
|
|
|
|
1131
|
|
|
/** |
1132
|
|
|
* @param string $typicalAgeRange |
1133
|
|
|
* @return AbstractTypicalAgeRangeUpdated |
1134
|
|
|
*/ |
1135
|
|
|
abstract protected function createTypicalAgeRangeUpdatedEvent($typicalAgeRange); |
1136
|
|
|
|
1137
|
|
|
/** |
1138
|
|
|
* @return AbstractTypicalAgeRangeDeleted |
1139
|
|
|
*/ |
1140
|
|
|
abstract protected function createTypicalAgeRangeDeletedEvent(); |
1141
|
|
|
|
1142
|
|
|
/** |
1143
|
|
|
* @param string $organizerId |
1144
|
|
|
* @return AbstractOrganizerUpdated |
1145
|
|
|
*/ |
1146
|
|
|
abstract protected function createOrganizerUpdatedEvent($organizerId); |
1147
|
|
|
|
1148
|
|
|
/** |
1149
|
|
|
* @param string $organizerId |
1150
|
|
|
* @return AbstractOrganizerDeleted |
1151
|
|
|
*/ |
1152
|
|
|
abstract protected function createOrganizerDeletedEvent($organizerId); |
1153
|
|
|
|
1154
|
|
|
/** |
1155
|
|
|
* @param ContactPoint $contactPoint |
1156
|
|
|
* @return AbstractContactPointUpdated |
1157
|
|
|
*/ |
1158
|
|
|
abstract protected function createContactPointUpdatedEvent(ContactPoint $contactPoint); |
1159
|
|
|
|
1160
|
|
|
/** |
1161
|
|
|
* @param Coordinates $coordinates |
1162
|
|
|
* @return AbstractGeoCoordinatesUpdated |
1163
|
|
|
*/ |
1164
|
|
|
abstract protected function createGeoCoordinatesUpdatedEvent(Coordinates $coordinates); |
1165
|
|
|
|
1166
|
|
|
/** |
1167
|
|
|
* @param BookingInfo $bookingInfo |
1168
|
|
|
* @return AbstractBookingInfoUpdated |
1169
|
|
|
*/ |
1170
|
|
|
abstract protected function createBookingInfoUpdatedEvent(BookingInfo $bookingInfo); |
1171
|
|
|
|
1172
|
|
|
/** |
1173
|
|
|
* @param PriceInfo $priceInfo |
1174
|
|
|
* @return AbstractPriceInfoUpdated |
1175
|
|
|
*/ |
1176
|
|
|
abstract protected function createPriceInfoUpdatedEvent(PriceInfo $priceInfo); |
1177
|
|
|
|
1178
|
|
|
/** |
1179
|
|
|
* @param \DateTimeInterface $publicationDate |
1180
|
|
|
* @return AbstractPublished |
1181
|
|
|
*/ |
1182
|
|
|
abstract protected function createPublishedEvent(\DateTimeInterface $publicationDate); |
1183
|
|
|
|
1184
|
|
|
/** |
1185
|
|
|
* @return AbstractApproved |
1186
|
|
|
*/ |
1187
|
|
|
abstract protected function createApprovedEvent(); |
1188
|
|
|
|
1189
|
|
|
/** |
1190
|
|
|
* @param StringLiteral $reason |
1191
|
|
|
* @return AbstractRejected |
1192
|
|
|
*/ |
1193
|
|
|
abstract protected function createRejectedEvent(StringLiteral $reason); |
1194
|
|
|
|
1195
|
|
|
/** |
1196
|
|
|
* @return AbstractFlaggedAsDuplicate |
1197
|
|
|
*/ |
1198
|
|
|
abstract protected function createFlaggedAsDuplicate(); |
1199
|
|
|
|
1200
|
|
|
/** |
1201
|
|
|
* @return AbstractFlaggedAsInappropriate |
1202
|
|
|
*/ |
1203
|
|
|
abstract protected function createFlaggedAsInappropriate(); |
1204
|
|
|
|
1205
|
|
|
/** |
1206
|
|
|
* @param ImageCollection $images |
1207
|
|
|
* @return AbstractImagesImportedFromUDB2 |
1208
|
|
|
*/ |
1209
|
|
|
abstract protected function createImagesImportedFromUDB2(ImageCollection $images); |
1210
|
|
|
|
1211
|
|
|
/** |
1212
|
|
|
* @param ImageCollection $images |
1213
|
|
|
* @return AbstractImagesUpdatedFromUDB2 |
1214
|
|
|
*/ |
1215
|
|
|
abstract protected function createImagesUpdatedFromUDB2(ImageCollection $images); |
1216
|
|
|
|
1217
|
|
|
/** |
1218
|
|
|
* @param EventType $type |
1219
|
|
|
* @return AbstractTypeUpdated |
1220
|
|
|
*/ |
1221
|
|
|
abstract protected function createTypeUpdatedEvent(EventType $type); |
1222
|
|
|
|
1223
|
|
|
/** |
1224
|
|
|
* @param Theme $theme |
1225
|
|
|
* @return AbstractThemeUpdated |
1226
|
|
|
*/ |
1227
|
|
|
abstract protected function createThemeUpdatedEvent(Theme $theme); |
1228
|
|
|
|
1229
|
|
|
/** |
1230
|
|
|
* @param array $facilities |
1231
|
|
|
* @return AbstractFacilitiesUpdated |
1232
|
|
|
*/ |
1233
|
|
|
abstract protected function createFacilitiesUpdatedEvent(array $facilities); |
1234
|
|
|
} |
1235
|
|
|
|
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.