Passed
Push — master ( 202a73...bb5081 )
by Fabio
06:38
created

TGlobalization::setDefaultCharset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
rs 10
ccs 0
cts 0
cp 0
crap 2
1
<?php
2
/**
3
 * TGlobalization class file.
4
 *
5
 * @author Wei Zhuo<weizhuo[at]gmail[dot]com>
6
 * @link https://github.com/pradosoft/prado
7
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
8
 * @package Prado\I18N
9
 */
10
11
namespace Prado\I18N;
12
13
use Prado\Exceptions\TConfigurationException;
14
use Prado\Prado;
15
use Prado\TApplication;
16
use Prado\TPropertyValue;
17
18
/**
19
 * TGlobalization contains settings for Culture, Charset
20
 * and TranslationConfiguration.
21
 *
22
 * TGlobalization can be subclassed to change how the Culture, Charset
23
 * are determined. See TGlobalizationAutoDetect for example of
24
 * setting the Culture based on browser settings.
25
 *
26
 * @author Wei Zhuo<weizhuo[at]gmail[dot]com>
27
 * @package Prado\I18N
28
 * @since 3.0
29
 */
30
class TGlobalization extends \Prado\TModule
31
{
32
	/**
33
	 * Default character set is 'UTF-8'.
34
	 * @var string
35
	 */
36
	private $_defaultCharset = 'UTF-8';
37
38
	/**
39
	 * Default culture is 'en'.
40
	 * @var string
41
	 */
42
	private $_defaultCulture = 'en';
43
44
	/**
45
	 * The current charset.
46
	 * @var string
47
	 */
48
	private $_charset;
49
50
	/**
51
	 * The current culture.
52
	 * @var string
53
	 */
54
	private $_culture;
55
56
	/**
57
	 * Translation source parameters.
58
	 * @var \Prado\Collections\TMap
59
	 */
60
	private $_translation;
61
62
	/**
63
	 * @var bool whether we should translate the default culture
64
	 */
65
	private $_translateDefaultCulture = true;
66
	
67
	/**
68
	 * @var bool whether the current culture is Right to Left.
69
	 */
70
	private $_cultureRTL;
71
72
	/**
73
	 * Initialize the Culture and Charset for this application.
74
	 * You should override this method if you want a different way of
75
	 * setting the Culture and/or Charset for your application.
76
	 * If you override this method, call parent::init($xml) first.
77
	 * @param mixed $config application configuration
78
	 */
79
	public function init($config)
80
	{
81
		if ($this->_charset === null) {
82
			$this->_charset = $this->getDefaultCharset();
83
		}
84
		if ($this->_culture === null) {
85
			$this->_culture = $this->getDefaultCulture();
86
		}
87
88
		if ($config !== null) {
89
			if ($this->getApplication()->getConfigurationType() == TApplication::CONFIG_TYPE_PHP) {
90
				$translation = $config['translate'] ?? null;
91
			} else {
92
				$t = $config->getElementByTagName('translation');
93
				$translation = ($t) ? $t->getAttributes() : null;
94
			}
95
			if ($translation) {
96
				$this->setTranslationConfiguration($translation);
97
			}
98
		}
99
		$this->getApplication()->setGlobalization($this);
100
	}
101
102
	/**
103
	 * @return string default culture
104
	 */
105
	public function getTranslateDefaultCulture()
106
	{
107
		return $this->_translateDefaultCulture;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_translateDefaultCulture returns the type boolean which is incompatible with the documented return type string.
Loading history...
108
	}
109
110
	/**
111
	 * @param bool $value default culture, e.g. <tt>en_US</tt> for American English
112
	 */
113
	public function setTranslateDefaultCulture($value)
114
	{
115
		$this->_translateDefaultCulture = TPropertyValue::ensureBoolean($value);
116
	}
117
118
	/**
119
	 * @return string default culture
120
	 */
121
	public function getDefaultCulture()
122
	{
123
		return $this->_defaultCulture;
124
	}
125
126
	/**
127
	 * @param string $culture default culture, e.g. <tt>en_US</tt> for American English
128
	 */
129
	public function setDefaultCulture($culture)
130
	{
131
		$this->_defaultCulture = str_replace('-', '_', $culture);
132
	}
133
134
	/**
135
	 * @return string default charset set
136
	 */
137
	public function getDefaultCharset()
138
	{
139
		return $this->_defaultCharset;
140
	}
141
142
	/**
143
	 * @param string $charset default localization charset, e.g. <tt>UTF-8</tt>
144
	 */
145
	public function setDefaultCharset($charset)
146
	{
147
		$this->_defaultCharset = $charset;
148
	}
149
150
	/**
151
	 * @return string current application culture
152
	 */
153
	public function getCulture()
154
	{
155
		return $this->_culture;
156
	}
157
158
	/**
159
	 * @param string $culture culture, e.g. <tt>en_US</tt> for American English
160
	 */
161
	public function setCulture($culture)
162
	{
163
		if (($culture = str_replace('-', '_', $culture)) != $this->_culture) {
164
			$this->_culture = $culture;
165
			$this->_cultureRTL = null;
166
		}
167
	}
168
169
	/**
170
	 * @return string localization charset
171
	 */
172
	public function getCharset()
173
	{
174
		return $this->_charset;
175
	}
176
177
	/**
178
	 * @param string $charset localization charset, e.g. <tt>UTF-8</tt>
179
	 */
180
	public function setCharset($charset)
181
	{
182
		$this->_charset = $charset;
183
	}
184
185
	/**
186
	 * @return null|\Prado\Collections\TMap translation source configuration.
187
	 */
188
	public function getTranslationConfiguration()
189
	{
190
		return (!$this->_translateDefaultCulture && ($this->getDefaultCulture() == $this->getCulture()))
191
			? null
192
			: $this->_translation;
193
	}
194
195
	/**
196
	 * Sets the translation configuration. Example configuration:
197
	 * <code>
198
	 * $config['type'] = 'XLIFF'; //XLIFF, gettext, PHP or Database
199
	 * $config['source'] = 'Path\to\directory'; // for types XLIFF, PHP and gettext
200
	 * $config['source'] = 'connectionId'; // for type Database
201
	 * $config['catalogue'] = 'messages'; //default catalog
202
	 * $config['autosave'] = 'true'; //save untranslated message
203
	 * $config['cache'] = 'true'; //cache translated message
204
	 * $config['marker'] = '@@'; // surround untranslated text with '@@'
205
	 * </code>
206
	 * Throws exception is source is not found.
207
	 * @param array|\Prado\Collections\TMap $config configuration options
208
	 */
209
	protected function setTranslationConfiguration($config)
210
	{
211
		if ($config['type'] == 'XLIFF' || $config['type'] == 'gettext' || $config['type'] == 'PHP') {
212
			if ($config['source']) {
213
				$config['source'] = Prado::getPathOfNamespace($config['source']);
214
				if (!is_dir($config['source'])) {
0 ignored issues
show
Bug introduced by
It seems like $config['source'] can also be of type null; however, parameter $filename of is_dir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

214
				if (!is_dir(/** @scrutinizer ignore-type */ $config['source'])) {
Loading history...
215
					if (@mkdir($config['source']) === false) {
0 ignored issues
show
Bug introduced by
It seems like $config['source'] can also be of type null; however, parameter $directory of mkdir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

215
					if (@mkdir(/** @scrutinizer ignore-type */ $config['source']) === false) {
Loading history...
216
						throw new TConfigurationException(
217
							'globalization_source_path_failed',
218
							$config['source']
219
						);
220
					}
221
					chmod($config['source'], Prado::getDefaultPermissions()); //make it deletable
0 ignored issues
show
Bug introduced by
It seems like $config['source'] can also be of type null; however, parameter $filename of chmod() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

221
					chmod(/** @scrutinizer ignore-type */ $config['source'], Prado::getDefaultPermissions()); //make it deletable
Loading history...
222
				}
223
			} else {
224
				throw new TConfigurationException("invalid source dir '{$config['source']}'");
225
			}
226
		}
227
		if (isset($config['cache']) && TPropertyValue::ensureBoolean($config['cache'])) {
228
			$config['cache'] = $this->getApplication()->getRunTimePath() . '/i18n';
229
			if (!is_dir($config['cache'])) {
230
				if (@mkdir($config['cache']) === false) {
231
					throw new TConfigurationException(
232
						'globalization_cache_path_failed',
233
						$config['cache']
234
					);
235
				}
236
				chmod($config['cache'], Prado::getDefaultPermissions()); //make it deletable
237
			}
238
		} else {
239
			unset($config['cache']);
240
		}
241
		$this->_translation = $config;
242
	}
243
244
	/**
245
	 * @return string current translation catalogue.
246
	 */
247
	public function getTranslationCatalogue()
248
	{
249
		return $this->_translation['catalogue'];
250
	}
251
252
	/**
253
	 * @param string $value update the translation catalogue.
254
	 */
255
	public function setTranslationCatalogue($value)
256
	{
257
		$this->_translation['catalogue'] = $value;
258
	}
259
260
	/**
261
	 * Gets all the variants of a specific culture. If the parameter
262
	 * $culture is null, the current culture is used.
263
	 * @param string $culture the Culture string
264
	 * @return array variants of the culture.
265
	 */
266
	public function getCultureVariants($culture = null)
267
	{
268
		if ($culture === null) {
269
			$culture = $this->getCulture();
270
		}
271
		$variants = explode('_', $culture);
272
		$result = [];
273
		for (; count($variants) > 0; array_pop($variants)) {
274
			$result[] = implode('_', $variants);
275
		}
276
		return $result;
277
	}
278
279
	/**
280
	 * Returns a list of possible localized files. Example
281
	 * <code>
282
	 * $files = $app->getLocalizedResource("path/to/Home.page","en_US");
283
	 * </code>
284
	 * will return
285
	 * <pre>
286
	 * array
287
	 *   0 => 'path/to/en_US/Home.page'
288
	 *   1 => 'path/to/en/Home.page'
289
	 *   2 => 'path/to/Home.en_US.page'
290
	 *   3 => 'path/to/Home.en.page'
291
	 *   4 => 'path/to/Home.page'
292
	 * </pre>
293
	 * Note that you still need to verify the existance of these files.
294
	 * @param string $file filename
295
	 * @param string $culture culture string, null to use current culture
296
	 * @return array list of possible localized resource files.
297
	 */
298
	public function getLocalizedResource($file, $culture = null)
299
	{
300
		$files = [];
301
		$variants = $this->getCultureVariants($culture);
302
		$path = pathinfo($file);
303
		foreach ($variants as $variant) {
304
			$files[] = $path['dirname'] . DIRECTORY_SEPARATOR . $variant . DIRECTORY_SEPARATOR . $path['basename'];
305
		}
306
		$filename = substr($path['basename'], 0, strrpos($path['basename'], '.'));
307
		foreach ($variants as $variant) {
308
			$files[] = $path['dirname'] . DIRECTORY_SEPARATOR . $filename . '.' . $variant . '.' . $path['extension'];
309
		}
310
		$files[] = $file;
311
		return $files;
312
	}
313
	
314
	/**
315
	 * This returns whether or not the current culture or the specified
316
	 * culture is right to left orientation.  Default $culture is null, which
317
	 * equal to using $this->Culture as the parameter.
318
	 * @param null|string $culture, default null which makes this grab the current object culture
319
	 * @return bool whether or not the specifeid or current culture is right to left
320
	 * @since 4.2.0
321
	 */
322
	public function getIsCultureRTL($culture = null)
323
	{
324
		$currentCulture = $this->getCulture();
325
		
326
		if (($culture === null || $culture == $currentCulture) && $this->_cultureRTL !== null) {
327
			return $this->_cultureRTL;
328
		}
329
		if ($culture === null) {
330
			$culture = $currentCulture;
331
		}
332
		$ci = new \Prado\I18N\core\CultureInfo($culture);
333
		$textDirection = $ci->findInfo('layout/characters');
334
		$isRTL = ($textDirection == 'right-to-left');
335
		if ($culture == $currentCulture) {
336
			$this->_cultureRTL = $isRTL;
337
		}
338
		return $isRTL;
339
	}
340
	
341
	/**
342
	 * This hard sets the IsCultureRTL property to the value.
343
	 * @param bool $rtl whether or not the culture is right to left
344
	 * @since 4.2.0
345
	 */
346
	public function setIsCultureRTL($rtl)
347
	{
348
		$this->_cultureRTL = TPropertyValue::ensureBoolean($rtl);
349
	}
350
}
351