Completed
Pull Request — master (#240)
by Kristof
10:41 queued 04:55
created

longDescriptionStartsWithShortDescription()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
3
namespace CultuurNet\UDB3\Event\ReadModel\JSONLD;
4
5
use CultureFeed_Cdb_Data_File;
6
use CultuurNet\UDB3\Cdb\CdbId\EventCdbIdExtractorInterface;
7
use CultuurNet\UDB3\Cdb\DateTimeFactory;
8
use CultuurNet\UDB3\Cdb\PriceDescriptionParser;
9
use CultuurNet\UDB3\LabelImporter;
10
use CultuurNet\UDB3\Offer\ReadModel\JSONLD\CdbXMLItemBaseImporter;
11
use CultuurNet\UDB3\SluggerInterface;
12
use CultuurNet\UDB3\StringFilter\BreakTagToNewlineStringFilter;
13
use CultuurNet\UDB3\StringFilter\CombinedStringFilter;
14
use CultuurNet\UDB3\StringFilter\StringFilterInterface;
15
use CultuurNet\UDB3\StringFilter\StripLeadingSpaceStringFilter;
16
use CultuurNet\UDB3\StringFilter\StripNewlineStringFilter;
17
use CultuurNet\UDB3\StringFilter\StripSourceStringFilter;
18
use CultuurNet\UDB3\StringFilter\StripTrailingSpaceStringFilter;
19
20
/**
21
 * Takes care of importing cultural events in the CdbXML format (UDB2)
22
 * into a UDB3 JSON-LD document.
23
 */
24
class CdbXMLImporter
25
{
26
    /**
27
     * @var CdbXMLItemBaseImporter
28
     */
29
    private $cdbXMLItemBaseImporter;
30
31
    /**
32
     * @var EventCdbIdExtractorInterface
33
     */
34
    private $cdbIdExtractor;
35
36
    /**
37
     * @var PriceDescriptionParser
38
     */
39
    private $priceDescriptionParser;
40
41
    /**
42
     * @var StringFilterInterface
43
     */
44
    private $longDescriptionFilter;
45
46
    /**
47
     * @param CdbXMLItemBaseImporter $dbXMLItemBaseImporter
48
     * @param EventCdbIdExtractorInterface $cdbIdExtractor
49
     * @param PriceDescriptionParser $priceDescriptionParser
50
     */
51
    public function __construct(
52
        CdbXMLItemBaseImporter $dbXMLItemBaseImporter,
53
        EventCdbIdExtractorInterface $cdbIdExtractor,
54
        PriceDescriptionParser $priceDescriptionParser
55
    ) {
56
        $this->cdbXMLItemBaseImporter = $dbXMLItemBaseImporter;
57
        $this->cdbIdExtractor = $cdbIdExtractor;
58
        $this->priceDescriptionParser = $priceDescriptionParser;
59
60
        $this->longDescriptionFilter = new CombinedStringFilter();
61
        $this->longDescriptionFilter->addFilter(
62
            new StripSourceStringFilter()
63
        );
64
        $this->longDescriptionFilter->addFilter(
65
            new StripNewlineStringFilter()
66
        );
67
        $this->longDescriptionFilter->addFilter(
68
            new BreakTagToNewlineStringFilter()
69
        );
70
        $this->longDescriptionFilter->addFilter(
71
            new StripLeadingSpaceStringFilter()
72
        );
73
        $this->longDescriptionFilter->addFilter(
74
            new StripTrailingSpaceStringFilter()
75
        );
76
    }
77
78
    /**
79
     * Imports a UDB2 event into a UDB3 JSON-LD document.
80
     *
81
     * @param \stdClass $base
82
     *   The JSON-LD document to start from.
83
     * @param \CultureFeed_Cdb_Item_Event $event
84
     *   The cultural event data from UDB2 to import.
85
     * @param PlaceServiceInterface $placeManager
86
     *   The manager from which to retrieve the JSON-LD of a place.
87
     * @param OrganizerServiceInterface $organizerManager
88
     *   The manager from which to retrieve the JSON-LD of an organizer.
89
     * @param SluggerInterface $slugger
90
     *   The slugger that's used to generate a sameAs reference.
91
     *
92
     * @return \stdClass
93
     *   The document with the UDB2 event data merged in.
94
     */
95
    public function documentWithCdbXML(
96
        $base,
97
        \CultureFeed_Cdb_Item_Event $event,
98
        PlaceServiceInterface $placeManager,
99
        OrganizerServiceInterface $organizerManager,
100
        SluggerInterface $slugger
101
    ) {
102
        $jsonLD = clone $base;
103
104
        /** @var \CultureFeed_Cdb_Data_EventDetail $detail */
105
        $detail = null;
106
107
        /** @var \CultureFeed_Cdb_Data_EventDetail[] $details */
108
        $details = $event->getDetails();
109
110
        foreach ($details as $languageDetail) {
111
            $language = $languageDetail->getLanguage();
112
113
            // The first language detail found will be used to retrieve
114
            // properties from which in UDB3 are not any longer considered
115
            // to be language specific.
116
            if (!$detail) {
117
                $detail = $languageDetail;
118
            }
119
120
            $jsonLD->name[$language] = $languageDetail->getTitle();
121
122
            $this->importDescription($languageDetail, $jsonLD, $language);
123
        }
124
125
        $this->cdbXMLItemBaseImporter->importAvailable($event, $jsonLD);
126
127
        $this->importPicture($detail, $jsonLD);
128
129
        $labelImporter = new LabelImporter();
130
        $labelImporter->importLabels($event, $jsonLD);
131
132
        $jsonLD->calendarSummary = $detail->getCalendarSummary();
133
134
        $this->importLocation($event, $placeManager, $jsonLD);
135
136
        $this->importOrganizer($event, $organizerManager, $jsonLD);
137
138
        $this->importBookingInfo($event, $detail, $jsonLD);
139
140
        $this->importPriceInfo($detail, $jsonLD);
141
142
        $this->importTerms($event, $jsonLD);
143
144
        $this->cdbXMLItemBaseImporter->importPublicationInfo($event, $jsonLD);
145
146
        $this->importCalendar($event, $jsonLD);
147
148
        $this->importTypicalAgeRange($event, $jsonLD);
149
150
        $this->importPerformers($detail, $jsonLD);
151
152
        $this->importLanguages($event, $jsonLD);
153
154
        $this->importUitInVlaanderenReference($event, $slugger, $jsonLD);
155
156
        $this->cdbXMLItemBaseImporter->importExternalId($event, $jsonLD);
157
158
        $this->importSeeAlso($event, $jsonLD);
159
160
        $this->importContactPoint($event, $jsonLD);
161
162
        $this->cdbXMLItemBaseImporter->importWorkflowStatus($event, $jsonLD);
163
164
        return $jsonLD;
165
    }
166
167
    /**
168
     * @param int $unixTime
169
     * @return \DateTime
170
     */
171
    private function dateFromUdb2UnixTime($unixTime)
172
    {
173
        $dateTime = new \DateTime(
174
            '@' . $unixTime,
175
            new \DateTimeZone('Europe/Brussels')
176
        );
177
178
        return $dateTime;
179
    }
180
181
    /**
182
     * @param \CultureFeed_Cdb_Data_EventDetail $languageDetail
183
     * @param \stdClass $jsonLD
184
     * @param string $language
185
     */
186
    private function importDescription($languageDetail, $jsonLD, $language)
187
    {
188
        $longDescription = trim($languageDetail->getLongDescription());
189
        $shortDescription = $languageDetail->getShortDescription();
190
191
        $descriptions = [];
192
193
        if ($shortDescription) {
194
            $shortDescription = trim($shortDescription);
195
196
            if (!$this->longDescriptionStartsWithShortDescription($longDescription, $shortDescription)) {
197
                $descriptions[] = $shortDescription;
198
            }
199
        }
200
201
        $longDescription = $this->longDescriptionFilter->filter($longDescription);
202
203
        $descriptions[] = trim($longDescription);
204
205
        $descriptions = array_filter($descriptions);
206
        $description = implode("\n\n", $descriptions);
207
208
        $jsonLD->description[$language] = $description;
209
    }
210
211
    /**
212
     * @param \CultureFeed_Cdb_Data_EventDetail $detail
213
     * @param \stdClass $jsonLD
214
     *
215
     * This is based on code found in the culturefeed theme.
216
     * @see https://github.com/cultuurnet/culturefeed/blob/master/culturefeed_agenda/theme/theme.inc#L266-L284
217
     */
218 View Code Duplication
    private function importPicture($detail, $jsonLD)
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...
219
    {
220
        $mainPicture = null;
221
222
        // first check if there is a media file that is main and has the PHOTO media type
223
        $photos = $detail->getMedia()->byMediaType(CultureFeed_Cdb_Data_File::MEDIA_TYPE_PHOTO);
224
        foreach ($photos as $photo) {
225
            if ($photo->isMain()) {
226
                $mainPicture = $photo;
227
            }
228
        }
229
230
        // the IMAGEWEB media type is deprecated but can still be used as a main image if there is no PHOTO
231
        if (empty($mainPicture)) {
232
            $images = $detail->getMedia()->byMediaType(CultureFeed_Cdb_Data_File::MEDIA_TYPE_IMAGEWEB);
233
            foreach ($images as $image) {
234
                if ($image->isMain()) {
235
                    $mainPicture = $image;
236
                }
237
            }
238
        }
239
240
        // if there is no explicit main image we just use the oldest picture of any type
241
        if (empty($mainPicture)) {
242
            $pictures = $detail->getMedia()->byMediaTypes(
243
                [
244
                    CultureFeed_Cdb_Data_File::MEDIA_TYPE_PHOTO,
245
                    CultureFeed_Cdb_Data_File::MEDIA_TYPE_IMAGEWEB
246
                ]
247
            );
248
249
            $pictures->rewind();
250
            $mainPicture = count($pictures) > 0 ? $pictures->current() : null;
251
        }
252
253
        if ($mainPicture) {
254
            $jsonLD->image = $mainPicture->getHLink();
255
        }
256
    }
257
258
    /**
259
     * @param \CultureFeed_Cdb_Item_Event $event
260
     * @param PlaceServiceInterface $placeManager
261
     * @param \stdClass $jsonLD
262
     */
263
    private function importLocation(\CultureFeed_Cdb_Item_Event $event, PlaceServiceInterface $placeManager, $jsonLD)
264
    {
265
        $location = array();
266
        $location['@type'] = 'Place';
267
268
        $location_id = $this->cdbIdExtractor->getRelatedPlaceCdbId($event);
269
270
        if ($location_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $location_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
271
            $location += (array)$placeManager->placeJSONLD($location_id);
272
        } else {
273
            $location_cdb = $event->getLocation();
274
            $location['name']['nl'] = $location_cdb->getLabel();
275
            $address = $location_cdb->getAddress()->getPhysicalAddress();
276
            if ($address) {
277
                $location['address'] = array(
278
                    'addressCountry' => $address->getCountry(),
279
                    'addressLocality' => $address->getCity(),
280
                    'postalCode' => $address->getZip(),
281
                    'streetAddress' =>
282
                        $address->getStreet() . ' ' . $address->getHouseNumber(
283
                        ),
284
                );
285
            }
286
        }
287
        $jsonLD->location = $location;
288
    }
289
290
    /**
291
     * @param \CultureFeed_Cdb_Item_Event $event
292
     * @param OrganizerServiceInterface $organizerManager
293
     * @param \stdClass $jsonLD
294
     */
295
    private function importOrganizer(
296
        \CultureFeed_Cdb_Item_Event $event,
297
        OrganizerServiceInterface $organizerManager,
298
        $jsonLD
299
    ) {
300
        $organizer = null;
301
        $organizer_id = $this->cdbIdExtractor->getRelatedOrganizerCdbId($event);
302
        $organizer_cdb = $event->getOrganiser();
303
        $contact_info_cdb = $event->getContactInfo();
304
305
        if ($organizer_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $organizer_id of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
306
            $organizer = (array)$organizerManager->organizerJSONLD($organizer_id);
307
        } elseif ($organizer_cdb && $contact_info_cdb) {
308
            $organizer = array();
309
            $organizer['name'] = $organizer_cdb->getLabel();
310
311
            $emails_cdb = $contact_info_cdb->getMails();
312
            if (count($emails_cdb) > 0) {
313
                $organizer['email'] = array();
314
                foreach ($emails_cdb as $email) {
315
                    $organizer['email'][] = $email->getMailAddress();
316
                }
317
            }
318
319
            $phones_cdb = $contact_info_cdb->getPhones();
320
            if (count($phones_cdb) > 0) {
321
                $organizer['phone'] = array();
322
                foreach ($phones_cdb as $phone) {
323
                    $organizer['phone'][] = $phone->getNumber();
324
                }
325
            }
326
        }
327
328
        if (!is_null($organizer)) {
329
            $organizer['@type'] = 'Organizer';
330
            $jsonLD->organizer = $organizer;
331
        }
332
    }
333
334
    /**
335
     * @param \CultureFeed_Cdb_Data_EventDetail $detail
336
     * @param \stdClass $jsonLD
337
     */
338
    private function importPriceInfo(
339
        \CultureFeed_Cdb_Data_EventDetail $detail,
340
        $jsonLD
341
    ) {
342
        $prices = array();
343
344
        $price = $detail->getPrice();
345
346
        if ($price) {
347
            $description = $price->getDescription();
348
349
            if ($description) {
350
                $prices = $this->priceDescriptionParser->parse($description);
351
            }
352
353
            // If price description was not interpretable, fall back to
354
            // price title and value.
355
            if (empty($prices) && $price->getValue() !== null) {
356
                $prices['Basistarief'] = floatval($price->getValue());
357
            }
358
        }
359
360
        if (!empty($prices)) {
361
            $priceInfo = array();
362
363
            /** @var \CultureFeed_Cdb_Data_Price $price */
364
            foreach ($prices as $title => $value) {
365
                $priceInfoItem = array(
366
                    'name' => $title,
367
                    'priceCurrency' => 'EUR',
368
                    'price' => $value,
369
                );
370
371
                $priceInfoItem['category'] = 'tariff';
372
373
                if ($priceInfoItem['name'] === 'Basistarief') {
374
                    $priceInfoItem['category'] = 'base';
375
                }
376
377
                $priceInfo[] = $priceInfoItem;
378
            }
379
380
            if (!empty($priceInfo)) {
381
                $jsonLD->priceInfo = $priceInfo;
382
            }
383
        }
384
    }
385
386
    /**
387
     * @param \CultureFeed_Cdb_Data_EventDetail $detail
388
     * @param \stdClass $jsonLD
389
     */
390
    private function importBookingInfo(
391
        \CultureFeed_Cdb_Item_Event $event,
392
        \CultureFeed_Cdb_Data_EventDetail $detail,
393
        $jsonLD
394
    ) {
395
        $bookingInfo = array();
396
397
        $price = $detail->getPrice();
398
        if ($price) {
399
            if ($price->getDescription()) {
400
                $bookingInfo['description'] = $price->getDescription();
401
            }
402
            if ($price->getTitle()) {
403
                $bookingInfo['name'] = $price->getTitle();
404
            }
405
            if ($price->getValue() !== null) {
406
                $bookingInfo['priceCurrency'] = 'EUR';
407
                $bookingInfo['price'] = floatval($price->getValue());
408
            }
409
            if ($bookingPeriod = $event->getBookingPeriod()) {
410
                $startDate = $this->dateFromUdb2UnixTime($bookingPeriod->getDateFrom());
411
                $endDate = $this->dateFromUdb2UnixTime($bookingPeriod->getDateTill());
412
413
                $bookingInfo['availabilityStarts'] = $startDate->format('c');
414
                $bookingInfo['availabilityEnds'] = $endDate->format('c');
415
            }
416
        }
417
418
        // Add reservation contact data.
419
        $contactInfo = $event->getContactInfo();
420
        if ($contactInfo) {
421
            foreach ($contactInfo->getUrls() as $url) {
422
                if ($url->isForReservations()) {
423
                    $bookingInfo['url'] = $url->getUrl();
424
                    break;
425
                }
426
            }
427
428
            if (array_key_exists('url', $bookingInfo)) {
429
                $bookingInfo['urlLabel'] = 'Reserveer plaatsen';
430
            }
431
432
            foreach ($contactInfo->getPhones() as $phone) {
433
                if ($phone->isForReservations()) {
434
                    $bookingInfo['phone'] = $phone->getNumber();
435
                    break;
436
                }
437
            }
438
439
            foreach ($contactInfo->getMails() as $mail) {
440
                if ($mail->isForReservations()) {
441
                    $bookingInfo['email'] = $mail->getMailAddress();
442
                    break;
443
                }
444
            }
445
        }
446
447
        if (!empty($bookingInfo)) {
448
            $jsonLD->bookingInfo = $bookingInfo;
449
        }
450
    }
451
452
    /**
453
     * @param \CultureFeed_Cdb_Item_Event $event
454
     * @param \stdClass $jsonLD
455
     */
456
    private function importContactPoint(
457
        \CultureFeed_Cdb_Item_Event $event,
458
        \stdClass $jsonLD
459
    ) {
460
        $contactInfo = $event->getContactInfo();
461
462
        $notForReservations = function ($item) {
463
            /** @var \CultureFeed_Cdb_Data_Url|\CultureFeed_Cdb_Data_Phone|\CultureFeed_Cdb_Data_Mail $item */
464
            return !$item->isForReservations();
465
        };
466
467
        if ($contactInfo) {
468
            $contactPoint = array();
469
470
            $emails = array_filter($contactInfo->getMails(), $notForReservations);
471
472 View Code Duplication
            if (!empty($emails)) {
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...
473
                $contactPoint['email'] = array_map(
474
                    function (\CultureFeed_Cdb_Data_Mail $email) {
475
                        return $email->getMailAddress();
476
                    },
477
                    $emails
478
                );
479
                $contactPoint['email'] = array_values($contactPoint['email']);
480
            }
481
482
            $phones = array_filter($contactInfo->getPhones(), $notForReservations);
483
484 View Code Duplication
            if (!empty($phones)) {
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...
485
                $contactPoint['phone'] = array_map(
486
                    function (\CultureFeed_Cdb_Data_phone $phone) {
487
                        return $phone->getNumber();
488
                    },
489
                    $phones
490
                );
491
                $contactPoint['phone'] = array_values($contactPoint['phone']);
492
            }
493
494
            $urls = array_filter($contactInfo->getUrls(), $notForReservations);
495
496 View Code Duplication
            if (!empty($urls)) {
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...
497
                $contactPoint['url'] = array_map(
498
                    function (\CultureFeed_Cdb_Data_Url $url) {
499
                        return $url->getUrl();
500
                    },
501
                    $urls
502
                );
503
                $contactPoint['url'] = array_values($contactPoint['url']);
504
            }
505
506
            array_filter($contactPoint);
507
            if (!empty($contactPoint)) {
508
                $jsonLD->contactPoint = $contactPoint;
509
            }
510
        }
511
    }
512
513
    /**
514
     * @param \CultureFeed_Cdb_Item_Event $event
515
     * @param \stdClass $jsonLD
516
     */
517
    private function importTerms(\CultureFeed_Cdb_Item_Event $event, $jsonLD)
518
    {
519
        $themeBlacklist = [
520
            'Thema onbepaald',
521
            'Meerder kunstvormen',
522
            'Meerdere filmgenres'
523
        ];
524
        $categories = array();
525 View Code Duplication
        foreach ($event->getCategories() as $category) {
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...
526
            /* @var \Culturefeed_Cdb_Data_Category $category */
527
            if ($category && !in_array($category->getName(), $themeBlacklist)) {
528
                $categories[] = array(
529
                    'label' => $category->getName(),
530
                    'domain' => $category->getType(),
531
                    'id' => $category->getId(),
532
                );
533
            }
534
        }
535
        $jsonLD->terms = $categories;
536
    }
537
538
    /**
539
     * @param \CultureFeed_Cdb_Item_Event $event
540
     * @param \stdClass $jsonLD
541
     */
542
    private function importCalendar(\CultureFeed_Cdb_Item_Event $event, $jsonLD)
543
    {
544
        // To render the front-end we make a distinction between 4 calendar types
545
        // Permanent and Periodic map directly to the Cdb calendar classes
546
        // Simple timestamps are divided into single and multiple
547
        $calendarType = 'unknown';
548
        $calendar = $event->getCalendar();
549
550
        if ($calendar instanceof \CultureFeed_Cdb_Data_Calendar_Permanent) {
551
            $calendarType = 'permanent';
552
        } elseif ($calendar instanceof \CultureFeed_Cdb_Data_Calendar_PeriodList) {
553
            $calendarType = 'periodic';
554
            $calendar->rewind();
555
            $firstCalendarItem = $calendar->current();
556
            $startDateString = $firstCalendarItem->getDateFrom() . 'T00:00:00';
557
            $startDate = DateTimeFactory::dateTimeFromDateString($startDateString);
558
559 View Code Duplication
            if (iterator_count($calendar) > 1) {
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...
560
                $periodArray = iterator_to_array($calendar);
561
                $lastCalendarItem = end($periodArray);
562
            } else {
563
                $lastCalendarItem = $firstCalendarItem;
564
            }
565
566
            $endDateString = $lastCalendarItem->getDateTo() . 'T00:00:00';
567
            $endDate = DateTimeFactory::dateTimeFromDateString($endDateString);
568
569
            $jsonLD->startDate = $startDate->format('c');
570
            $jsonLD->endDate = $endDate->format('c');
571
        } elseif ($calendar instanceof \CultureFeed_Cdb_Data_Calendar_TimestampList) {
572
            $calendarType = 'single';
573
            $calendar->rewind();
574
            /** @var \CultureFeed_Cdb_Data_Calendar_Timestamp $firstCalendarItem */
575
            $firstCalendarItem = $calendar->current();
576
            if ($firstCalendarItem->getStartTime()) {
577
                $dateString =
578
                    $firstCalendarItem->getDate() . 'T' . $firstCalendarItem->getStartTime();
579
            } else {
580
                $dateString = $firstCalendarItem->getDate() . 'T00:00:00';
581
            }
582
583
            $startDate = DateTimeFactory::dateTimeFromDateString($dateString);
584
585 View Code Duplication
            if (iterator_count($calendar) > 1) {
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...
586
                $periodArray = iterator_to_array($calendar);
587
                $lastCalendarItem = end($periodArray);
588
            } else {
589
                $lastCalendarItem = $firstCalendarItem;
590
            }
591
592
            $endDateString = null;
593
            if ($lastCalendarItem->getEndTime()) {
594
                $endDateString =
595
                    $lastCalendarItem->getDate() . 'T' . $lastCalendarItem->getEndTime();
596
            } else {
597
                if (iterator_count($calendar) > 1) {
598
                    $endDateString = $lastCalendarItem->getDate() . 'T00:00:00';
599
                }
600
            }
601
602
            if ($endDateString) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $endDateString of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
603
                $endDate = DateTimeFactory::dateTimeFromDateString($endDateString);
604
                $jsonLD->endDate = $endDate->format('c');
605
606
                if ($startDate->format('Ymd') != $endDate->format('Ymd')) {
607
                    $calendarType = 'multiple';
608
                }
609
            }
610
611
            $jsonLD->startDate = $startDate->format('c');
612
        }
613
614
        $jsonLD->calendarType = $calendarType;
615
    }
616
617
    /**
618
     * @param \CultureFeed_Cdb_Item_Event $event
619
     * @param \stdClass $jsonLD
620
     */
621
    private function importTypicalAgeRange(\CultureFeed_Cdb_Item_Event $event, $jsonLD)
622
    {
623
        $ageFrom = $event->getAgeFrom();
624
        if ($ageFrom) {
625
            $jsonLD->typicalAgeRange = "{$ageFrom}-";
626
        }
627
    }
628
629
    /**
630
     * @param \CultureFeed_Cdb_Data_EventDetail $detail
631
     * @param \stdClass $jsonLD
632
     */
633
    private function importPerformers(\CultureFeed_Cdb_Data_EventDetail $detail, $jsonLD)
634
    {
635
        /** @var \CultureFeed_Cdb_Data_Performer $performer */
636
        $performers = $detail->getPerformers();
637
        if ($performers) {
638
            foreach ($performers as $performer) {
639
                if ($performer->getLabel()) {
640
                    $performerData = new \stdClass();
641
                    $performerData->name = $performer->getLabel();
642
                    $jsonLD->performer[] = $performerData;
643
                }
644
            }
645
        }
646
    }
647
648
    /**
649
     * @param \CultureFeed_Cdb_Item_Event $event
650
     * @param \stdClass $jsonLD
651
     */
652
    private function importLanguages(\CultureFeed_Cdb_Item_Event $event, $jsonLD)
653
    {
654
        /** @var \CultureFeed_Cdb_Data_Language $udb2Language */
655
        $languages = $event->getLanguages();
656
        if ($languages) {
657
            $jsonLD->language = [];
658
            foreach ($languages as $udb2Language) {
659
                $jsonLD->language[] = $udb2Language->getLanguage();
660
            }
661
            $jsonLD->language = array_unique($jsonLD->language);
662
        }
663
    }
664
665
    /**
666
     * @param \CultureFeed_Cdb_Item_Event $event
667
     * @param \stdClass $jsonLD
668
     */
669
    private function importSeeAlso(
670
        \CultureFeed_Cdb_Item_Event $event,
671
        \stdClass $jsonLD
672
    ) {
673
        if (!property_exists($jsonLD, 'seeAlso')) {
674
            $jsonLD->seeAlso = [];
675
        }
676
677
        // Add contact info url, if it's not for reservations.
678
        if ($contactInfo = $event->getContactInfo()) {
679
            /** @var \CultureFeed_Cdb_Data_Url[] $contactUrls */
680
            $contactUrls = $contactInfo->getUrls();
681
            if (is_array($contactUrls) && count($contactUrls) > 0) {
682
                foreach ($contactUrls as $contactUrl) {
683
                    if (!$contactUrl->isForReservations()) {
684
                        $jsonLD->seeAlso[] = $contactUrl->getUrl();
685
                    }
686
                }
687
            }
688
        }
689
    }
690
691
    /**
692
     * @param \CultureFeed_Cdb_Item_Event $event
693
     * @param SluggerInterface $slugger
694
     * @param \stdClass $jsonLD
695
     */
696
    private function importUitInVlaanderenReference(
697
        \CultureFeed_Cdb_Item_Event $event,
698
        SluggerInterface $slugger,
699
        $jsonLD
700
    ) {
701
702
        // Some events seem to not have a Dutch name, even though this is
703
        // required. If there's no Dutch name, we just leave the slug empty as
704
        // that seems to be the behaviour on http://m.uitinvlaanderen.be
705
        if (isset($jsonLD->name['nl'])) {
706
            $name = $jsonLD->name['nl'];
707
            $slug = $slugger->slug($name);
708
        } else {
709
            $slug = '';
710
        }
711
712
        $reference = 'http://www.uitinvlaanderen.be/agenda/e/' . $slug . '/' . $event->getCdbId();
713
714
715
        if (!property_exists($jsonLD, 'sameAs')) {
716
            $jsonLD->sameAs = [];
717
        }
718
719
        if (!in_array($reference, $jsonLD->sameAs)) {
720
            array_push($jsonLD->sameAs, $reference);
721
        }
722
    }
723
724
    /**
725
     * @param string $longDescription
726
     * @param string $shortDescription
727
     * @return bool
728
     */
729
    private function longDescriptionStartsWithShortDescription(
730
        $longDescription,
731
        $shortDescription
732
    ) {
733
        $longDescription = strip_tags(html_entity_decode($longDescription));
734
735
        return 0 === strncmp($longDescription, $shortDescription, mb_strlen($shortDescription));
736
    }
737
}
738