Completed
Pull Request — master (#306)
by Luc
04:43
created

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