Completed
Pull Request — master (#251)
by Kristof
05:50
created

HTMLEventFormatter::formatEvent()   C

Complexity

Conditions 9
Paths 160

Size

Total Lines 60
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 60
rs 6.3008
c 0
b 0
f 0
cc 9
eloc 32
nc 160
nop 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @file
4
 */
5
6
namespace CultuurNet\UDB3\EventExport\Format\HTML;
7
8
use CultuurNet\CalendarSummary\CalendarHTMLFormatter;
9
use CultuurNet\UDB3\Event\EventType;
10
use CultuurNet\UDB3\Event\ReadModel\Calendar\CalendarRepositoryInterface;
11
use CultuurNet\UDB3\Event\ReadModel\JSONLD\Specifications\EventSpecificationInterface;
12
use CultuurNet\UDB3\Event\ReadModel\JSONLD\Specifications\Has1Taalicoon;
13
use CultuurNet\UDB3\Event\ReadModel\JSONLD\Specifications\Has2Taaliconen;
14
use CultuurNet\UDB3\Event\ReadModel\JSONLD\Specifications\Has3Taaliconen;
15
use CultuurNet\UDB3\Event\ReadModel\JSONLD\Specifications\Has4Taaliconen;
16
use CultuurNet\UDB3\Event\ReadModel\JSONLD\Specifications\HasUiTPASBrand;
17
use CultuurNet\UDB3\Event\ReadModel\JSONLD\Specifications\HasVliegBrand;
18
use CultuurNet\UDB3\EventExport\Format\HTML\Properties\TaalicoonDescription;
19
use CultuurNet\UDB3\EventExport\Format\HTML\Uitpas\EventInfo\EventInfoServiceInterface;
20
use CultuurNet\UDB3\EventExport\PriceFormatter;
21
use CultuurNet\UDB3\EventExport\UitpasInfoFormatter;
22
use CultuurNet\UDB3\StringFilter\CombinedStringFilter;
23
use CultuurNet\UDB3\StringFilter\StripHtmlStringFilter;
24
use CultuurNet\UDB3\StringFilter\TruncateStringFilter;
25
use stdClass;
26
27
class HTMLEventFormatter
28
{
29
    /**
30
     * @var CombinedStringFilter
31
     */
32
    protected $filters;
33
34
    /**
35
     * @var EventSpecificationInterface[]
36
     */
37
    protected $taalicoonSpecs;
38
39
    /**
40
     * @var EventSpecificationInterface[]
41
     */
42
    protected $brandSpecs;
43
44
    /**
45
     * @var EventInfoServiceInterface|null
46
     */
47
    protected $uitpas;
48
49
    /**
50
     * @var PriceFormatter
51
     */
52
    protected $priceFormatter;
53
54
    /**
55
     * @var UitpasInfoFormatter
56
     */
57
    protected $uitpasInfoFormatter;
58
59
    /**
60
     * @var CalendarRepositoryInterface
61
     */
62
    protected $calendarRepository;
63
64
    /**
65
     * @param EventInfoServiceInterface|null $uitpas
66
     * @param CalendarRepositoryInterface $calendarRepository
67
     */
68
    public function __construct(
69
        EventInfoServiceInterface $uitpas = null,
70
        CalendarRepositoryInterface $calendarRepository = null
71
    ) {
72
        $this->uitpas = $uitpas;
73
        $this->calendarRepository = $calendarRepository;
74
75
        $this->priceFormatter = new PriceFormatter(2, ',', '.', 'Gratis');
76
77
        $this->uitpasInfoFormatter = new UitpasInfoFormatter($this->priceFormatter);
78
79
        $this->filters = new CombinedStringFilter();
80
81
        $this->filters->addFilter(new StripHtmlStringFilter());
82
83
        $truncateFilter = new TruncateStringFilter(300);
84
        $truncateFilter->addEllipsis();
85
        $truncateFilter->turnOnWordSafe(1);
86
        $truncateFilter->beSentenceFriendly();
87
        $this->filters->addFilter($truncateFilter);
88
89
        $this->taalicoonSpecs = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('EEN_TAALICOON' =>...tions\Has4Taaliconen()) of type array<string,object<Cult...ons\\Has4Taaliconen>"}> is incompatible with the declared type array<integer,object<Cul...pecificationInterface>> of property $taalicoonSpecs.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
90
            'EEN_TAALICOON' => new Has1Taalicoon(),
91
            'TWEE_TAALICONEN' => new Has2Taaliconen(),
92
            'DRIE_TAALICONEN' => new Has3Taaliconen(),
93
            'VIER_TAALICONEN' => new Has4Taaliconen()
94
        );
95
96
        $this->brandSpecs = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('uitpas' => new \C...ations\HasVliegBrand()) of type array<string,object<Cult...ions\\HasVliegBrand>"}> is incompatible with the declared type array<integer,object<Cul...pecificationInterface>> of property $brandSpecs.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
97
            'uitpas' => new HasUiTPASBrand(),
98
            'vlieg' => new HasVliegBrand()
99
        );
100
    }
101
102
    /**
103
     * @param string $eventId
104
     *   The event's CDB ID.
105
     * @param string $eventString
106
     *   The cultural event encoded as JSON-LD
107
     *
108
     * @return array
109
     *   The event as an array suitable for rendering with HTMLFileWriter
110
     */
