Completed
Push — master ( 7c299e...0e1155 )
by Kristof
12s
created

fixOrganizerLabelEvent()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 2
nop 2
1
<?php
2
3
namespace CultuurNet\UDB3;
4
5
use Broadway\Serializer\SerializerInterface;
6
use Broadway\Serializer\SimpleInterfaceSerializer;
7
use CultuurNet\UDB3\Event\Events\BookingInfoUpdated as EventBookingInfoUpdated;
8
use CultuurNet\UDB3\Event\Events\ContactPointUpdated as EventContactPointUpdated;
9
use CultuurNet\UDB3\Event\Events\DescriptionTranslated;
10
use CultuurNet\UDB3\Event\Events\DescriptionUpdated as EventDescriptionUpdated;
11
use CultuurNet\UDB3\Event\Events\EventDeleted;
12
use CultuurNet\UDB3\Event\Events\EventImportedFromUDB2;
13
use CultuurNet\UDB3\Event\Events\LabelAdded;
14
use CultuurNet\UDB3\Event\Events\LabelRemoved;
15
use CultuurNet\UDB3\Event\Events\LabelsMerged;
16
use CultuurNet\UDB3\Event\Events\MajorInfoUpdated;
17
use CultuurNet\UDB3\Event\Events\OrganizerDeleted as EventOrganizerDeleted;
18
use CultuurNet\UDB3\Event\Events\OrganizerUpdated as EventOrganizerUpdated;
19
use CultuurNet\UDB3\Event\Events\TitleTranslated;
20
use CultuurNet\UDB3\Event\Events\TypicalAgeRangeDeleted as EventTypicalAgeRangeDeleted;
21
use CultuurNet\UDB3\Event\Events\TypicalAgeRangeUpdated as EventTypicalAgeRangeUpdated;
22
use CultuurNet\UDB3\EventSourcing\PayloadManipulatingSerializer;
23
use CultuurNet\UDB3\Label\ReadModels\JSON\Repository\ReadRepositoryInterface;
24
use CultuurNet\UDB3\Label\ValueObjects\Visibility;
25
use CultuurNet\UDB3\Place\Events\BookingInfoUpdated as PlaceBookingInfoUpdated;
26
use CultuurNet\UDB3\Place\Events\ContactPointUpdated as PlaceContactPointUpdated;
27
use CultuurNet\UDB3\Place\Events\DescriptionUpdated as PlaceDescriptionUpdated;
28
use CultuurNet\UDB3\Place\Events\OrganizerDeleted as PlaceOrganizerDeleted;
29
use CultuurNet\UDB3\Place\Events\OrganizerUpdated as PlaceOrganizerUpdated;
30
use CultuurNet\UDB3\Place\Events\PlaceDeleted;
31
use CultuurNet\UDB3\Place\Events\TypicalAgeRangeDeleted as PlaceTypicalAgeRangeDeleted;
32
use CultuurNet\UDB3\Place\Events\TypicalAgeRangeUpdated as PlaceTypicalAgeRangeUpdated;
33
use CultuurNet\UDB3\UsedLabelsMemory\Created as UsedLabelsMemoryCreated;
34
use CultuurNet\UDB3\UsedLabelsMemory\LabelUsed;
35
use ValueObjects\Identity\UUID;
36
37
/**
38
 * Factory chaining together the logic to manipulate the payload of old events
39
 * in order to make it usable by new events.
40
 *
41
 * Some cases:
42
 * - changing the class name / namespace after class renames
43
 * - changing the names of properties
44
 */
