Completed
Push — master ( 56c695...dbb523 )
by Michal
03:48
created

Loader::listLocales()   C

Complexity

Conditions 11
Paths 43

Size

Total Lines 47
Code Lines 31

Duplication

Lines 16
Ratio 34.04 %

Code Coverage

Tests 33
CRAP Score 11

Importance

Changes 0
Metric Value
cc 11
eloc 31
nc 43
nop 1
dl 16
loc 47
ccs 33
cts 33
cp 1
crap 11
rs 5.2653
c 0
b 0
f 0

How to fix   Complexity   

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
    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
24
namespace PhpMyAdmin\MoTranslator;
25
26
class Loader
27
{
28
    /**
29
     * Loader instance.
30
     *
31
     * @static
32
     *
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 = array();
57
58
    /**
59
     * Bound paths for domains.
60
     *
61
     * @var array
62
     */
63
    private $paths = array('' => './');
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 1
        }
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 18
    public static function listLocales($locale)
97
    {
98 18
        $locale_names = array();
99
100 18
        $lang = null;
101 18
        $country = null;
102 18
        $charset = null;
103 18
        $modifier = null;
104
105 18
        if ($locale) {
106 17
            if (preg_match('/^(?P<lang>[a-z]{2,3})'      // language code
107
                . '(?:_(?P<country>[A-Z]{2}))?'           // country code
108 17
                . '(?:\\.(?P<charset>[-A-Za-z0-9_]+))?'   // charset
109 17
                . '(?:@(?P<modifier>[-A-Za-z0-9_]+))?$/', // @ modifier
110 17
                $locale, $matches)) {
111 16
                extract($matches);
112
113 16
                if ($modifier) {
114 5 View Code Duplication
                    if ($country) {
115 2
                        if ($charset) {
116 2
                            array_push($locale_names, "${lang}_$country.$charset@$modifier");
117 2
                        }
118 2
                        array_push($locale_names, "${lang}_$country@$modifier");
119 5
                    } elseif ($charset) {
120 1
                        array_push($locale_names, "${lang}.$charset@$modifier");
121 1
                    }
122 5
                    array_push($locale_names, "$lang@$modifier");
123 5
                }
124 View Code Duplication
                if ($country) {
125
                    if ($charset) {
126
                        array_push($locale_names, "${lang}_$country.$charset");
127
                    }
128
                    array_push($locale_names, "${lang}_$country");
129 16
                } elseif ($charset) {
130 2
                    array_push($locale_names, "${lang}.$charset");
131 2
                }
132 16
                array_push($locale_names, $lang);
133 16
            }
134
135
            // If the locale name doesn't match POSIX style, just include it as-is.
136 17
            if (!in_array($locale, $locale_names)) {
137 1
                array_push($locale_names, $locale);
138 1
            }
139 17
        }
140
141 18
        return $locale_names;
142
    }
143
144
    /**
145
     * Returns Translator object for domain or for default domain.
146
     *
147
     * @param string $domain Translation domain
148
     *
149
     * @return Translator
150
     */
151
    public function getTranslator($domain = '')
152
    {
153 9
        if (empty($domain)) {
154 6
            $domain = $this->default_domain;
155 6
        }
156
157 9
        if (!isset($this->domains[$domain])) {
158 7
            if (isset($this->paths[$domain])) {
159 5
                $base = $this->paths[$domain];
160 5
            } else {
161 2
                $base = './';
162
            }
163
164 7
            $locale_names = $this->listLocales($this->locale);
165
166 7
            $filename = '';
167 7
            foreach ($locale_names as $locale) {
168 7
                $filename = "$base/$locale/LC_MESSAGES/$domain.mo";
169 7
                if (file_exists($filename)) {
170 5
                    break;
171
                }
172 7
            }
173
174
            // We don't care about invalid path, we will get fallback
175
            // translator here
176 7
            $this->domains[$domain] = new Translator($filename);
177 7
        }
178
179 9
        return $this->domains[$domain];
180
    }
181
182
    /**
183
     * Sets the path for a domain.
184
     *
185
     * @param string $domain Domain name
186
     * @param string $path   Path where to find locales
187
     */
188
    public function bindtextdomain($domain, $path)
189
    {
190 9
        $this->paths[$domain] = $path;
191 9
    }
192
193
    /**
194
     * Sets the default domain.
195
     *
196
     * @param string $domain Domain name
197
     */
198
    public function textdomain($domain)
199
    {
200 9
        $this->default_domain = $domain;
201 9
    }
202
203
    /**
204
     * Sets a requested locale.
205
     *
206
     * @param string $locale Locale name
207
     *
208
     * @return string Set or current locale
209
     */
210
    public function setlocale($locale)
211
    {
212 9
        if (!empty($locale)) {
213 9
            $this->locale = $locale;
214
            // Set system locales as well
215 9
            if (function_exists('setlocale')) {
216 9
                setlocale(0, $locale);
217 9
            }
218 9
        }
219
220 9
        return $this->locale;
221
    }
222
223
    /**
224
     * Detects currently configured locale.
225
     *
226
     * It checks:
227
     *
228
     * - global lang variable
229
     * - environment for LC_ALL, LC_MESSAGES and LANG
230
     *
231
     * @return string with locale name
232
     */
233
    public function detectlocale()
234
    {
235 2
        if (isset($GLOBALS['lang'])) {
236 1
            return $GLOBALS['lang'];
237 1
        } elseif (getenv('LC_ALL')) {
238 1
            return getenv('LC_ALL');
239 1
        } elseif (getenv('LC_MESSAGES')) {
240 1
            return getenv('LC_MESSAGES');
241 1
        } elseif (getenv('LANG')) {
242 1
            return getenv('LANG');
243
        }
244
245 1
        return 'en';
246
    }
247
}
248