Failed Conditions
Pull Request — master (#233)
by
unknown
02:30
created

locales.loader.php ➔ negotiateLanguage()   C

Complexity

Conditions 8
Paths 24

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 18
nc 24
nop 2
dl 0
loc 28
rs 5.3846
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 32 and the first side effect is on line 121.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
/**
4
 * The next 3 functions come from the HTTP2 pear package 
5
 * Copyright (c) 2002-2005, 
6
 * Stig Bakken <[email protected]>,
7
 * Sterling Hughes <[email protected]>,
8
 * Tomas V.V.Cox <[email protected]>,
9
 * Richard Heyes <[email protected]>,
10
 * Philippe Jausions <[email protected]>,
11
 * Michael Wallner <[email protected]>.
12
 * Licensed under http://www.opensource.org/licenses/bsd-license.php  New BSD License
13
 */
14
15
/**
16
 * Negotiates language with the user's browser through the Accept-Language
17
 * HTTP header or the user's host address.  Language codes are generally in
18
 * the form "ll" for a language spoken in only one country, or "ll-CC" for a
19
 * language spoken in a particular country.  For example, U.S. English is
20
 * "en-US", while British English is "en-UK".  Portugese as spoken in
21
 * Portugal is "pt-PT", while Brazilian Portugese is "pt-BR".
22
 *
23
 * Quality factors in the Accept-Language: header are supported, e.g.:
24
 *      Accept-Language: en-UK;q=0.7, en-US;q=0.6, no, dk;q=0.8
25
 *
26
 * @param array  $supported An associative array of supported languages,
27
 *                          whose values must evaluate to true.
28
 * @param string $default   The default language to use if none is found.
29
 *
30
 * @return string The negotiated language result or the supplied default.
31
 */
32
function negotiateLanguage($supported, $default = 'en-US')
0 ignored issues
show
Coding Style introduced by
negotiateLanguage uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
33
{
34
	$supp = array();
35
	foreach ($supported as $lang => $isSupported) {
36
		if ($isSupported) {
37
			$supp[strtolower($lang)] = $lang;
38
		}
39
	}
40
	if (!count($supp)) {
41
		return $default;
42
	}
43
	if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
44
		$match = matchAccept(
45
			$_SERVER['HTTP_ACCEPT_LANGUAGE'],
46
			$supp
47
		);
48
		if (!is_null($match)) {
49
			return $match;
50
		}
51
	}
52
	if (isset($_SERVER['REMOTE_HOST'])) {
53
		$lang = strtolower(end($h = explode('.', $_SERVER['REMOTE_HOST'])));
0 ignored issues
show
Bug introduced by
$h = explode('.', $_SERVER['REMOTE_HOST']) cannot be passed to end() as the parameter $array expects a reference.
Loading history...
54
		if (isset($supp[$lang])) {
55
			return $supp[$lang];
56
		}
57
	}
58
	return $default;
59
}
60
61
/**
62
 * Parses a weighed "Accept" HTTP header and matches it against a list
63
 * of supported options
64
 *
65
 * @param string $header    The HTTP "Accept" header to parse
66
 * @param array  $supported A list of supported values
67
 *
68
 * @return string|NULL a matched option, or NULL if no match
69
 */
70
function matchAccept($header, $supported)
71
{
72
	$matches = sortAccept($header);
73
	foreach ($matches as $key => $q) {
74
		if (isset($supported[$key])) {
75
			return $supported[$key];
76
		}
77
	}
78
	// If any (i.e. "*") is acceptable, return the first supported format
79
	if (isset($matches['*'])) {
80
		return array_shift($supported);
81
	}
82
	return null;
83
}
84
85
/**
86
 * Parses and sorts a weighed "Accept" HTTP header
87
 *
88
 * @param string $header The HTTP "Accept" header to parse
89
 *
90
 * @return array Sorted list of "accept" options
91
 */
