Completed
Pull Request — master (#308)
by
unknown
07:54
created

OrganizerLDProjector::iri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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