Completed
Push — master ( 85914a...2ce878 )
by Harald
06:39 queued 03:01
created

Language::__construct()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 90
Code Lines 77

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 77
nc 8
nop 1
dl 0
loc 90
rs 8.2713
c 0
b 0
f 0

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
  * osCommerce Online Merchant
4
  *
5
  * @copyright (c) 2016 osCommerce; https://www.oscommerce.com
6
  * @license GPL; https://www.oscommerce.com/gpllicense.txt
7
  */
8
9
namespace OSC\OM;
10
11
use OSC\OM\Cache;
12
use OSC\OM\OSCOM;
13
use OSC\OM\Registry;
14
15
class Language
16
{
17
    protected $language;
18
    protected $languages = [];
19
    protected $definitions = [];
20
    protected $detectors = [];
21
    protected $use_cache = false;
22
    protected $db;
23
24
    public function __construct($code = null)
25
    {
26
        $this->db = Registry::get('Db');
27
28
        $Qlanguages = $this->db->prepare('select languages_id, name, code, image, directory from :table_languages order by sort_order');
29
        $Qlanguages->setCache('languages-system');
30
        $Qlanguages->execute();
31
32
        while ($Qlanguages->fetch()) {
33
            $this->languages[$Qlanguages->value('code')] = [
34
                'id' => $Qlanguages->valueInt('languages_id'),
35
                'code' => $Qlanguages->value('code'),
36
                'name' => $Qlanguages->value('name'),
37
                'image' => $Qlanguages->value('image'),
38
                'directory' => $Qlanguages->value('directory')
39
            ];
40
        }
41
42
        $this->detectors = [
43
            'af' => 'af|afrikaans',
44
            'ar' => 'ar([-_][[:alpha:]]{2})?|arabic',
45
            'be' => 'be|belarusian',
46
            'bg' => 'bg|bulgarian',
47
            'br' => 'pt[-_]br|brazilian portuguese',
48
            'ca' => 'ca|catalan',
49
            'cs' => 'cs|czech',
50
            'da' => 'da|danish',
51
            'de' => 'de([-_][[:alpha:]]{2})?|german',
52
            'el' => 'el|greek',
53
            'en' => 'en([-_][[:alpha:]]{2})?|english',
54
            'es' => 'es([-_][[:alpha:]]{2})?|spanish',
55
            'et' => 'et|estonian',
56
            'eu' => 'eu|basque',
57
            'fa' => 'fa|farsi',
58
            'fi' => 'fi|finnish',
59
            'fo' => 'fo|faeroese',
60
            'fr' => 'fr([-_][[:alpha:]]{2})?|french',
61
            'ga' => 'ga|irish',
62
            'gl' => 'gl|galician',
63
            'he' => 'he|hebrew',
64
            'hi' => 'hi|hindi',
65
            'hr' => 'hr|croatian',
66
            'hu' => 'hu|hungarian',
67
            'id' => 'id|indonesian',
68
            'it' => 'it|italian',
69
            'ja' => 'ja|japanese',
70
            'ko' => 'ko|korean',
71
            'ka' => 'ka|georgian',
72
            'lt' => 'lt|lithuanian',
73
            'lv' => 'lv|latvian',
74
            'mk' => 'mk|macedonian',
75
            'mt' => 'mt|maltese',
76
            'ms' => 'ms|malaysian',
77
            'nl' => 'nl([-_][[:alpha:]]{2})?|dutch',
78
            'no' => 'no|norwegian',
79
            'pl' => 'pl|polish',
80
            'pt' => 'pt([-_][[:alpha:]]{2})?|portuguese',
81
            'ro' => 'ro|romanian',
82
            'ru' => 'ru|russian',
83
            'sk' => 'sk|slovak',
84
            'sq' => 'sq|albanian',
85
            'sr' => 'sr|serbian',
86
            'sv' => 'sv|swedish',
87
            'sz' => 'sz|sami',
88
            'sx' => 'sx|sutu',
89
            'th' => 'th|thai',
90
            'ts' => 'ts|tsonga',
91
            'tr' => 'tr|turkish',
92
            'tn' => 'tn|tswana',
93
            'uk' => 'uk|ukrainian',
94
            'ur' => 'ur|urdu',
95
            'vi' => 'vi|vietnamese',
96
            'tw' => 'zh[-_]tw|chinese traditional',
97
            'zh' => 'zh|chinese simplified',
98
            'ji' => 'ji|yiddish',
99
            'zu' => 'zu|zulu'
100
        ];
101
102
        if (!isset($code) || !$this->exists($code)) {
103
            if (isset($_SESSION['language'])) {
104
                $code = $_SESSION['language'];
105
            } else {
106
                $client = $this->getClientPreference();
107
108
                $code = ($client !== false) ? $client : DEFAULT_LANGUAGE;
109
            }
110
        }
111
112
        $this->set($code);
113
    }
114
115
    public function set($code)
116
    {
117
        if ($this->exists($code)) {
118
            $this->language = $code;
119
        } else {
120
            trigger_error('OSC\OM\Language::set() - The language does not exist: ' . $code);
121
        }
122
    }
123
124
    public function get($data = null, $language_code = null)
125
    {
126
        if (!isset($data)) {
127
            $data = 'code';
128
        }
129
130
        if (!isset($language_code)) {
131
            $language_code = $this->language;
132
        }
133
134
        return $this->languages[$language_code][$data];
135
    }
136
137
    public function getId($language_code = null)
138
    {
139
        return (int)$this->get('id', $language_code);
140
    }
141
142
    public function getAll()
143
    {
144
        return $this->languages;
145
    }
146
147
    public function exists($code)
148
    {
149
        return isset($this->languages[$code]);
150
    }
151
152
    public function getClientPreference()
153
    {
154
        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
155
            $client = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
156
157
            foreach ($client as $c) {
158
                foreach ($this->detectors as $code => $value) {
159
                    if (preg_match('/^(' . $value . ')(;q=[0-9]\\.[0-9])?$/i', $c) && $this->exists($code)) {
160
                        return $code;
161
                    }
162
                }
163
            }
164
        }
165
166
        return false;
167
    }
