Completed
Pull Request — master (#344)
by Luc
05:16
created

BackwardsCompatiblePayloadSerializerFactory   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 347
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 6
dl 0
loc 347
rs 10
c 0
b 0
f 0

9 Methods

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