45
class BackwardsCompatiblePayloadSerializerFactory
46
{
47
48
    private function __construct()
49
    {
50
51
    }
52
53
    /**
54
     * @param ReadRepositoryInterface $labelRepository
55
     * @return SerializerInterface
56
     */
57
    public static function createSerializer(ReadRepositoryInterface $labelRepository)
58
    {
59
        $payloadManipulatingSerializer = new PayloadManipulatingSerializer(
60
            new SimpleInterfaceSerializer()
61
        );
62
63
        /*
64
         * KEYWORDS EVENTS
65
         */
66
67
        $payloadManipulatingSerializer->manipulateEventsOfClass(
68
            'CultuurNet\UDB3\UsedKeywordsMemory\Created',
69
            function (array $serializedObject) {
70
                $serializedObject['class'] = UsedLabelsMemoryCreated::class;
71
72
                return $serializedObject;
73
            }
74
        );
75
76
        $payloadManipulatingSerializer->manipulateEventsOfClass(
77
            'CultuurNet\UDB3\UsedKeywordsMemory\KeywordUsed',
78
            function (array $serializedObject) {
79
                $serializedObject['class'] = LabelUsed::class;
80
81
                $serializedObject = self::replaceKeywordWithLabel($serializedObject);
82
83
                return $serializedObject;
84
            }
85
        );
86
87
        /*
88
         * TRANSLATION EVENTS
89
         */
90
91
        $payloadManipulatingSerializer->manipulateEventsOfClass(
92
            'CultuurNet\UDB3\Event\TitleTranslated',
93
            function (array $serializedObject) {
94
                $serializedObject['class'] = TitleTranslated::class;
95
96
                $serializedObject = self::replaceEventIdWithItemId($serializedObject);
97
98
                return $serializedObject;
99
            }
100
        );
101
102
        $payloadManipulatingSerializer->manipulateEventsOfClass(
103
            'CultuurNet\UDB3\Event\DescriptionTranslated',
104
            function (array $serializedObject) {
105
                $serializedObject['class'] = DescriptionTranslated::class;
106
107
                $serializedObject = self::replaceEventIdWithItemId($serializedObject);
108
109
                return $serializedObject;
110
            }
111
        );
112
113
        /*
114
         * LABEL EVENTS
115
         */
116
117
        $payloadManipulatingSerializer->manipulateEventsOfClass(
118
            'CultuurNet\UDB3\Label\Events\MadeInvisible',
119
            function (array $serializedObject) use ($labelRepository) {
120
                return self::addLabelName($serializedObject, $labelRepository);
121
            }
122
        );
123
124
        $payloadManipulatingSerializer->manipulateEventsOfClass(
125
            'CultuurNet\UDB3\Label\Events\MadeVisible',
126
            function (array $serializedObject) use ($labelRepository) {
127
                return self::addLabelName($serializedObject, $labelRepository);
128
            }
129
        );
130
131
        $payloadManipulatingSerializer->manipulateEventsOfClass(
132
            'CultuurNet\UDB3\Label\Events\MadePrivate',
133
            function (array $serializedObject) use ($labelRepository) {
134
                return self::addLabelName($serializedObject, $labelRepository);
135
            }
136
        );
137
138
        $payloadManipulatingSerializer->manipulateEventsOfClass(
139
            'CultuurNet\UDB3\Label\Events\MadePublic',
140
            function (array $serializedObject) use ($labelRepository) {
141
                return self::addLabelName($serializedObject, $labelRepository);
142
            }
143
        );
144
145
        $payloadManipulatingSerializer->manipulateEventsOfClass(
146
            'CultuurNet\UDB3\Organizer\Events\LabelAdded',
147
            function (array $serializedObject) use ($labelRepository) {
148
                return self::fixOrganizerLabelEvent($serializedObject, $labelRepository);
149
            }
150
        );
151
152
        $payloadManipulatingSerializer->manipulateEventsOfClass(
153
            'CultuurNet\UDB3\Organizer\Events\LabelRemoved',
154
            function (array $serializedObject) use ($labelRepository) {
155
                return self::fixOrganizerLabelEvent($serializedObject, $labelRepository);
156
            }
157
        );
158
159
        $payloadManipulatingSerializer->manipulateEventsOfClass(
160
            'CultuurNet\UDB3\Event\Events\EventWasLabelled',
161
            function (array $serializedObject) {
162
                $serializedObject['class'] = LabelAdded::class;
163
164
                $serializedObject = self::replaceEventIdWithItemId($serializedObject);
165
166
                return $serializedObject;
167
            }
168
        );
169
170
        $payloadManipulatingSerializer->manipulateEventsOfClass(
171
            'CultuurNet\UDB3\Event\EventWasTagged',
172
            function (array $serializedObject) {
173
                $serializedObject['class'] = LabelAdded::class;
174
175
                $serializedObject = self::replaceEventIdWithItemId($serializedObject);
176
177
                $serializedObject = self::replaceKeywordWithLabel($serializedObject);
178
179
                return $serializedObject;
180
            }
181
        );
182
183
        $payloadManipulatingSerializer->manipulateEventsOfClass(
184
            'CultuurNet\UDB3\Event\TagErased',
185
            function (array $serializedObject) {
186
                $serializedObject['class'] = LabelRemoved::class;
187
188
                $serializedObject = self::replaceEventIdWithItemId($serializedObject);
189
190
                $serializedObject = self::replaceKeywordWithLabel($serializedObject);
191
192
                return $serializedObject;
193
            }
194
        );
195
196
        $payloadManipulatingSerializer->manipulateEventsOfClass(
197
            'CultuurNet\UDB3\Event\Events\Unlabelled',
198
            function (array $serializedObject) {
199
                $serializedObject['class'] = LabelRemoved::class;
200
201
                $serializedObject = self::replaceEventIdWithItemId($serializedObject);
202
203
                return $serializedObject;
204
            }
205
        );
206
207
        $payloadManipulatingSerializer->manipulateEventsOfClass(
208
            'CultuurNet\UDB3\Event\Events\LabelsApplied',
209
            function (array $serializedObject) {
210
                $serializedObject['class'] = LabelsMerged::class;
211
212
                $keywordsString = $serializedObject['payload']['keywords_string'];
213
214
                $query = array();
215
                parse_str($keywordsString, $query);
216
217
                $keywords = explode(';', $query['keywords']);
218
                $visibles = explode(';', $query['visibles']);
219
220
                $labelsArray = array();
221
222
                foreach ($keywords as $key => $keyword) {
223
                    $visible = 'true' === $visibles[$key];
224
                    $labelsArray[] = new Label(
225
                        $keyword,
226
                        $visible
227
                    );
228
                }
229
230
                $labels = array_map(
231
                    function (Label $label) {
232
                        return [
233
                            'text' => (string) $label,
234
                            'visible' => $label->isVisible(),
235
                        ];
236
                    },
237
                    $labelsArray
238
                );
239
240
                $serializedObject['payload']['labels'] = $labels;
241
                unset($serializedObject['payload']['keywords_string']);
242
243
                return $serializedObject;
244
            }
245
        );
246
247
        /**
248
         * UBD2 IMPORT
249
         */
250
251
        $payloadManipulatingSerializer->manipulateEventsOfClass(
252
            'CultuurNet\UDB3\Event\EventImportedFromUDB2',
253
            function (array $serializedObject) {
254
                $serializedObject['class'] = EventImportedFromUDB2::class;
255
256
                return $serializedObject;
257
            }
258
        );
259
260
        /**
261
         * EventEvent to AbstractEvent (Offer)
262
         */
263
        $refactoredEventEvents = [
264
            EventBookingInfoUpdated::class,
265
            EventTypicalAgeRangeDeleted::class,
266
            EventTypicalAgeRangeUpdated::class,
267
            EventContactPointUpdated::class,
268
            MajorInfoUpdated::class,
269
            EventOrganizerUpdated::class,
270
            EventOrganizerDeleted::class,
271
            EventDescriptionUpdated::class,
272
            EventDeleted::class,
273
        ];
274
275
        foreach ($refactoredEventEvents as $refactoredEventEvent) {
276
            $payloadManipulatingSerializer->manipulateEventsOfClass(
277
                $refactoredEventEvent,
278
                function (array $serializedObject) {
279
                    $serializedObject = self::replaceEventIdWithItemId($serializedObject);
280
                    return $serializedObject;
281
                }
282
            );
283
        }
284
285
        /**
286
         * PlaceEvent to AbstractEvent (Offer)
287
         */
288
        $refactoredPlaceEvents = [
289
            PlaceOrganizerUpdated::class,
290
            PlaceOrganizerDeleted::class,
291
            PlaceBookingInfoUpdated::class,
292
            PlaceTypicalAgeRangeDeleted::class,
293
            PlaceTypicalAgeRangeUpdated::class,
294
            PlaceContactPointUpdated::class,
295
            PlaceDescriptionUpdated::class,
296
            PlaceDeleted::class,
297
        ];
298
299
        foreach ($refactoredPlaceEvents as $refactoredPlaceEvent) {
300
            $payloadManipulatingSerializer->manipulateEventsOfClass(
301
                $refactoredPlaceEvent,
302
                function (array $serializedObject) {
303
                    $serializedObject = self::replacePlaceIdWithItemId($serializedObject);
304
                    return $serializedObject;
305
                }
306
            );
307
        }
308
309
        return $payloadManipulatingSerializer;
310
    }
311
312
    /**
313
     * @param array $serializedObject
314
     * @return array
315
     */
316
    private static function replaceEventIdWithItemId(array $serializedObject)
317
    {
318
        return self::replaceKeys('event_id', 'item_id', $serializedObject);
319
    }
320
321
    /**
322
     * @param array $serializedObject
323
     * @return array
324
     */
325
    private static function replacePlaceIdWithItemId(array $serializedObject)
326
    {
327
        return self::replaceKeys('place_id', 'item_id', $serializedObject);
328
    }
329
330
    /**
331
     * @param string $oldKey
332
     * @param string $newKey
333
     * @param array $serializedObject
334
     * @return array
335
     */
336
    private static function replaceKeys($oldKey, $newKey, $serializedObject)
337
    {
338
        if (isset($serializedObject['payload'][$oldKey])) {
339
            $value = $serializedObject['payload'][$oldKey];
340
            $serializedObject['payload'][$newKey] = $value;
341
            unset($serializedObject['payload'][$oldKey]);
342
        }
343
344
        return $serializedObject;
345
    }
346
347
    /**
348
     * @param array $serializedObject
349
     * @return array
350
     */
351
    private static function replaceKeywordWithLabel(array $serializedObject)
352
    {
353
        $keyword = $serializedObject['payload']['keyword'];
354
        $serializedObject['payload']['label'] = $keyword;
355
        unset($serializedObject['payload']['keyword']);
356
357
        return $serializedObject;
358
    }
359
360
    /**
361
     * @param array $serializedObject
362
     * @param ReadRepositoryInterface $labelRepository
363
     * @return array
364
     */
365
    private static function addLabelName(
366
        array $serializedObject,
367
        ReadRepositoryInterface $labelRepository
368
    ) {
369
        if (!isset($serializedObject['payload']['name'])) {
370
            $uuid = $serializedObject['payload']['uuid'];
371
            $label = $labelRepository->getByUuid(new UUID($uuid));
372
373
            $serializedObject['payload']['name'] = $label->getName()->toNative();
374
        }
375
376
        return $serializedObject;
377
    }
378
379
    /**
380
     * @param array $serializedObject
381
     * @param ReadRepositoryInterface $labelRepository
382
     * @return array
383
     */
384
    private static function fixOrganizerLabelEvent(
385
        array $serializedObject,
386
        ReadRepositoryInterface $labelRepository
387
    ) {
388
        if (!isset($serializedObject['payload']['label']) ||
389
            !isset($serializedObject['payload']['visibility'])) {
390
            $uuid = $serializedObject['payload']['labelId'];
391
            $label = $labelRepository->getByUuid(new UUID($uuid));
392
393
            $serializedObject['payload']['label'] = $label->getName()->toNative();
394
            $serializedObject['payload']['visibility'] = $label->getVisibility() === Visibility::VISIBLE();
395
        }
396
397
        return $serializedObject;
398
    }
399
}
400