168
169
    public function getDef($key, $values = null, $scope = 'global')
170
    {
171
        if (isset($this->definitions[$scope][$key])) {
172
            $def = $this->definitions[$scope][$key];
173
174
            if (is_array($values) && !empty($values)) {
175
                $def = str_replace(array_keys($values), array_values($values), $def);
176
            }
177
178
            return $def;
179
        }
180
181
        return $key;
182
    }
183
184
    public function definitionsExist($group, $language_code = null)
185
    {
186
        $language_code = isset($language_code) && $this->exists($language_code) ? $language_code : $this->get('code');
187
188
        $site = OSCOM::getSite();
189
190
        if ((strpos($group, '/') !== false) && (preg_match('/^([A-Z][A-Za-z0-9-_]*)\/(.*)$/', $group, $matches) === 1) && OSCOM::siteExists($matches[1])) {
191
            $site = $matches[1];
192
            $group = $matches[2];
193
        }
194
195
        $pathname = OSCOM::getConfig('dir_root', $site) . 'includes/languages/' . $this->get('directory', $language_code) . '/' . $group;
196
197
        // legacy
198
        if (is_file($pathname . '.php')) {
199
            return true;
200
        }
201
202
        $pathname .= '.txt';
203
204
        if (is_file($pathname)) {
205
            return true;
206
        }
207
208
        if ($language_code != 'en') {
209
            return call_user_func([$this, __FUNCTION__], $group, 'en');
210
        }
211
212
        return false;
213
    }
214
215
    public function loadDefinitions($group, $language_code = null, $scope = null)
