Completed
Push — master ( 07eafb...b4894d )
by Luc
12:27 queued 01:31
created

OrganizerLDProjector::loadDocumentFromRepository()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
3
namespace CultuurNet\UDB3\Organizer;
4
5
use Broadway\Domain\DateTime;
6
use Broadway\Domain\DomainMessage;
7
use Broadway\EventHandling\EventBusInterface;
8
use Broadway\EventHandling\EventListenerInterface;
9
use CultuurNet\UDB3\Actor\ActorEvent;
10
use CultuurNet\UDB3\Cdb\ActorItemFactory;
11
use CultuurNet\UDB3\Event\ReadModel\DocumentGoneException;
12
use CultuurNet\UDB3\Event\ReadModel\DocumentRepositoryInterface;
13
use CultuurNet\UDB3\EventHandling\DelegateEventHandlingToSpecificMethodTrait;
14
use CultuurNet\UDB3\Iri\IriGeneratorInterface;
15
use CultuurNet\UDB3\Label;
16
use CultuurNet\UDB3\Language;
17
use CultuurNet\UDB3\Organizer\Events\AddressUpdated;
18
use CultuurNet\UDB3\Organizer\Events\ContactPointUpdated;
19
use CultuurNet\UDB3\Organizer\Events\LabelAdded;
20
use CultuurNet\UDB3\Organizer\Events\LabelRemoved;
21
use CultuurNet\UDB3\Organizer\Events\OrganizerCreated;
22
use CultuurNet\UDB3\Organizer\Events\OrganizerCreatedWithUniqueWebsite;
23
use CultuurNet\UDB3\Organizer\Events\OrganizerDeleted;
24
use CultuurNet\UDB3\Organizer\Events\OrganizerImportedFromUDB2;
25
use CultuurNet\UDB3\Organizer\Events\OrganizerUpdatedFromUDB2;
26
use CultuurNet\UDB3\Organizer\Events\TitleUpdated;
27
use CultuurNet\UDB3\Organizer\Events\WebsiteUpdated;
28
use CultuurNet\UDB3\Organizer\ReadModel\JSONLD\CdbXMLImporter;
29
use CultuurNet\UDB3\ReadModel\JsonDocument;
30
use CultuurNet\UDB3\ReadModel\MultilingualJsonLDProjectorTrait;
31
32
class OrganizerLDProjector implements EventListenerInterface
33
{
34
    use MultilingualJsonLDProjectorTrait;
35
    /**
36
     * @uses applyOrganizerImportedFromUDB2
37
     * @uses applyOrganizerCreated
38
     * @uses applyOrganizerCreatedWithUniqueWebsite
39
     * @uses applyWebsiteUpdated
40
     * @uses applyTitleUpdated
41
     * @uses applyAddressUpdated
42
     * @uses applyContactPointUpdated
43
     * @uses applyOrganizerUpdatedFRomUDB2
44
     * @uses applyLabelAdded
45
     * @uses applyLabelRemoved
46
     * @uses applyOrganizerDeleted
47
     */
48
    use DelegateEventHandlingToSpecificMethodTrait;
49
50
    /**
51
     * @var DocumentRepositoryInterface
52
     */
53
    protected $repository;
54
55
    /**
56
     * @var IriGeneratorInterface
57
     */
58
    protected $iriGenerator;
59
60
    /**
61
     * @var EventBusInterface
62
     */
63
    protected $eventBus;
64
65
    /**
66
     * @var CdbXMLImporter
67
     */
68
    private $cdbXMLImporter;
69
70
    /**
71
     * @param DocumentRepositoryInterface $repository
72
     * @param IriGeneratorInterface $iriGenerator
73
     * @param EventBusInterface $eventBus
74
     */
75
    public function __construct(
76
        DocumentRepositoryInterface $repository,
77
        IriGeneratorInterface $iriGenerator,
78
        EventBusInterface $eventBus
79
    ) {
80
        $this->repository = $repository;
81
        $this->iriGenerator = $iriGenerator;
82
        $this->eventBus = $eventBus;
83
        $this->cdbXMLImporter = new CdbXMLImporter();
84
    }
85
86
    /**
87
     * @param OrganizerImportedFromUDB2 $organizerImportedFromUDB2
88
     */
89 View Code Duplication
    private function applyOrganizerImportedFromUDB2(
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...
90
        OrganizerImportedFromUDB2 $organizerImportedFromUDB2
91
    ) {
92
        $udb2Actor = ActorItemFactory::createActorFromCdbXml(
93
            $organizerImportedFromUDB2->getCdbXmlNamespaceUri(),
94
            $organizerImportedFromUDB2->getCdbXml()
95
        );
96
97
        $document = $this->newDocument($organizerImportedFromUDB2->getActorId());
98
        $actorLd = $document->getBody();
99
100
        $this->setMainLanguage($actorLd, new Language('nl'));
101
102
        $actorLd = $this->cdbXMLImporter->documentWithCdbXML(
103
            $actorLd,
104
            $udb2Actor
105
        );
106
107
        $this->repository->save($document->withBody($actorLd));
108
    }
109
110
    /**
111
     * @param OrganizerCreated $organizerCreated
112
     * @param DomainMessage $domainMessage
113
     */
114
    private function applyOrganizerCreated(OrganizerCreated $organizerCreated, DomainMessage $domainMessage)
115
    {
116
        $document = $this->newDocument($organizerCreated->getOrganizerId());
117
118
        $jsonLD = $document->getBody();
119
120
        $jsonLD->{'@id'} = $this->iriGenerator->iri(
121
            $organizerCreated->getOrganizerId()
122
        );
123
124
        $this->setMainLanguage($jsonLD, new Language('nl'));
125
126
        $jsonLD->name = $organizerCreated->getTitle();
127
128
        $addresses = $organizerCreated->getAddresses();
129
        $jsonLD->addresses = array();
130
        foreach ($addresses as $address) {
131
            $jsonLD->addresses[] = array(
132
                'addressCountry' => $address->getCountry(),
133
                'addressLocality' => $address->getLocality(),
134
                'postalCode' => $address->getPostalCode(),
135
                'streetAddress' => $address->getStreetAddress(),
136
            );
137
        }
138
139
        $jsonLD->phone = $organizerCreated->getPhones();
140
        $jsonLD->email = $organizerCreated->getEmails();
141
        $jsonLD->url = $organizerCreated->getUrls();
142
143
        $recordedOn = $domainMessage->getRecordedOn()->toString();
144
        $jsonLD->created = \DateTime::createFromFormat(
145
            DateTime::FORMAT_STRING,
146
            $recordedOn
147
        )->format('c');
148
149
        $metaData = $domainMessage->getMetadata()->serialize();
150 View Code Duplication
        if (isset($metaData['user_id']) && isset($metaData['user_nick'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
151
            $jsonLD->creator = "{$metaData['user_id']} ({$metaData['user_nick']})";
152
        }
153
154
        $this->repository->save($document->withBody($jsonLD));
155
    }
156
157
    /**
158
     * @param OrganizerCreatedWithUniqueWebsite $organizerCreated
159
     * @param DomainMessage $domainMessage
160
     */
161
    private function applyOrganizerCreatedWithUniqueWebsite(
162
        OrganizerCreatedWithUniqueWebsite $organizerCreated,
163
        DomainMessage $domainMessage
164
    ) {
165
        $document = $this->newDocument($organizerCreated->getOrganizerId());
166
167
        $jsonLD = $document->getBody();
168
169
        $jsonLD->{'@id'} = $this->iriGenerator->iri(
170
            $organizerCreated->getOrganizerId()
171
        );
172
173
        $this->setMainLanguage($jsonLD, new Language('nl'));
174
175
        $jsonLD->url = (string) $organizerCreated->getWebsite();
176
        $jsonLD->name = $organizerCreated->getTitle();
177
178
        $recordedOn = $domainMessage->getRecordedOn()->toString();
179
        $jsonLD->created = \DateTime::createFromFormat(
180
            DateTime::FORMAT_STRING,
181
            $recordedOn
182
        )->format('c');
183
184
        $metaData = $domainMessage->getMetadata()->serialize();
185 View Code Duplication
        if (isset($metaData['user_id']) && isset($metaData['user_nick'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
186
            $jsonLD->creator = "{$metaData['user_id']} ({$metaData['user_nick']})";
187
        }
188
189
        $this->repository->save($document->withBody($jsonLD));
190
    }
191
192
    /**
193
     * @param WebsiteUpdated $websiteUpdated
194
     */
195 View Code Duplication
    private function applyWebsiteUpdated(WebsiteUpdated $websiteUpdated)
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...
196
    {
197
        $organizerId = $websiteUpdated->getOrganizerId();
198
199
        $document = $this->repository->get($organizerId);
200
201
        $jsonLD = $document->getBody();
202
        $jsonLD->url = (string) $websiteUpdated->getWebsite();
203
204
        $this->repository->save($document->withBody($jsonLD));
205
    }
206
207
    /**
208
     * @param TitleUpdated $titleUpdated
209
     */
210 View Code Duplication
    private function applyTitleUpdated(TitleUpdated $titleUpdated)
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...
211
    {
212
        $organizerId = $titleUpdated->getOrganizerId();
213
214
        $document = $this->repository->get($organizerId);
215
216
        $jsonLD = $document->getBody();
217
        $jsonLD->name = $titleUpdated->getTitle()->toNative();
218
219
        $this->repository->save($document->withBody($jsonLD));
220
    }
221
222
    /**
223
     * @param AddressUpdated $addressUpdated
224
     */
225 View Code Duplication
    private function applyAddressUpdated(AddressUpdated $addressUpdated)
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...
226
    {
227
        $organizerId = $addressUpdated->getOrganizerId();
228
        $address = $addressUpdated->getAddress();
229
230
        $document = $this->repository->get($organizerId);
231
232
        $jsonLD = $document->getBody();
233
        $jsonLD->address = $address->toJsonLd();
234
235
        $this->repository->save($document->withBody($jsonLD));
236
    }
237
238
    /**
239
     * @param ContactPointUpdated $contactPointUpdated
240
     */
241 View Code Duplication
    private function applyContactPointUpdated(ContactPointUpdated $contactPointUpdated)
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...
242
    {
243
        $organizerId = $contactPointUpdated->getOrganizerId();
244
        $contactPoint = $contactPointUpdated->getContactPoint();
245
246
        $document = $this->repository->get($organizerId);
247
248
        $jsonLD = $document->getBody();
249
        $jsonLD->contactPoint = $contactPoint->toJsonLd();
250
251
        $this->repository->save($document->withBody($jsonLD));
252
    }
253
254
    /**
255
     * @param OrganizerUpdatedFromUDB2 $organizerUpdatedFromUDB2
256
     */
257 View Code Duplication
    private function applyOrganizerUpdatedFromUDB2(
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...
258
        OrganizerUpdatedFromUDB2 $organizerUpdatedFromUDB2
259
    ) {
260
        // It's possible that an organizer has been deleted in udb3, but never
261
        // in udb2. If an update comes for that organizer from udb2, it should
262
        // be imported again. This is intended by design.
263
        // @see https://jira.uitdatabank.be/browse/III-1092
264
        try {
265
            $document = $this->loadDocumentFromRepository(
266
                $organizerUpdatedFromUDB2
267
            );
268
        } catch (DocumentGoneException $e) {
269
            $document = $this->newDocument($organizerUpdatedFromUDB2->getActorId());
270
        }
271
272
        $udb2Actor = ActorItemFactory::createActorFromCdbXml(
273
            $organizerUpdatedFromUDB2->getCdbXmlNamespaceUri(),
274
            $organizerUpdatedFromUDB2->getCdbXml()
275
        );
276
277
        $actorLd = $this->cdbXMLImporter->documentWithCdbXML(
278
            $document->getBody(),
279
            $udb2Actor
280
        );
281
282
        $this->setMainLanguage($actorLd, new Language('nl'));
283
284
        $this->repository->save($document->withBody($actorLd));
285
    }
286
287
    /**
288
     * @param LabelAdded $labelAdded
289
     */
290 View Code Duplication
    private function applyLabelAdded(LabelAdded $labelAdded)
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...
291
    {
292
        $document = $this->repository->get($labelAdded->getOrganizerId());
293
294
        $jsonLD = $document->getBody();
295
296
        // Check the visibility of the label to update the right property.
297
        $labelsProperty = $labelAdded->getLabel()->isVisible() ? 'labels' : 'hiddenLabels';
298
299
        $labels = isset($jsonLD->{$labelsProperty}) ? $jsonLD->{$labelsProperty} : [];
300
        $label = (string) $labelAdded->getLabel();
301
302
        $labels[] = $label;
303
        $jsonLD->{$labelsProperty} = array_unique($labels);
304
305
        $this->repository->save($document->withBody($jsonLD));
306
    }
307
308
    /**
309
     * @param LabelRemoved $labelRemoved
310
     */
311 View Code Duplication
    private function applyLabelRemoved(LabelRemoved $labelRemoved)
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...
312
    {
313
        $document = $this->repository->get($labelRemoved->getOrganizerId());
314
        $jsonLD = $document->getBody();
315
316
        // Don't presume that the label visibility is correct when removing.
317
        // So iterate over both the visible and invisible labels.
318
        $labelsProperties = ['labels', 'hiddenLabels'];
319
320
        foreach ($labelsProperties as $labelsProperty) {
321
            if (isset($jsonLD->{$labelsProperty}) && is_array($jsonLD->{$labelsProperty})) {
322
                $jsonLD->{$labelsProperty} = array_filter(
323
                    $jsonLD->{$labelsProperty},
324
                    function ($label) use ($labelRemoved) {
325
                        return !$labelRemoved->getLabel()->equals(
326
                            new Label($label)
327
                        );
328
                    }
329
                );
330
331
                // Ensure array keys start with 0 so json_encode() does encode it
332
                // as an array and not as an object.
333
                if (count($jsonLD->{$labelsProperty}) > 0) {
334
                    $jsonLD->{$labelsProperty} = array_values($jsonLD->{$labelsProperty});
335
                } else {
336
                    unset($jsonLD->{$labelsProperty});
337
                }
338
            }
339
        }
340
341
        $this->repository->save($document->withBody($jsonLD));
342
    }
343
344
    /**
345
     * @param OrganizerDeleted $organizerDeleted
346
     */
347
    private function applyOrganizerDeleted(
348
        OrganizerDeleted $organizerDeleted
349
    ) {
350
        $this->repository->remove($organizerDeleted->getOrganizerId());
351
    }
352
353
    /**
354
     * @param string $id
355
     * @return JsonDocument
356
     */
357 View Code Duplication
    private function newDocument($id)
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...
358
    {
359
        $document = new JsonDocument($id);
360
361
        $organizerLd = $document->getBody();
362
        $organizerLd->{'@id'} = $this->iriGenerator->iri($id);
363
        $organizerLd->{'@context'} = '/contexts/organizer';
364
365
        return $document->withBody($organizerLd);
366
    }
367
368
    /**
369
     * @param ActorEvent $actor
370
     * @return JsonDocument
371
     */
372
    private function loadDocumentFromRepository(ActorEvent $actor)
373
    {
374
        $document = $this->repository->get($actor->getActorId());
375
376
        if (!$document) {
377
            return $this->newDocument($actor->getActorId());
378
        }
379
380
        return $document;
381
    }
382
}
383