Test Failed
Push — master ( 553dad...720bdd )
by Maurício
02:06
created

Loader::loadFunctions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
    Copyright (c) 2005 Steven Armstrong <sa at c-area dot ch>
4
    Copyright (c) 2009 Danilo Segan <[email protected]>
5
    Copyright (c) 2016 Michal Čihař <[email protected]>
6
7
    This file is part of MoTranslator.
8
9
    This program is free software; you can redistribute it and/or modify
10
    it under the terms of the GNU General Public License as published by
11
    the Free Software Foundation; either version 2 of the License, or
12
    (at your option) any later version.
13
14
    This program is distributed in the hope that it will be useful,
15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
    GNU General Public License for more details.
18
19
    You should have received a copy of the GNU General Public License along
20
    with this program; if not, write to the Free Software Foundation, Inc.,
21
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
*/
23
declare(strict_types=1);
24
25
namespace PhpMyAdmin\MoTranslator;
26
27
class Loader
28
{
29
    /**
30
     * Loader instance.
31
     *
32
     * @static
33
     * @var Loader
34
     */
35
    private static $_instance;
36
37
    /**
38
     * Default gettext domain to use.
39
     *
40
     * @var string
41
     */
42
    private $default_domain = '';
43
44
    /**
45
     * Configured locale.
46
     *
47
     * @var string
48
     */
49
    private $locale = '';
50
51
    /**
52
     * Loaded domains.
53
     *
54
     * @var array
55
     */
56
    private $domains = [];
57
58
    /**
59
     * Bound paths for domains.
60
     *
61
     * @var array
62
     */
63
    private $paths = ['' => './'];
64
65
    /**
66
     * Returns the singleton Loader object.
67
     *
68
     * @return Loader object
69
     */
70 5
    public static function getInstance()
71
    {
72 5
        if (empty(self::$_instance)) {
73 1
            self::$_instance = new self();
74
        }
75
76 5
        return self::$_instance;
77
    }
78
79
    /**
80
     * Loads global localizaton functions.
81
     */
82 2
    public static function loadFunctions()
83
    {
84 2
        require_once __DIR__ . '/functions.php';
85 2
    }
86
87
    /**
88
     * Figure out all possible locale names and start with the most
89
     * specific ones.  I.e. for sr_CS.UTF-8@latin, look through all of
90
     * sr_CS.UTF-8@latin, sr_CS@latin, sr@latin, sr_CS.UTF-8, sr_CS, sr.
91
     *
92
     * @param string $locale Locale code
93
     *
94
     * @return array list of locales to try for any POSIX-style locale specification
95
     */
96 20
    public static function listLocales($locale)
97
    {
98 20
        $locale_names = [];
99
100 20
        if ($locale) {
101 20
            if (preg_match(
102 20
                '/^(?P<lang>[a-z]{2,3})'      // language code
103 20
                . '(?:_(?P<country>[A-Z]{2}))?'           // country code
104
                . '(?:\\.(?P<charset>[-A-Za-z0-9_]+))?'   // charset
105 20
                . '(?:@(?P<modifier>[-A-Za-z0-9_]+))?$/', // @ modifier
106 19
                $locale,
107
                $matches
108
            )) {
109 19
                $lang = $matches['lang'] ?? null;
110 19
                $country = $matches['country'] ?? null;
111 18
                $charset = $matches['charset'] ?? null;
112
                $modifier = $matches['modifier'] ?? null;
113 18
114 5
                if ($modifier) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $modifier 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...
115 2 View Code Duplication
                    if ($country) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $country 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...
116 2
                        if ($charset) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $charset 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...
117
                            array_push($locale_names, "${lang}_$country.$charset@$modifier");
118 2
                        }
119 3
120 1
                        array_push($locale_names, "${lang}_$country@$modifier");
121
                    } elseif ($charset) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $charset 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...
122 5
                        array_push($locale_names, "${lang}.$charset@$modifier");
123
                    }
124
125
                    array_push($locale_names, "$lang@$modifier");
126
                }
127
128 View Code Duplication
                if ($country) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $country 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...
129 10
                    if ($charset) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $charset 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...
130 2
                        array_push($locale_names, "${lang}_$country.$charset");
131
                    }
132 18
133
                    array_push($locale_names, "${lang}_$country");
134
                } elseif ($charset) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $charset 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...
135
                    array_push($locale_names, "${lang}.$charset");
136 19
                }
137 1
138
                array_push($locale_names, $lang);
139
            }
140
141 20
            // If the locale name doesn't match POSIX style, just include it as-is.
142
            if (! in_array($locale, $locale_names)) {
143
                array_push($locale_names, $locale);
144
            }
145
        }
146
147
        return $locale_names;
148
    }
149
150
    /**
151
     * Returns Translator object for domain or for default domain.
152
     *
153 10
     * @param string $domain Translation domain
154 6
     *
155
     * @return Translator
156
     */
157 10
    public function getTranslator($domain = '')
158 9
    {
159
        if (empty($domain)) {
160
            $domain = $this->default_domain;
161 10
        }
162 9
163 7
        if (! isset($this->domains[$this->locale])) {
164
            $this->domains[$this->locale] = [];
165 2
        }
166
167
        if (! isset($this->domains[$this->locale][$domain])) {
168 9
            if (isset($this->paths[$domain])) {
169
                $base = $this->paths[$domain];
170 9
            } else {
171 9
                $base = './';
172 9
            }
173 9
174 7
            $locale_names = $this->listLocales($this->locale);
175
176
            $filename = '';
177
            foreach ($locale_names as $locale) {
178
                $filename = "$base/$locale/LC_MESSAGES/$domain.mo";
179
                if (file_exists($filename)) {
180 9
                    break;
181
                }
182
            }
183 10
184
            // We don't care about invalid path, we will get fallback
185
            // translator here
186
            $this->domains[$this->locale][$domain] = new Translator($filename);
187
        }
188
189
        return $this->domains[$this->locale][$domain];
190
    }
191
192
    /**
193
     * Sets the path for a domain.
194 10
     *
195 10
     * @param string $domain Domain name
196
     * @param string $path   Path where to find locales
197
     */
198
    public function bindtextdomain($domain, $path)
199
    {
200
        $this->paths[$domain] = $path;
201
    }
202
203
    /**
204 10
     * Sets the default domain.
205 10
     *
206
     * @param string $domain Domain name
207
     */
208
    public function textdomain($domain)
209
    {
210
        $this->default_domain = $domain;
211
    }
212
213
    /**
214
     * Sets a requested locale.
215
     *
216 10
     * @param string $locale Locale name
217 10
     *
218
     * @return string Set or current locale
219
     */
220 10
    public function setlocale($locale)
221
    {
222
        if (! empty($locale)) {
223
            $this->locale = $locale;
224
        }
225
226
        return $this->locale;
227
    }
228
229
    /**
230
     * Detects currently configured locale.
231
     *
232
     * It checks:
233
     *
234
     * - global lang variable
235 2
     * - environment for LC_ALL, LC_MESSAGES and LANG
236 1
     *
237 1
     * @return string with locale name
238 1
     */
239 1
    public function detectlocale()
240 1
    {
241 1
        if (isset($GLOBALS['lang'])) {
242 1
            return $GLOBALS['lang'];
243
        } elseif (false !== $locale = getenv('LC_ALL')) {
244
            return $locale;
245 1
        } elseif (false !== $locale = getenv('LC_MESSAGES')) {
246
            return $locale;
247
        } elseif (false !== $locale = getenv('LANG')) {
248
            return $locale;
249
        }
250
251
        return 'en';
252
    }
253
}
254