111
    public function formatEvent($eventId, $eventString)
112
    {
113
        $event = json_decode($eventString);
114
115
        $formattedEvent = [];
116
117
        if (isset($event->image)) {
118
            $formattedEvent['image'] = 'http:' . $event->image;
119
        }
120
121
        $type = EventType::fromJSONLDEvent($eventString);
122
        if ($type) {
123
            $formattedEvent['type'] = $type->getLabel();
124
        }
125
126
        $formattedEvent['title'] = reset($event->name);
127
128
        if (property_exists($event, 'description')) {
129
            $formattedEvent['description'] = $this->filters->filter(
130
                reset($event->description)
131
            );
132
        }
133
134
        $address = [];
135
136
        if (property_exists($event, 'location')) {
137
            if (property_exists($event->location, 'name')) {
138
                $address['name'] = reset($event->location->name);
139
            }
140
141
            if (property_exists($event->location, 'address')) {
142
                $address += [
143
                    'street' => $event->location->address->streetAddress,
144
                    'postcode' => $event->location->address->postalCode,
145
                    'municipality' => $event->location->address->addressLocality,
146
                ];
147
            }
148
        }
149
150
        if (!empty($address)) {
151
            $formattedEvent['address'] = $address;
152
        }
153
154
        $this->addPriceInfo($event, $formattedEvent);
155
156
        $this->addCalendarInfo($eventId, $event, $formattedEvent);
157
158
        $this->addUitpasInfo($eventId, $formattedEvent);
159
160
        $this->formatTaaliconen($event, $formattedEvent);
161
162
        $formattedEvent['brands'] = $this->getBrands($event);
163
164
        if (isset($event->typicalAgeRange)) {
165
            $ageRange = $event->typicalAgeRange;
166
            $formattedEvent['ageFrom'] = explode('-', $ageRange)[0];
167
        }
168
169
        return $formattedEvent;
170
    }
171
172
    /**
173
     * @param string $eventId
174
     * @param stdClass $event
175
     * @param array $formattedEvent
176
     */
177
    private function addCalendarInfo($eventId, stdClass $event, array &$formattedEvent)
178
    {
179
        // Set the pre-formatted calendar summary as fallback in case no calendar repository was provided.
180
        $formattedEvent['dates'] = $event->calendarSummary;
181
182
        $calendar = null;
183
184
        if ($this->calendarRepository) {
185
            $calendar = $this->calendarRepository->get($eventId);
186
        }
187
188
        if ($calendar instanceof \CultureFeed_Cdb_Data_Calendar) {
189
            $formatter = new CalendarHTMLFormatter();
190
            $formattedEvent['dates'] = $formatter->format($calendar, 'lg');
191
        }
192
    }
193
194
    /**
195
     * @param string $eventId
196
     * @param array $formattedEvent
197
     */
198
    private function addUitpasInfo($eventId, array &$formattedEvent)
199
    {
200
        if ($this->uitpas) {
201
            $uitpasInfo = $this->uitpas->getEventInfo($eventId);
202
            if ($uitpasInfo) {
203
                $formattedEvent['uitpas'] = $this->uitpasInfoFormatter->format($uitpasInfo);
204
            }
205
        }
206
    }
207
208
    /**
209
     * @param $event
210
     * @param $formattedEvent
211
     */
212
    private function formatTaaliconen($event, &$formattedEvent)
213
    {
214
        $taalicoonCount = 0;
215
        $description = '';
216
        $i = 0;
217
        $satisfiedCount = 0;
218
219
        foreach ($this->taalicoonSpecs as $name => $spec) {
220
            $i++;
221
            /** @var EventSpecificationInterface $spec */
222
            if ($spec->isSatisfiedBy($event)) {
223
                $satisfiedCount++;
224
                $taalicoonCount = $i;
225
                $description = TaalicoonDescription::getByName($name)->getValue();
226
            }
227
        }
228
229
        // Only add the taalicoonCount if the event was tagged with a single "taaliconen" tag. If multiple tags were
230
        // added, simply ignore the taaliconen.
231
        if ($taalicoonCount > 0 && $satisfiedCount == 1) {
232
            $formattedEvent['taalicoonCount'] = $taalicoonCount;
233
            $formattedEvent['taalicoonDescription'] = $description;
234
        }
235
    }
236
237
    /**
238
     * @param $event
239
     * @return string[]
240
     */
241
    private function getBrands($event)
242
    {
243
        return array_keys(array_filter(
244
            $this->brandSpecs,
245
            function (EventSpecificationInterface $brandSpec) use ($event) {
246
                return $brandSpec->isSatisfiedBy($event);
247
            }
248
        ));
249
    }
250
251
    /**
252
     * @param stdClass $event
253
     * @param array $formattedEvent
254
     */
255 View Code Duplication
    private function addPriceInfo($event, &$formattedEvent)
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...
256
    {
257
        $basePrice = null;
258
259
        if (property_exists($event, 'priceInfo') && is_array($event->priceInfo)) {
260
            foreach ($event->priceInfo as $price) {
261
                if ($price->category == 'base') {
262
                    $basePrice = $price;
263
                    break;
264
                }
265
            }
266
        }
267
268
        $formattedEvent['price'] =
269
            $basePrice ? $this->priceFormatter->format($basePrice->price) : 'Niet ingevoerd';
270
    }
271
}
272