FileTranslator   A
last analyzed

Complexity

Total Complexity 31

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 7
Bugs 3 Features 1
Metric Value
wmc 31
c 7
b 3
f 1
lcom 1
cbo 3
dl 0
loc 257
rs 9.8

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A getPath() 0 6 3
A getMessageFile() 0 6 2
B getTranslation() 0 24 5
A retrieveMessages() 0 8 3
A getAllTranslationByLanguage() 0 7 2
A getTranslationsForLanguage() 0 7 2
A getTranslationsForKey() 0 12 4
A deleteTranslation() 0 15 3
A setTranslation() 0 7 1
A setTranslationsForLanguage() 0 7 1
A setTranslationsForKey() 0 7 2
A getLanguageList() 0 11 2
1
<?php
2
/*
3
 * Copyright (c) 2012-2015 Marc TEYSSIER
4
 * 
5
 * See the file LICENSE.txt for copying permission.
6
 */
7
namespace Mouf\Utils\I18n\Fine\Translator;
8
9
use Mouf\Validator\MoufValidatorResult;
10
11
use Mouf\Validator\MoufValidatorInterface;
12
13
use Mouf\MoufManager;
14
15
use Mouf\Utils\I18n\Fine\FineMessageLanguage;
16
17
use Mouf\Utils\I18n\Fine\LanguageDetectionInterface;
18
use Mouf\Utils\I18n\Fine\Common\Ui\EditTranslationHelperTrait;
19
use Mouf\Utils\I18n\Fine\TranslatorInterface;
20
use Mouf\Utils\I18n\Fine\Common\Ui\EditTranslationInterface;
21
22
/**
23
 * <p>Each file in this directory is a PHP file containing an array variable named $msg. The key is the code or message id, the value is translation.<br/>Example :</p><pre class="brush:php">$msg["home.title"] = "Hello world";<br />$msg["home.text"] = "News 1, news 2 and news 3";</pre>
24
 * 
25
 * @author Marc TEYSSIER
26
 */