216
    {
217
        $language_code = isset($language_code) && $this->exists($language_code) ? $language_code : $this->get('code');
218
219
        if (!isset($scope)) {
220
            $scope = 'global';
221
        }
222
223
        $site = OSCOM::getSite();
224
225
        if ((strpos($group, '/') !== false) && (preg_match('/^([A-Z][A-Za-z0-9-_]*)\/(.*)$/', $group, $matches) === 1) && OSCOM::siteExists($matches[1])) {
226
            $site = $matches[1];
227
            $group = $matches[2];
228
        }
229
230
        $pathname = OSCOM::getConfig('dir_root', $site) . 'includes/languages/' . $this->get('directory', $language_code) . '/' . $group;
231
232
        // legacy
233
        if (is_file($pathname . '.php')) {
234
            include($pathname . '.php');
235
            return true;
236
        }
237
238
        $pathname .= '.txt';
239
240
        if ($language_code != 'en') {
241
            call_user_func([$this, __FUNCTION__], $group, 'en', $scope);
242
        }
243
244
        $defs = $this->getDefinitions($group, $language_code, $pathname);
245
246
        $this->injectDefinitions($defs, $scope);
247
    }
248
249
    public function getDefinitions($group, $language_code, $pathname)
250
    {
251
        $defs = [];
252
253
        $group_key = str_replace(['/', '\\'], '-', $group);
254
255
        if ($this->use_cache === false) {
256
            return $this->getDefinitionsFromFile($pathname);
257
        }
258
259
        $OSCOM_Cache = new Cache();
260
261
        if ($OSCOM_Cache->read('languages-defs-' . $group_key . '-lang' . $this->getId($language_code))) {
262
            $defs = $OSCOM_Cache->getCache();
263
        } else {
264
            $Qdefs = $this->db->get('languages_definitions', [
265
                'definition_key',
266
                'definition_value'
267
            ], [
268
                'languages_id' => $this->getId($language_code),
269
                'content_group' => $group_key
270
            ]);
271
272
            while ($Qdefs->fetch()) {
273
                $defs[$Qdefs->value('definition_key')] = $Qdefs->value('definition_value');
274
            }
275
276
            if (empty($defs)) {
277
                $defs = $this->getDefinitionsFromFile($pathname);
278
279
                foreach ($defs as $key => $value) {
0 ignored issues
show
Bug introduced by
The expression $defs of type false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
280
                    $this->db->save('languages_definitions', [
281
                        'languages_id' => $this->getId($language_code),
282
                        'content_group' => $group_key,
283
                        'definition_key' => $key,
284
                        'definition_value' => $value
285
                    ]);
286
                }
287
            }
288
289
            $OSCOM_Cache->write($defs);
290
        }
291
292
        return $defs;
293
    }
294
295
    public function getDefinitionsFromFile($filename)
296
    {
297
        if (!is_file($filename)) {
298
            trigger_error('OSC\OM\Language::getDefinitionsFromFile() - Filename does not exist: ' . $filename);
299
300
            return false;
301
        }
302
303
        $defs = [];
304
305
        foreach (file($filename) as $line) {
306
            $line = trim($line);
307
308
            if (!empty($line) && (substr($line, 0, 1) != '#')) {
309
                $delimiter = strpos($line, '=');
310
311
                if (($delimiter !== false) && (preg_match('/^[A-Za-z0-9_-]/', substr($line, 0, $delimiter)) === 1) && (substr_count(substr($line, 0, $delimiter), ' ') === 1)) {
312
                    $key = trim(substr($line, 0, $delimiter));
313
                    $value = trim(substr($line, $delimiter + 1));
314
315
                    $defs[$key] = $value;
316
                } elseif (isset($key)) {
317
                    $defs[$key] .= "\n" . $line;
318
                }
319
            }
320
        }
321
322
        return $defs;
323
    }
324
325
    public function injectDefinitions($defs, $scope)
326
    {
327
        if (isset($this->definitions[$scope])) {
328
            $this->definitions[$scope] = array_merge($this->definitions[$scope], $defs);
329
        } else {
330
            $this->definitions[$scope] = $defs;
331
        }
332
    }
333
334
    public function setUseCache($flag)
335
    {
336
        $this->use_cache = ($flag === true);
337
    }
338
}
339