Passed
Push — master ( 199d92...bf1436 )
by Spuds
39s
created

Lang::get()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 1
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
ccs 8
cts 8
cp 1
crap 4
1
<?php
2
/**
3
 * @name      OpenImporter
4
 * @copyright OpenImporter contributors
5
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
6
 *
7
 * @version 1.0 Alpha
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
	/**
23
	 * @var array
24
	 */
25
	protected $_lang = array();
26
27
	/**
28
	 * @var array
29
	 */
30
	protected $_ns = array();
31
32
	/**
33
	 * Adds a new variable to lang.
34
	 *
35
	 * @param string $key Name of the variable
36
	 * @param string $value Value of the variable
37
	 * @throws \Exception
38
	 * @return boolean|null
39
	 */
40 4
	protected function set($key, $value)
41
	{
42
		try
43
		{
44
			// No duplicates, we only use the first set
45 4
			if ($this->has($key))
46 1
				throw new \Exception('Unable to set language string for <em>' . $key . '</em>. It was already set.');
47
48 4
			$this->_lang[$key] = $value;
49
50 4
			return true;
51
		}
52 1
		catch(\Exception $e)
53
		{
54
			// @todo this should not be a fatal error
55 1
			ImportException::exception_handler($e);
56
		}
57
	}
58
59
	/**
60
	 * Loads the language xml file.
61
	 *
62
	 * @return null
63
	 * @throws \Exception if it cannot find the XML file.
64
	 * @throws ImportException if the XML file has got a corrupted structure.
65
	 */
66 3
	public function loadLang($path)
67
	{
68
		// Detect the browser language
69 3
		$language = $this->detect_browser_language();
70 3
		$language_file = $this->findLanguage($path, $language);
71
72
		// Ouch, we really should never arrive here..
73 3
		if (!$language_file)
74 1
			throw new \Exception('Unable to detect language file!');
75
76
		// Silence simplexml errors because we take care of them by ourselves
77 2
		libxml_use_internal_errors(true);
78
79
		// Import the xml language
80 2
		if (!$langObj = simplexml_load_file($language_file, 'SimpleXMLElement', LIBXML_NOCDATA))
81 1
			throw new ImportException('XML-Syntax error in file: ' . $language_file);
82
83
		// Set them for use
84 1
		foreach ($langObj as $strings)
85 1
			$this->set((string) $strings->attributes()->{'name'}, (string) $strings);
86
87 1
		return null;
88
	}
89
90
	/**
91
	 * Finds the best language file to use, falls back to english
92
	 *
93
	 * @param string $path
94
	 * @param string[] $language
95
	 *
96
	 * @return bool|string
97
	 */
98 4
	protected function findLanguage($path, $language)
99
	{
100 4
		$language_file = false;
101
102
		// Loop through the preferred languages and try to find the related language file
103 4
		foreach ($language as $key)
104
		{
105 4
			if (file_exists($path . '/import_' . $key . '.xml'))
106
			{
107 3
				$language_file = $path . '/import_' . $key . '.xml';
108 4
				break;
109
			}
110
		}
111
112
		// English is still better than nothing
113 4
		if (empty($language_file))
114
		{
115 2
			if (file_exists($path . '/import_en.xml'))
116 1
				$language_file = $path . '/import_en.xml';
117
		}
118
119 4
		return $language_file;
120
	}
121
122
	/**
123
	 * Tests if given $key exists in lang
124
	 *
125
	 * @param string $key
126
	 *
127
	 * @return bool
128
	 */
129 2
	public function has($key)
130
	{
131 2
		return isset($this->_lang[(string) $key]);
132
	}
133
134
	/**
135
	 * Returns a key via magic method
136
	 *
137
	 * @param string $key
138
	 *
139
	 * @return null|string
140
	 */
141 1
	public function __get($key)
142
	{
143 1
		return $this->get($key);
144
	}
145
146
	/**
147
	 * Returns the value of the specified $key in lang.
148
	 *
149
	 * @param string $key Name of the variable
150
	 *
151
	 * @return string|null Value of the specified $key
152
	 */
153 1
	public function get($key)
154
	{
155 1
		if (is_array($key))
156
		{
157 1
			$l_key = array_shift($key);
158
159 1
			if ($this->has($l_key))
160 1
				return vsprintf($this->_lang[$l_key], $key);
161
		}
162
		else
163
		{
164 1
			if ($this->has($key))
165 1
				return $this->_lang[$key];
166
		}
167
168 1
		return (string) $key;
169
	}
170
171
	/**
172
	 * Returns the whole lang as an array.
173
	 *
174
	 * @return array Whole lang
175
	 */
176 1
	public function getAll()
177
	{
178 1
		return $this->_lang;
179
	}
180
181
	/**
182
	 * This is used to detect the Client's browser language.
183
	 *
184
	 * @return string the shortened string of the browser's language.
185
	 */
186 3
	protected function detect_browser_language()
187
	{
188 3
		$preferred = array();
189
190 3
		if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
191
		{
192
			// Break up string into pieces (languages and q factors)
193
			// the string looks like: en-GB,en;q=0.9,it;q=0.8
194 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);
195
196 3
			if (count($lang_parse[1]))
197
			{
198
				// Create a list like "en" => 0.8
199 3
				$preferred = array_combine($lang_parse[1], $lang_parse[4]);
200
201
				// Set default to 1 for any without q factor (IE fix)
202 3
				foreach ($preferred as $lang => $val)
203
				{
204 3
					if ($val === '')
205 3
						$preferred[$lang] = 1;
206
				}
207
208
				// Sort list based on value
209 3
				arsort($preferred, SORT_NUMERIC);
210
			}
211
		}
212
213 3
		return array_keys($preferred);
214
	}
215
}