Passed
Pull Request — master (#117)
by Spuds
07:11
created

Lang   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 198
Duplicated Lines 0 %

Test Coverage

Coverage 98.11%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 47
c 2
b 0
f 0
dl 0
loc 198
ccs 52
cts 53
cp 0.9811
rs 10
wmc 24

8 Methods

Rating   Name   Duplication   Size   Complexity  
A findLanguage() 0 21 5
A set() 0 18 3
A loadLang() 0 28 4
A get() 0 17 4
A detect_browser_language() 0 30 5
A has() 0 3 1
A getAll() 0 3 1
A __get() 0 3 1
1
<?php
2
/**
3
 * @name      OpenImporter
4
 * @copyright OpenImporter contributors
5
 * @license   BSD https://opensource.org/licenses/BSD-3-Clause
6
 *
7
 * @version 1.0
8
 */
9
10
namespace OpenImporter;
11
12
/**
13
 * Class Lang
14
 * loads the appropriate language file(s) if they exist.
15
 *
16
 * The default import_en.xml file contains the English strings used by the importer.
17
 *
18
 * @package OpenImporter
19
 */
20
class Lang
21
{
22
	/** @var array */
23
	protected $_lang = array();
24
25
	/**
26
	 * Loads the language xml file.
27
	 *
28
	 * @return null
29
	 * @throws \Exception if it cannot find the XML file.
30
	 * @throws ImportException if the XML file has got a corrupted structure.
31
	 */
32 3
	public function loadLang($path)
33
	{
34
		// Detect the browser language
35 3
		$language = $this->detect_browser_language();
36 3
		$language_file = $this->findLanguage($path, $language);
37
38
		// Ouch, we really should never arrive here.
39 3
		if (!$language_file)
40
		{
41 1
			throw new \Exception('Unable to detect language file!');
42
		}
43
44
		// Silence simplexml errors because we take care of them by ourselves
45 2
		libxml_use_internal_errors(true);
46
47
		// Import the xml language
48 2
		if (!$langObj = simplexml_load_file($language_file, 'SimpleXMLElement', LIBXML_NOCDATA))
49
		{
50 1
			throw new ImportException('XML-Syntax error in file: ' . $language_file);
51
		}
52
53
		// Set them for use
54 1
		foreach ($langObj as $strings)
55
		{
56 1
			$this->set((string) $strings->attributes()->{'name'}, (string) $strings);
0 ignored issues
show
Bug introduced by
The method attributes() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

56
			$this->set((string) $strings->/** @scrutinizer ignore-call */ attributes()->{'name'}, (string) $strings);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
57
		}
58
59 1
		return null;
60
	}
61
62
	/**
63
	 * This is used to detect the Client's browser language.
64
	 *
65
	 * @return string[] the shortened string of the browser's language.
66
	 */
67 3
	protected function detect_browser_language()
68
	{
69 3
		$preferred = array();
70
71 3
		if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
72
		{
73
			// Break up string into pieces (languages and q factors)
74
			// the string looks like: en-GB,en;q=0.9,it;q=0.8
75 3
			preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']), $lang_parse);
76
77 3
			if (count($lang_parse[1]))
78
			{
79
				// Create a list like "en" => 0.8
80 3
				$preferred = array_combine($lang_parse[1], $lang_parse[4]);
81
82
				// Set default to 1 for any without q factor (IE fix)
83 3
				foreach ($preferred as $lang => $val)
84
				{
85 3
					if ($val === '')
86
					{
87 2
						$preferred[$lang] = 1;
88
					}
89
				}
90
91
				// Sort list based on value
92 3
				arsort($preferred, SORT_NUMERIC);
93
			}
94
		}
95
96 3
		return array_keys($preferred);
97
	}
98
99
	/**
100
	 * Finds the best language file to use, falls back to english
101
	 *
102
	 * @param string $path
103
	 * @param string[] $language
104
	 *
105
	 * @return bool|string
106
	 */
107 4
	protected function findLanguage($path, $language)
108
	{
109 4
		$language_file = false;
110
111
		// Loop through the preferred languages and try to find the related language file
112 4
		foreach ($language as $key)
113
		{
114 4
			if (file_exists($path . '/import_' . $key . '.xml'))
115
			{
116 3
				$language_file = $path . '/import_' . $key . '.xml';
117 3
				break;
118
			}
119
		}
120
121
		// English is still better than nothing
122 4
		if (empty($language_file) && file_exists($path . '/import_en.xml'))
123
		{
124 1
			$language_file = $path . '/import_en.xml';
125
		}
126
127 4
		return $language_file;
128
	}
129
130
	/**
131
	 * Adds a new variable to lang.
132
	 *
133
	 * @param string $key Name of the variable
134
	 * @param string $value Value of the variable
135
	 *
136
	 * @return boolean|null
137
	 * @throws \Exception
138
	 */
139 4
	protected function set($key, $value)
140
	{
141
		try
142
		{
143
			// No duplicates, we only use the first set
144 4
			if ($this->has($key))
145
			{
146 1
				throw new \Exception('Unable to set language string for <em>' . $key . '</em>. It was already set.');
147
			}
148
149 4
			$this->_lang[$key] = $value;
150
151 4
			return true;
152
		}
153 1
		catch (\Exception $e)
154
		{
155
			// @todo this should not be a fatal error
156 1
			ImportException::exception_handler($e);
157
		}
158
	}
159
160
	/**
161
	 * Tests if given $key exists in lang
162
	 *
163
	 * @param string $key
164
	 *
165
	 * @return bool
166
	 */
167 2
	public function has($key)
168
	{
169 2
		return isset($this->_lang[(string) $key]);
170
	}
171
172
	/**
173
	 * Returns a key via magic method
174
	 *
175
	 * @param string $key
176
	 *
177
	 * @return null|string
178
	 */
179 1
	public function __get($key)
180
	{
181 1
		return $this->get($key);
182
	}
183
184
	/**
185
	 * Returns the value of the specified $key in lang.
186
	 *
187
	 * @param string|string[] $key Name of the variable
188
	 *
189
	 * @return string|null Value of the specified $key
190
	 */
191 1
	public function get($key)
192
	{
193 1
		if (is_array($key))
194
		{
195 1
			$l_key = array_shift($key);
196
197 1
			if ($this->has($l_key))
198
			{
199 1
				return vsprintf($this->_lang[$l_key], $key);
200
			}
201
		}
202 1
		elseif ($this->has($key))
203
		{
204 1
			return $this->_lang[$key];
205
		}
206
207 1
		return (string) $key;
208
	}
209
210
	/**
211
	 * Returns the whole lang as an array.
212
	 *
213
	 * @return array Whole lang
214
	 */
215 1
	public function getAll()
216
	{
217 1
		return $this->_lang;
218
	}
219
}
220