Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
22.16% covered (danger)
22.16%
39 / 176
22.22% covered (danger)
22.22%
6 / 27
CRAP
0.00% covered (danger)
0.00%
0 / 1
TwigExtension
22.16% covered (danger)
22.16%
39 / 176
22.22% covered (danger)
22.22%
6 / 27
1995.90
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getFunctions
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 1
2
 dump
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 currentRoute
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
 getD115Enabeld
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getD115OpeningTimes
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getD115Text
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getBobbiChatButtonEnabeld
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getOSMAccessToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getOSMOptions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 formatPhoneNumber
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 convertOpeningTimes
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
1
 dateToTS
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 tsToDate
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 formatDateTime
93.75% covered (success)
93.75%
15 / 16
0.00% covered (danger)
0.00%
0 / 1
4.00
 kindOfPayment
50.00% covered (danger)
50.00%
6 / 12
0.00% covered (danger)
0.00%
0 / 1
10.50
 azPrefixList
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
30
 sortFirstChar
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 sortByName
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 toSortableString
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
2
 csvProperty
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 csvAppointmentLocations
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
56
 getAppointmentForLocationFromServiceAppointmentLocations
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 getAppointmentForService
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
30
 getLocationHintByServiceId
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
20
 dayIsBookable
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3/**
4 * @copyright BerlinOnline Stadtportal GmbH & Co. KG
5 **/
6
7namespace BO\Zmsdldb;
8
9use Error;
10
11/**
12 * Extension for Twig
13 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
14 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
15 * @SuppressWarnings(PHPMD.TooManyMethods)
16 */
17class TwigExtension extends \Twig\Extension\AbstractExtension
18{
19    private $container;
20
21    public function __construct($container = null)
22    {
23        $this->container = $container;
24    }
25
26    public function getName(): string
27    {
28        return 'dldb';
29    }
30
31    #[\Override]
32    public function getFunctions()
33    {
34        return array(
35            new \Twig\TwigFunction('convertOpeningTimes', array($this, 'convertOpeningTimes')),
36            new \Twig\TwigFunction('csvProperty', array($this, 'csvProperty')),
37            new \Twig\TwigFunction('csvAppointmentLocations', array($this, 'csvAppointmentLocations')),
38            new \Twig\TwigFunction('getAppointmentForService', array($this, 'getAppointmentForService')),
39            new \Twig\TwigFunction('getLocationHintByServiceId', array($this, 'getLocationHintByServiceId')),
40            new \Twig\TwigFunction('isAppointmentBookable', array($this, 'isAppointmentBookable')),
41            new \Twig\TwigFunction('kindOfPayment', array($this, 'kindOfPayment')),
42            new \Twig\TwigFunction('formatDateTime', array($this, 'formatDateTime')),
43            new \Twig\TwigFunction('dateToTS', array($this, 'dateToTS')),
44            new \Twig\TwigFunction('tsToDate', array($this, 'tsToDate')),
45            new \Twig\TwigFunction('dayIsBookable', array($this, 'dayIsBookable')),
46            new \Twig\TwigFunction('azPrefixList', array($this, 'azPrefixList')),
47            new \Twig\TwigFunction('formatPhoneNumber', array($this, 'formatPhoneNumber')),
48            new \Twig\TwigFunction('getOSMOptions', array($this, 'getOSMOptions')),
49            new \Twig\TwigFunction('getOSMAccessToken', array($this, 'getOSMAccessToken')),
50            new \Twig\TwigFunction('getD115Enabeld', array($this, 'getD115Enabeld')),
51            new \Twig\TwigFunction('getD115OpeningTimes', array($this, 'getD115OpeningTimes')),
52            new \Twig\TwigFunction('getD115Text', array($this, 'getD115Text')),
53            new \Twig\TwigFunction('getBobbiChatButtonEnabeld', array($this, 'getBobbiChatButtonEnabeld')),
54            new \Twig\TwigFunction('currentRoute', array($this, 'currentRoute')),
55            new \Twig\TwigFunction('dump', array($this, 'dump')),
56            new \Twig\TwigFunction(
57                'getAppointmentForLocationFromServiceAppointmentLocations',
58                array($this, 'getAppointmentForLocationFromServiceAppointmentLocations')
59            ),
60        );
61    }
62
63    public function dump($item): string
64    {
65        return '<pre>' . print_r($item, 1) . '</pre>';
66    }
67
68    /**
69     * @return (array|mixed|string)[]
70     *
71     */
72    public function currentRoute($lang = null): array
73    {
74        if ($this->container->has('currentRoute')) {
75            $routeParams = $this->container->get('currentRouteParams');
76
77            if (null !== $lang && 'de' == $lang) {
78                unset($routeParams['lang']);
79            } else {
80                $routeParams['lang'] = ($lang !== null) ? $lang : \App::$language->getCurrentLanguage();
81            }
82
83
84            $routeName = $this->container->get('currentRoute');
85            $route = array(
86                'name' => $routeName,
87                'params' => $routeParams
88            );
89        } else {
90            $route = array(
91                'name' => 'noroute',
92                'params' => []
93            );
94        }
95        return $route;
96    }
97
98
99    public function getD115Enabeld(): bool
100    {
101        $settingsRepository = \App::$repository->fromSetting();
102        $active = (bool)($settingsRepository->fetchName('d115.active') ?? true);
103
104
105        return $active;
106    }
107
108    public function getD115OpeningTimes()
109    {
110        $settingsRepository = \App::$repository->fromSetting();
111        $openinTimes = $settingsRepository->fetchName('d115.openingTime') ?? \App::D115_DEFAULT_OPENINGTIME;
112
113        return $openinTimes;
114    }
115
116    public function getD115Text()
117    {
118        $settingsRepository = \App::$repository->fromSetting();
119        $text = $settingsRepository->fetchName('d115.messageHtml') ?? \App::D115_DEFAULT_TEXT;
120
121        return $text;
122    }
123
124    public function getBobbiChatButtonEnabeld(): bool
125    {
126        $settingsRepository = \App::$repository->fromSetting();
127        $buttonEnabled = (bool)($settingsRepository->fetchName('frontend.bobbi.chatbutton.enabled') ?? false);
128
129        return $buttonEnabled;
130    }
131
132    public function getOSMAccessToken(): string
133    {
134        return \App::OSM_ACCESS_TOKEN;
135    }
136
137    public function getOSMOptions(): string
138    {
139        return 'gestureHandling: ' . \App::OSM_GESTURE_HANDLING;
140    }
141
142    public function formatPhoneNumber($phoneNumber): string|null
143    {
144        preg_match_all('/(^\+)?[\d]+/', $phoneNumber, $matches);
145        $number = implode($matches[0]);
146        $phonenumber = preg_replace('/^030/', '+4930', $number);
147        return $phonenumber;
148    }
149
150    public function convertOpeningTimes($name): string
151    {
152        $days = array(
153            'monday' => 'Montag',
154            'tuesday' => 'Dienstag',
155            'wednesday' => 'Mittwoch',
156            'thursday' => 'Donnerstag',
157            'friday' => 'Freitag',
158            'saturday' => 'Samstag',
159            'sunday' => 'Sonntag',
160            'special' => ''
161        );
162        return $days[$name];
163    }
164
165    /**
166     * @return false|int
167     */
168    public function dateToTS($datetime): int|false
169    {
170        $timestamp = ($datetime === (int)$datetime) ? $datetime : strtotime($datetime);
171        return $timestamp;
172    }
173
174    public function tsToDate($timestamp): string
175    {
176        $date =  date('Y-m-d', $timestamp);
177        return $date;
178    }
179
180    /**
181     * @return (false|float|int|mixed|string)[]
182     *
183     */
184    public function formatDateTime($dateString): array
185    {
186        $dateTime = new \DateTimeImmutable($dateString, new \DateTimezone('Europe/Berlin'));
187        $formatDate['date']     = Helper\DateTime::getFormatedDates($dateTime, "EE, dd. MMMM yyyy");
188        $formatDate['fulldate'] = Helper\DateTime::getFormatedDates($dateTime, "EEEE, 'den' dd. MMMM yyyy");
189        $formatDate['weekday']  = ($dateTime->format('N') == 0) ?
190            $dateTime->format('N') + 6 :
191            $dateTime->format('N') - 1;
192        $formatDate['weekdayfull'] = Helper\DateTime::getFormatedDates($dateTime, "EEEE");
193
194        $time = $dateTime->format('H:i');
195        $formatDate['time']     = ($time != '00:00') ?
196            Helper\DateTime::getFormatedDates($dateTime, "HH:mm 'Uhr'") :
197            false;
198        $formatDate['timeId']   = ($time != '00:00') ? $time : false;
199        $formatDate['ts']       = $dateTime->getTimestamp();
200        $formatDate['dateId']   = $dateTime->format('Y-m-d');
201        $formatDate['ym']      = $dateTime->format('Y-m');
202
203        return $formatDate;
204    }
205
206    public function kindOfPayment($code): string
207    {
208        $result = '';
209        if ($code == 0) {
210            $result = 'eccash';
211        } elseif ($code == 1) {
212            $result = 'nocash';
213        } elseif ($code == 2) {
214            $result = 'ec';
215        } elseif ($code == 3) {
216            $result = 'cash';
217        } elseif ($code == 4) {
218            $result = 'subscribecash';
219        }
220        return $result;
221    }
222
223    /**
224     * @return (array|mixed)[][]
225     *
226     */
227    public function azPrefixList($list, $property): array
228    {
229        $azList = array();
230        foreach ((array)$list as $item) {
231            if (!is_scalar($item) && Entity\Base::hasValidOffset($item, $property)) {
232                $currentPrefix = self::sortFirstChar($item[$property]);
233                if (!array_key_exists($currentPrefix, $azList)) {
234                    $azList[$currentPrefix] = array(
235                        'prefix' => $currentPrefix,
236                        'sublist' => array(),
237                    );
238                }
239                $azList[$currentPrefix]['sublist'][] = $item;
240                uasort($azList[$currentPrefix]['sublist'], array($this,'sortByName'));
241                ksort($azList);
242            }
243        }
244        return $azList;
245    }
246
247    protected static function sortFirstChar($string): string
248    {
249        $firstChar = mb_substr($string, 0, 1);
250        $firstChar = mb_strtoupper($firstChar);
251        $firstChar = strtr($firstChar, array('Ä' => 'A', 'Ö' => 'O', 'Ü' => 'U'));
252        return $firstChar;
253    }
254
255    protected static function sortByName($left, $right): int
256    {
257        return strcmp(
258            self::toSortableString(strtolower($left['name'])),
259            strtolower(self::toSortableString($right['name']))
260        );
261    }
262
263    protected static function toSortableString(string $string): string
264    {
265        $string = strtr($string, array(
266            'Ä' => 'Ae',
267            'Ö' => 'Oe',
268            'Ü' => 'Ue',
269            'ä' => 'ae',
270            'ö' => 'oe',
271            'ü' => 'ue',
272            'ß' => 'ss',
273            '€' => 'E',
274        ));
275        return $string;
276    }
277
278    public function csvProperty($list, $property): string
279    {
280        $propertylist = array();
281        foreach ($list as $item) {
282            if (!is_scalar($item) && Entity\Base::hasValidOffset($item, $property)) {
283                $propertylist[] = $item[$property];
284            }
285        }
286        return implode(',', array_unique($propertylist));
287    }
288
289    public function csvAppointmentLocations($list, $service_id = ''): string
290    {
291        $propertylist = array();
292        foreach ($list as $item) {
293            if (!is_scalar($item) && Entity\Base::hasValidOffset($item, 'services')) {
294                $appointment = $this->getAppointmentForService($item, $service_id);
295                if ($appointment === false) {
296                    continue;
297                }
298                if (false === $appointment['external'] && true === $appointment['allowed']) {
299                    $propertylist[] = $item['id'];
300                }
301            }
302        }
303        return implode(',', array_unique($propertylist));
304    }
305
306    /**
307     * @SuppressWarnings(PHPMD.LongVariable)
308     */
309    public function getAppointmentForLocationFromServiceAppointmentLocations(
310        array $serviceAppointmentLocationList,
311        $locationId
312    ) {
313        if (isset($serviceAppointmentLocationList[$locationId])) {
314            $appointment = $serviceAppointmentLocationList[$locationId]['appointment'];
315            $appointment['responsibility_hint'] = $serviceAppointmentLocationList[$locationId]['responsibility_hint'];
316            $appointment['responsibility'] = $serviceAppointmentLocationList[$locationId]['responsibility'];
317            return $appointment;
318        }
319        return false;
320    }
321
322    public function getAppointmentForService($location, $service_id)
323    {
324        $servicecompare = explode(',', $service_id);
325        foreach ($location['services'] as $service) {
326            if (in_array($service['service'], $servicecompare)) {
327                $appointment = $service['appointment'];
328                if ($appointment['allowed'] === true || $appointment['external'] === true) {
329                    return $appointment;
330                }
331            }
332        }
333        return false;
334    }
335
336    public function getLocationHintByServiceId($location, $service_id)
337    {
338        if (isset($location['services'])) {
339            foreach ($location['services'] as $service) {
340                if ($service['service'] == $service_id) {
341                    return $service['hint'];
342                }
343            }
344        }
345        return false;
346    }
347
348    public function dayIsBookable($dateList, $day)
349    {
350        $result = false;
351        if (count($dateList)) {
352            foreach ($dateList as $date) {
353                if ($date['datum'] == $day) {
354                    $result = $date;
355                }
356            }
357        }
358        return $result;
359    }
360}