GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Language::setLanguage()   F
last analyzed

Complexity

Conditions 19
Paths 672

Size

Total Lines 63

Duplication

Lines 19
Ratio 30.16 %

Importance

Changes 0
Metric Value
cc 19
nc 672
nop 2
dl 19
loc 63
rs 0.8055
c 0
b 0
f 0

How to fix   Long Method    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
namespace phpMyFAQ;
4
5
/**
6
 * Manages all language stuff.
7
 *
8
 * This Source Code Form is subject to the terms of the Mozilla Public License,
9
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
10
 * obtain one at http://mozilla.org/MPL/2.0/.
11
 *
12
 * @package phpMyFAQ
13
 * @author Thorsten Rinne <[email protected]>
14
 * @author Matteo scaramuccia <[email protected]>
15
 * @author Aurimas Fišeras <[email protected]>
16
 * @copyright 2009-2019 phpMyFAQ Team
17
 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
18
 * @link https://www.phpmyfaq.de
19
 * @since 2009-05-14
20
 */
21
22
if (!defined('IS_VALID_PHPMYFAQ')) {
23
    exit();
24
}
25
26
/**
27
 * Class Language
28
 * @package phpMyFAQ
29
 * @author Thorsten Rinne <[email protected]>
30
 * @author Matteo scaramuccia <[email protected]>
31
 * @author Aurimas Fišeras <[email protected]>
32
 * @copyright 2009-2019 phpMyFAQ Team
33
 * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
34
 * @link https://www.phpmyfaq.de
35
 * @since 2009-05-14
36
 */