27
class FileTranslator implements TranslatorInterface, EditTranslationInterface  {
28
	use EditTranslationHelperTrait;
29
	
30
	/**
31
	 * Message list
32
	 * 
33
	 * @var array
34
	 */
35
	private $msg = null;
36
	
37
	/**
38
	 * The path to the directory storing the translations.
39
	 * <p>The directory path should end with a "/".</p>
40
	 * <p>If the path start with / or c:/ is the real path of file, otherwise, this must be start without / to root path of application.</p>
41
	 * <p>Each file in this directory is a PHP file containing an array variable named $msg. The key is the code or message id, the value is translation.<br/>
42
	 * Example :
43
	 * </p>
44
	 * <pre class="brush:php">$msg["home.title"] = "Hello world";<br />
45
	 * $msg["home.text"] = "News 1, news 2 and news 3";</pre>
46
	 * 
47
	 * 
48
	 * @Property
49
	 * @var string
50
	 */
51
	private $i18nMessagePath = "resources/";
52
53
	/**
54
	 * Set the language detection
55
	 *
56
	 * @Property
57
	 * @var LanguageDetectionInterface
58
	 */
59
	private $languageDetection;
60
61
	/**
62
	 * Store the instance of language
63
	 * @var array<MessageFileLanguage
64
	 */
65
	private $messageFile = [];
66
	
67
	/**
68
	 * 
69
	 * @param string $i18nMessagePath The path to the directory storing the translations. <p>The directory path should end with a "/".</p><p>If the path start with / or c:/ is the real path of file, otherwise, this must be start without / to root path of application.</p><p>By default this is resources/</p>
70
	 * @param LanguageDetectionInterface $languageDetection LanguageDetectionInterface
71
	 */
72
	public function __construct($i18nMessagePath = "resources/", LanguageDetectionInterface $languageDetection) {
73
		$this->i18nMessagePath = $i18nMessagePath;
74
		$this->languageDetection = $languageDetection;
75
	}
76
	
77
	/**
78
	 * This function return the real path set in parameter.
79
	 * @return string
80
	 */
81
	private function getPath() {
82
		if(strpos($this->i18nMessagePath, '/') === 0 || strpos($this->i18nMessagePath, ':/') === 1) {
83
			return $this->i18nMessagePath;
84
		}
85
		return ROOT_PATH.$this->i18nMessagePath;
86
	}
87
	
88
	/**
89
	 * Return the instance of the MessageFileLanguage
90
	 * Each MessageFileLanguage is link to one language
91
	 * 
92
	 * @param string $language
93
	 * @return MessageFileLanguage
94
	 */
95
	private function getMessageFile($language) {
96
		if(!isset($this->messageFile[$language])) {
97
			$this->messageFile[$language] = new MessageFileLanguage($this->getPath(), $language);
98
		}
99
		return $this->messageFile[$language];
100
	}
101
	
102
	/**
103
	 * Retrieve the translation of code or message.
104
	 * Check in the $msg variable if the key exist to return the value. This function check all the custom file if the translation is not in the main message_[language].php
105
	 * If this message doesn't exist, it return a link to edit it.
106
	 * 
107
	 */
108
	public function getTranslation($message, array $parameters = [], LanguageDetectionInterface $languageDetectionInterface = null) {
109
		if(!$languageDetectionInterface) {
110
			$lang = $this->languageDetection->getLanguage();
111
		}
112
		else {
113
			$lang = $languageDetectionInterface->getLanguage();
114
		}
115
		//Load the main file
116
		if(!isset($this->msg[$lang])) {
117
			$this->retrieveMessages($lang);
118
		}
119
		if (isset($this->msg[$lang][$message])) {
120
			// build a replacement array with braces around the context keys
121
			$replace = array();
122
			foreach ($parameters as $key => $val) {
123
				$replace['{' . $key . '}'] = $val;
124
			}
125
			
126
			// interpolate replacement values into the message and return
127
			return strtr($this->msg[$lang][$message], $replace);
128
		}
129
		
130
		return null;
131
	}
132
	
133
	/**
134
	 * Retrieve array variable store in the language file.
135
	 * This function include the message resource by default and the language file if the language code is set.
136
	 * The file contain an array with translation, we retrieve it in a private array msg. 
137
	 * 
138
	 * @param string $language Language code
139
	 * @return boolean
140
	 */
141
	private function retrieveMessages($language) {
142
		$this->msg = array();
143
		if($language) {
144
			if (file_exists($this->getPath().'messages_'.$language.'.php')){
145
				$this->msg[$language] = require_once $this->getPath().'messages_'.$language.'.php';
146
			}
147
		}
148
	}
149
	
150
151
	/***************************/
152
	/****** Edition mode *******/
153
	/***************************/
154
155
	/**
156
	 * The list of all messages in all languages
157
	 * @var array<string, FineMessageLanguage>
158
	 */
159
	private $messages = array();
160
161
	public function getAllTranslationByLanguage() {
162
		$languages = $this->getLanguageList();
163
		foreach ($languages as $language) {
164
			$this->getTranslationsForLanguage($language);
165
		}
166
		return $this->messages;
167
	}
168
	
169
	/**
170
	 * Return a list of all message for a language.
171
	 * 
172
	 * @param string $language Language
173
	 * @return array<string, string> List with key value of translation
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
174
	 */
175
	public function getTranslationsForLanguage($language) {
176
		if (!isset($this->messages[$language])) {
177
			$messageLanguage = $this->getMessageFile($language);
178
			$this->messages[$language] = $messageLanguage->getAllMessages();
179
		}		
180
		return $this->messages[$language];
181
	}
182
183
	/**
184
	 * Return a list of all message for a key, by language.
185
	 *
186
	 * @param string $key Key of translation
187
	 * @return array<string, string> List with key value of translation
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
188
	 */
189
	public function getTranslationsForKey($key) {
190
		$this->getAllTranslationByLanguage();
191
		$translations = [];
192
		foreach ($this->messages as $language => $messages) {
193
			foreach ($messages as $messageKey => $message) {
194
				if($key == $messageKey) {
195
					$translations[$language] = $message;
196
				}
197
			}
198
		}
199
		return $translations;
200
	}
201
	
202
	/**
203
	 * Delete a translation for a language. If the language is not set or null, this function deletes the translation for all language.
204
	 * 
205
	 * @param string $key Key to remove
206
	 * @param string|null $language Language to remove key or null for all
207
	 */
208
	public function deleteTranslation($key, $language = null) {
209
		if($language === null) {
210
			$languages = $this->getLanguageList();
211
		}
212
		else {
213
			$languages = array($language);
214
		}
215
		foreach ($languages as $language) {
216
			$messageFile = $this->getMessageFile($language);
217
			$messageFile->deleteMessage($key);
218
			$messageFile->save();
219
			
220
			unset($this->messages[$language][$key]);
221
		}
222
	}
223
	
224
	/**
225
	 * Add or change a translation
226
	 * 
227
	 * @param string $key Key of translation
228
	 * @param string $value Message of translation
229
	 * @param string $language Language to add translation
230
	 */
231
	public function setTranslation($key, $value, $language) {
232
		$messageFile = $this->getMessageFile($language);
233
		$messageFile->setMessage($key, $value);
234
		$messageFile->save();
235
236
		$this->messages[$language][$key] = $value;
237
	}
238
	
239
	/**
240
	 * Add or change many translations in one time
241
	 * 
242
	 * @param array<string, string> $messages List with key value of translation 
243
	 * @param string $language Language to add translation
244
	 */
245
	public function setTranslationsForLanguage(array $messages, $language) {
246
		$messageFile = $this->getMessageFile($language);
247
		$messageFile->setMessages($messages);
248
		$messageFile->save();
249
250
		$this->messages[$language] = array_merge($this->messages[$language], $messages);
251
	}
252
253
	/**
254
	 * Add or change many translations in one time
255
	 *
256
	 * @param array<string, string> $messages List with key value of translation
257
	 * @param string $key Key to add translation
258
	 */
259
	public function setTranslationsForKey(array $messages, $key) {
260
		foreach ($messages as $language => $value) {
261
			$messageFile = $this->getMessageFile($language);
262
			$messageFile->setMessage($key, $value);
263
			$messageFile->save();
264
		}
265
	}
266
	
267
	/**
268
	 * Liste of all language supported
269
	 * 
270
	 * @return array<string>
271
	 */
272
	public function getLanguageList() {
273
		$files = glob($this->getPath().'messages_*.php');
274
		
275
		$startAt = strlen('messages_');
276
		$languages = array();
277
		foreach ($files as $file) {
278
			$base = basename($file);
279
			$languages[] = substr($base, $startAt, strrpos($base, '.php') - $startAt);
280
		}
281
		return $languages;
282
	}
283
}
284