Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
89.83% covered (warning)
89.83%
53 / 59
80.00% covered (warning)
80.00%
8 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
Language
89.83% covered (warning)
89.83%
53 / 59
80.00% covered (warning)
80.00%
8 / 10
36.29
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
6
 getDefaultLanguageName
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getCurrentLanguage
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
3
 getLocale
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 getCurrentLocale
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setCurrentLocale
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 getLocaleList
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 getDefault
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
6
 getLanguageFromRequest
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
 getLanguageFromUri
42.86% covered (danger)
42.86%
3 / 7
0.00% covered (danger)
0.00%
0 / 1
9.66
1<?php
2
3namespace BO\Slim;
4
5use Psr\Http\Message\RequestInterface;
6use Psr\Http\Message\ServerRequestInterface;
7use Symfony\Bridge\Twig\Extension\TranslationExtension;
8use Symfony\Component\Translation\Translator;
9
10class Language
11{
12    public static array $supportedLanguages = array();
13
14    public string $current = '';
15
16    protected string $currentLocale = '';
17
18    protected string $default = '';
19
20    protected static ?Translator $translatorInstance = null;
21
22    public function __construct(RequestInterface $request, array $supportedLanguages)
23    {
24        self::$supportedLanguages = $supportedLanguages;
25        $this->current = $this->getLanguageFromRequest($request);
26        $fallbackLocale = $this->getLocale($this->getDefault());
27        $this->currentLocale = $this->getLocale($this->getCurrentLanguage());
28        $this->setCurrentLocale();
29        $defaultLang = $this->getDefault();
30
31        /** @psalm-suppress RedundantCondition Module App subclasses may set MULTILANGUAGE to false. */
32        if (
33            \App::MULTILANGUAGE
34            || (strlen($fallbackLocale) > 0 && strlen($this->currentLocale) > 0 && strlen($defaultLang) > 0)
35        ) {
36            if (null === self::$translatorInstance) {
37                self::$translatorInstance = (new LanguageTranslator(
38                    $fallbackLocale,
39                    $this->currentLocale,
40                    $defaultLang
41                ))->getInstance();
42                \BO\Slim\Bootstrap::addTwigExtension(new TranslationExtension(self::$translatorInstance));
43            } else {
44                self::$translatorInstance->setLocale($this->currentLocale);
45            }
46        }
47    }
48
49    /** @psalm-api */
50    public function getDefaultLanguageName(): ?string
51    {
52        $default = \App::$supportedLanguages[$this->getDefault()]['name'] ?? null;
53        return $default;
54    }
55
56    public function getCurrentLanguage(string $lang = ''): string
57    {
58        $current = (isset(self::$supportedLanguages[$this->current])) ? $this->current : $this->getDefault();
59        return ($lang != '') ? $lang : $current;
60    }
61
62    public function getLocale(string $locale = ''): string
63    {
64        $locale = ('' == $locale) ? $this->getDefault() : $locale;
65        if (
66            isset(self::$supportedLanguages[$this->getCurrentLanguage($locale)]) &&
67            isset(self::$supportedLanguages[$this->getCurrentLanguage($locale)]['locale'])
68        ) {
69            $locale = (string) self::$supportedLanguages[$this->getCurrentLanguage($locale)]['locale'];
70        }
71        return $locale;
72    }
73
74    /** @psalm-api */
75    public function getCurrentLocale(): string
76    {
77        return $this->currentLocale;
78    }
79
80    public function setCurrentLocale(): void
81    {
82        if (class_exists("Locale")) {
83            \Locale::setDefault($this->currentLocale);
84        }
85        \setlocale(LC_ALL, $this->getLocaleList($this->currentLocale));
86    }
87
88    /**
89     * @return string[]
90     *
91     */
92    protected function getLocaleList(string $locale): array
93    {
94        $localeList = [];
95        $localeList[] = $this->getCurrentLanguage();
96        $localeList[] = $locale;
97        $suffixList = ['utf8', 'utf-8'];
98        foreach ($suffixList as $suffix) {
99            array_unshift($localeList, $locale . '.' . $suffix);
100        }
101        return $localeList;
102    }
103
104    public function getDefault(): string
105    {
106        if ($this->default !== '') {
107            return $this->default;
108        }
109        foreach (self::$supportedLanguages as $lang_id => $lang_data) {
110            if (isset($lang_data['default']) && $lang_data['default']) {
111                $this->default = (string) $lang_id;
112                return $this->default;
113            }
114        }
115        $first = array_key_first(self::$supportedLanguages);
116        $this->default = $first !== null ? (string) $first : '';
117        return $this->default;
118    }
119
120    // Detect current language based on request URI or Parameter
121    protected function getLanguageFromRequest(RequestInterface $request): string
122    {
123        $language = $this->getLanguageFromUri($request);
124
125        if ($request instanceof ServerRequestInterface) {
126            $route = $request->getAttribute('route');
127            if ($route instanceof \Slim\Routing\Route) {
128                $lang = $route->getArgument('lang');
129                if ($lang !== null && $lang !== '') {
130                    $language = $lang;
131                }
132            }
133        }
134
135        return $language;
136    }
137
138    protected function getLanguageFromUri(RequestInterface $request): string
139    {
140        if ($request instanceof Request) {
141            $requestParamLang = $request->getParam('lang');
142            return ($requestParamLang) ? (string) $requestParamLang : $this->getDefault();
143        }
144        if ($request instanceof ServerRequestInterface) {
145            $query = $request->getQueryParams();
146            return !empty($query['lang']) ? (string) $query['lang'] : $this->getDefault();
147        }
148        return $this->getDefault();
149    }
150}