92
function sortAccept($header)
93
{
94
	$matches = array();
95
	foreach (explode(',', $header) as $option) {
96
		$option = array_map('trim', explode(';', $option));
97
		$l = strtolower($option[0]);
98
		if (isset($option[1])) {
99
			$q = (float) str_replace('q=', '', $option[1]);
100
		} else {
101
			$q = null;
102
			// Assign default low weight for generic values
103
			if ($l == '*/*') {
104
				$q = 0.01;
105
			} elseif (substr($l, -1) == '*') {
106
				$q = 0.02;
107
			}
108
		}
109
		// Unweighted values, get high weight by their position in the
110
		// list
111
		$matches[$l] = isset($q) ? $q : 1000 - count($matches);
112
	}
113
	arsort($matches, SORT_NUMERIC);
114
	return $matches;
115
}
116
117
// Language setting
118
###################
119
120
if (empty($config->system->forced_lang)) {
121
	$directories = glob(SYS_PATH.'/core/json/locales/*' , GLOB_ONLYDIR);
0 ignored issues
show
Coding Style introduced by
Space found before comma in function call
Loading history...
122
	$directories = array_map("basename", $directories);
123
	//print_r($directories);
124
	$browser_lang = negotiateLanguage(array_fill_keys($directories, true), $config->system->default_lang);
125
	//print_r($browser_lang);
126
} else {
127
	// Use forced language
128
	$browser_lang = $config->system->forced_lang;
129
}
130
131
// Activate lang
132
$locale_dir = SYS_PATH.'/core/json/locales/'.strtoupper($browser_lang);
133
// Allow partial translations
134
$translation_file = "{}";
135
$pokemon_file = "{}";
136
if (is_file($locale_dir.'/pokes.json')) {
137
	$pokemon_file		= file_get_contents($locale_dir.'/pokes.json');
138
}
139
if (is_file($locale_dir.'/translations.json')) {
140
	$translation_file	= file_get_contents($locale_dir.'/translations.json');
141
}
142
if (is_file($locale_dir.'/moves.json')) {
143
	$moves_file			= json_decode(file_get_contents($locale_dir.'/moves.json'));
144
} else {
145
	$moves_file			= json_decode(file_get_contents(SYS_PATH.'/core/json/locales/EN/moves.json'));
146
}
147
148
149
// Merge translation files
150
// missing translation --> use english
151
// same keys so translation will
152
// always overwrite english if available
153
########################################
154
155
$locales 		= (object) array_replace(json_decode(file_get_contents(SYS_PATH.'/core/json/locales/EN/translations.json'), true), json_decode($translation_file, true));
156
157
// Recursive replace because of multi level array
158
$pokemon_trans_array 	= array_replace_recursive(json_decode(file_get_contents(SYS_PATH.'/core/json/locales/EN/pokes.json'), true), json_decode($pokemon_file, true));
159
160
// convert associative array back to object array (recursive)
161
$pokemon_trans 		= json_decode(json_encode($pokemon_trans_array), false);
162
unset($pokemon_trans_array);
163
164
165
// Merge the pokedex, pokemon translation and rarity file into a new array 
166
##########################################################################
167
168
$pokedex_file 			= file_get_contents(SYS_PATH.'/core/json/pokedex.json');
169
$pokemons 			= json_decode($pokedex_file);
170
171
$pokedex_rarity_file 		= SYS_PATH.'/core/json/pokedex.rarity.json';
172
// initial create of pokedex.rarity.json if it doesn't exist
173
if (!is_file($pokedex_rarity_file)) {
174
	include_once(SYS_PATH.'/core/cron/pokedex.rarity.php');
175
}
176
$pokedex_rarity_file_content = file_get_contents($pokedex_rarity_file);
177
$pokemons_rarity = json_decode($pokedex_rarity_file_content);
178
179
foreach ($pokemons->pokemon as $pokeid => $pokemon) {
180
	// Merge name and description from translation files
181
	$pokemon->name 				= $pokemon_trans->pokemon->$pokeid->name;
182
	$pokemon->description 		= $pokemon_trans->pokemon->$pokeid->description;
183
184
	// Replace quick and charge move with translation
185
	$quick_move 				= $pokemon->quick_move;
186
	$pokemon->quick_move 		= $pokemon_trans->quick_moves->$quick_move;
187
	$charge_move 				= $pokemon->charge_move;
188
	$pokemon->charge_move 		= $pokemon_trans->charge_moves->$charge_move;
189
190
	// Replace types with translation
191
	foreach ($pokemon->types as &$type) {
192
		$type = $pokemon_trans->types->$type;
193
	}
194
	unset($type);
195
196
	// Resolve candy_id to candy_name
197
	if (isset($pokemon->candy_id)) {
198
		$candy_id 				= $pokemon->candy_id;
199
		$pokemon->candy_name	= $pokemon_trans->pokemon->$candy_id->name;
200
		unset($pokemon->candy_id);
201
	}
202
	// Convert move numbers to names
203
	$move = new stdClass();
204
	foreach ($moves_file as $move_id => $move_name) {
205
		if (isset($move_name)) {
206
			$move->$move_id = new stdClass();
207
			$move->$move_id->name = $move_name->name;
208
		}
209
	}
210
	
211
	// Calculate and add rarities to array
212
	$spawn_rate = $pokemons_rarity->$pokeid;
213
	$pokemon->spawn_rate = $spawn_rate;
214
	// >= 1          = Very common
215
	// 0.20 - 1      = Common
216
	// 0.01 - 0.20   = Rare
217
	// > 0  - 0.01   = Mythic
218
	// Unseen
219
	if ($spawn_rate >= 1) {
220
		$pokemon->rarity = $locales->VERYCOMMON;
221
	} elseif ($spawn_rate >= 0.20) {
222
		$pokemon->rarity = $locales->COMMON;
223
	} elseif ($spawn_rate >= 0.01) {
224
		$pokemon->rarity = $locales->RARE;
225
	} elseif ($spawn_rate > 0) {
226
		$pokemon->rarity = $locales->MYTHIC;
227
	} else {
228
		$pokemon->rarity = $locales->UNSEEN;
229
	}
230
}
231
232
// Translate typecolors array keys as well
233
$types_temp = new stdClass();
234
foreach ($pokemons->typecolors as $type => $color) {
235
	$type_trans = $pokemon_trans->types->$type;
236
	$types_temp->$type_trans = $color;
237
}
238
// Replace typecolors array with translated one
239
$pokemons->typecolors = $types_temp;
240
241
// unset unused variables to prevent issues with other php scripts
242
unset($directories);
243
unset($browser_lang);
244
unset($locale_dir);
245
unset($pokemon_file);
246
unset($translation_file);
247
unset($pokedex_file);
248
unset($moves_file);
249
unset($pokemon_trans);
250
unset($types_temp);
251
unset($type_trans);
252
unset($pokemons_rarity);
253
unset($quick_move);
254
unset($charge_move);
255
unset($candy_id);
256
unset($spawn_rate);
257