37
class Language
38
{
39
    /**
40
     * The accepted language of the user agend.
41
     *
42
     * @var string
43
     */
44
    public $acceptedLanguage = '';
45
46
    /**
47
     * The current language.
48
     *
49
     * @var string
50
     */
51
    public static $language = '';
52
53
    /**
54
     * @var Configuration
55
     */
56
    private $config;
57
58
    /**
59
     * Constructor.
60
     *
61
     * @param Configuration $config
62
     */
63
    public function __construct(Configuration $config)
64
    {
65
        $this->config = $config;
66
    }
67
68
    /**
69
     * Returns an array of country codes for a specific FAQ record ID,
70
     * specific category ID or all languages used by FAQ records , categories.
71
     *
72
     * @param int    $id    ID
73
     * @param string $table Specifies table
74
     *
75
     * @return array
76
     */
77
    public function languageAvailable(int $id, string $table = 'faqdata'): array
78
    {
79
        $output = [];
80
81
        if (isset($id)) {
82
            if ($id == 0) {
83
                // get languages for all ids
84
                $distinct = ' DISTINCT ';
85
                $where = '';
86
            } else {
87
                // get languages for specified id
88
                $distinct = '';
89
                $where = ' WHERE id = '.$id;
90
            }
91
92
            $query = sprintf('
93
                SELECT %s
94
                    lang
95
                FROM
96
                    %s%s
97
                %s',
98
                $distinct,
99
                Db::getTablePrefix(),
100
                $table,
101
                $where
102
            );
103
104
            $result = $this->config->getDb()->query($query);
105
106
            if ($this->config->getDb()->numRows($result) > 0) {
107
                while ($row = $this->config->getDb()->fetchObject($result)) {
108
                    $output[] = $row->lang;
109
                }
110
            }
111
        }
112
113
        return $output;
114
    }
115
116
    /**
117
     * Sets the current language for phpMyFAQ user session.
118
     *
119
     * @param bool   $configDetection Configuration detection
120
     * @param string $configLanguage  Language from configuration
121
     *
122
     * @return string
123
     */
124
    public function setLanguage(bool $configDetection, string $configLanguage): string
125
    {
126
        $detectedLang = [];
127
        self::getUserAgentLanguage();
128
129
        // Get language from: _POST, _GET, _COOKIE, phpMyFAQ configuration and the automatic language detection
130
        $detectedLang['post'] = Filter::filterInput(INPUT_POST, 'language', FILTER_SANITIZE_STRING);
131 View Code Duplication
        if (!is_null($detectedLang['post']) && !self::isASupportedLanguage($detectedLang['post'])) {
132
            $detectedLang['post'] = null;
133
        }
134
        // Get the user language
135
        $detectedLang['get'] = Filter::filterInput(INPUT_GET, 'lang', FILTER_SANITIZE_STRING);
136 View Code Duplication
        if (!is_null($detectedLang['get']) && !self::isASupportedLanguage($detectedLang['get'])) {
137
            $detectedLang['get'] = null;
138
        }
139
        // Get the faq record language
140
        $detectedLang['artget'] = Filter::filterInput(INPUT_GET, 'artlang', FILTER_SANITIZE_STRING);
141 View Code Duplication
        if (!is_null($detectedLang['artget']) && !self::isASupportedLanguage($detectedLang['artget'])) {
142
            $detectedLang['artget'] = null;
143
        }
144
        // Get the language from the session
145
        if (isset($_SESSION['lang']) && self::isASupportedLanguage($_SESSION['lang'])) {
146
            $detectedLang['session'] = trim($_SESSION['lang']);
147
        }
148
149
        // Get the language from the config
150
        if (isset($configLanguage)) {
151
            $confLangCode = str_replace(array('language_', '.php'), '', $configLanguage);
152
            if (self::isASupportedLanguage($confLangCode)) {
153
                $detectedLang['config'] = $confLangCode;
154
            }
155
        }
156
        // Detect the browser's language
157
        if ((true === $configDetection) && self::isASupportedLanguage($this->acceptedLanguage)) {
158
            $detectedLang['detection'] = strtolower($this->acceptedLanguage);
159
        }
160
        // Select the language
161
        if (isset($detectedLang['post'])) {
162
            self::$language = $detectedLang['post'];
163
            $detectedLang = null;
164
            unset($detectedLang);
165
        } elseif (isset($detectedLang['get'])) {
166
            self::$language = $detectedLang['get'];
167
        } elseif (isset($detectedLang['artget'])) {
168
            self::$language = $detectedLang['artget'];
169 View Code Duplication
        } elseif (isset($detectedLang['session'])) {
170
            self::$language = $detectedLang['session'];
171
            $detectedLang = null;
172
            unset($detectedLang);
173
        } elseif (isset($detectedLang['detection'])) {
174
            self::$language = $detectedLang['detection'];
175
            $detectedLang = null;
176
            unset($detectedLang);
177 View Code Duplication
        } elseif (isset($detectedLang['config'])) {
178
            self::$language = $detectedLang['config'];
179
            $detectedLang = null;
180
            unset($detectedLang);
181
        } else {
182
            self::$language = 'en'; // just a fallback
183
        }
184
185
        return $_SESSION['lang'] = self::$language;
186
    }
187
188
    /**
189
     * Returns the current language.
190
     *
191
     * @return string
192
     */
193
    public function getLanguage(): string
194
    {
195
        return self::$language;
196
    }
197
198
    /**
199
     * This function returns the available languages.
200
     *
201
     * @return array
202
     */
203
    public static function getAvailableLanguages(): array
204
    {
205
        global $languageCodes;
206
207
        $search = array('language_', '.php');
208
        $languages = $languageFiles = [];
209
210
        $dir = new \DirectoryIterator(LANGUAGE_DIR);
211
        foreach ($dir as $fileinfo) {
212
            if (!$fileinfo->isDot()) {
213
                $languageFiles[] = strtoupper(
214
                    str_replace($search, '', trim($fileinfo->getFilename()))
215
                );
216
            }
217
        }
218
219
        foreach ($languageFiles as $lang) {
220
            // Check if the file is related to a (real) language before using it
221
            if (array_key_exists($lang, $languageCodes)) {
222
                $languages[strtolower($lang)] = $languageCodes[$lang];
223
            }
224
        }
225
226
        // Sort the languages list
227
        asort($languages);
228
        reset($languages);
229
230
        return $languages;
231
    }
232
233
    /**
234
     * This function displays the <select> box for the available languages
235
     * optionally filtered by excluding some provided languages.
236
     *
237
     * @param string $default
238
     * @param bool   $submitOnChange
239
     * @param array  $excludedLanguages
240
     * @param string $id
241
     *
242
     * @return string
243
     */
244
    public static function selectLanguages(
245
        string $default,
246
        bool $submitOnChange = false,
247
        array $excludedLanguages = [],
248
        string $id = 'language'): string
249
    {
250
        global $languageCodes;
251
252
        $onChange = ($submitOnChange ? ' onchange="this.form.submit();"' : '');
253
        $output = '<select class="form-control" name="'.$id.'" id="'.$id.'"'.$onChange.">\n";
254
        $languages = self::getAvailableLanguages();
255
256
        if (count($languages) > 0) {
257
            foreach ($languages as $lang => $value) {
258
                if (!in_array($lang, $excludedLanguages)) {
259
                    $output .= "\t".'<option value="'.$lang.'"';
260
                    if ($lang == $default) {
261
                        $output .= ' selected';
262
                    }
263
                    $output .= '>'.$value."</option>\n";
264
                }
265
            }
266
        } else {
267
            $output .= "\t<option value=\"en\">".$languageCodes['EN'].'</option>';
268
        }
269
        $output .= "</select>\n";
270
271
        return $output;
272
    }
273
274
    /**
275
     * Function for displaying all languages in <option>.
276
     *
277
     * @param string $lang              the languange to be selected
278
     * @param bool   $onlyThisLang      print only the passed language?
279
     * @param bool   $fileLanguageValue print the <language file> instead of the <language code> as value?
280
     *
281
     * @return string
282
     */
283
    public static function languageOptions(
284
        string $lang = '',
285
        bool $onlyThisLang = false,
286
        bool $fileLanguageValue = false): string
287
    {
288
        $output = '';
289
        foreach (self::getAvailableLanguages() as $key => $value) {
290
            if ($onlyThisLang) {
291 View Code Duplication
                if (strtolower($key) == $lang) {
292
                    if ($fileLanguageValue) {
293
                        $output .= "\t<option value=\"language_".strtolower($lang).'.php"';
294
                    } else {
295
                        $output .= "\t<option value=\"".strtolower($lang).'"';
296
                    }
297
                    $output .= ' selected="selected"';
298
                    $output .= '>'.$value."</option>\n";
299
                    break;
300
                }
301 View Code Duplication
            } else {
302
                if ($fileLanguageValue) {
303
                    $output .= "\t<option value=\"language_".strtolower($key).'.php"';
304
                } else {
305
                    $output .= "\t<option value=\"".strtolower($key).'"';
306
                }
307
                if (strtolower($key) == $lang) {
308
                    $output .= ' selected="selected"';
309
                }
310
                $output .= '>'.$value."</option>\n";
311
            }
312
        }
313
314
        return $output;
315
    }
316
317
    /**
318
     * True if the language is supported by the current phpMyFAQ installation.
319
     *
320
     * @param string|null $langCode Language code
321
     *
322
     * @return bool
323
     */
324
    public static function isASupportedLanguage($langCode): bool
325
    {
326
        global $languageCodes;
327
328
        return isset($languageCodes[strtoupper($langCode)]);
329
    }
330
331
    /**
332
     * True if the language is supported by the bundled TinyMCE editor.
333
     *
334
     * TinyMCE Language is supported if there is a language file present in
335
     * ROOT/admin/editor/langs/$langcode.js
336
     *
337
     * TinyMCE language packs can be downloaded from 
338
     * http://tinymce.moxiecode.com/download_i18n.php
339
     * and extracted to ROOT/admin/editor
340
     *
341
     * @param string|null $langCode Language code
342
     *
343
     * @return bool
344
     */
345
    public static function isASupportedTinyMCELanguage($langCode): bool
346
    {
347
        return file_exists(
348
            PMF_ROOT_DIR.'/admin/assets/js/editor/langs/'.$langCode.'.js'
349
        );
350
    }
351
352
    /**
353
     * Gets the accepted language from the user agent.
354
     *
355
     * $_SERVER['HTTP_ACCEPT_LANGUAGE'] could be like the text below:
356
     * it,pt-br;q=0.8,en-us;q=0.5,en;q=0.3
357
     */
358
    private function getUserAgentLanguage()
359
    {
360
        $matches = $languages = [];
361
362
        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
363
            // ISO Language Codes, 2-letters: ISO 639-1, <Country tag>[-<Country subtag>]
364
            // Simplified language syntax detection: xx[-yy]
365
            preg_match_all(
366
                '/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
367
                $_SERVER['HTTP_ACCEPT_LANGUAGE'],
368
                $matches
369
            );
370
371
            if (count($matches[1])) {
372
                $languages = array_combine($matches[1], $matches[4]);
373
                foreach ($languages as $lang => $val) {
374
                    if ($val === '') {
375
                        $languages[$lang] = 1;
376
                    }
377
                }
378
                arsort($languages, SORT_NUMERIC);
379
            }
380
            foreach ($languages as $lang => $val) {
381
                if (self::isASupportedLanguage(strtoupper($lang))) {
382
                    $this->acceptedLanguage = $lang;
383
                    break;
384
                }
385
            }
386
        }
387
    }
388
}
389