Completed
Push — master ( 0a999d...b4b35b )
by Peter
13:24 queued 02:45
created

I18NAbleTrait   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 90%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 3
dl 0
loc 190
ccs 45
cts 50
cp 0.9
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A _changeAttributesLang() 0 19 4
A getLang() 0 4 2
A getLanguages() 0 4 1
A setLanguages() 0 11 2
A setRawI18N() 0 4 1
A getDefaultLanguage() 0 4 2
A setDefaultLanguage() 0 4 1
A getRawI18N() 0 13 2
A setLang() 0 21 4
1
<?php
2
3
/**
4
 * This software package is licensed under AGPL or Commercial license.
5
 *
6
 * @package maslosoft/mangan
7
 * @licence AGPL or Commercial
8
 * @copyright Copyright (c) Piotr Masełkowski <[email protected]>
9
 * @copyright Copyright (c) Maslosoft
10
 * @copyright Copyright (c) Others as mentioned in code
11
 * @link https://maslosoft.com/mangan/
12
 */
13
14
namespace Maslosoft\Mangan\Traits;
15
16
use Maslosoft\Mangan\Events\Event;
17
use Maslosoft\Mangan\Events\ModelEvent;
18
use Maslosoft\Mangan\Interfaces\InternationalInterface;
19
use Maslosoft\Mangan\Meta\ManganMeta;
20
21
/**
22
 * I18N-able trait contains basic implementation of I18N feature. This covers
23
 * methods from `InternationalInterface`.
24
 *
25
 * Use this trait to provide internationalized columns for models.
26
 *
27
 * @see InternationalInterface
28
 * @author Piotr Maselkowski <pmaselkowski at gmail.com>
29
 */
30
trait I18NAbleTrait
31
{
32
33
	private $_lang = 'en';
34
	private $_rawI18N = [];
35
	private $_languages = ['en'];
36
	private $_defaultLanguage = 'en';
37
38
	/**
39
	 * Get language code
40
	 * @return string Language code
41
	 * @Ignored
42
	 */
43 14
	public function getLang()
44
	{
45 14
		return $this->_lang? : $this->getDefaultLanguage();
46
	}
47
48
	/**
49
	 *
50
	 * @return string[]
51
	 * @Ignored
52
	 */
53 61
	public function getLanguages()
54
	{
55 61
		return $this->_languages;
56
	}
57
58
	/**
59
	 * Get i18n values with all languages.
60
	 * This returns all language values of all class fields. Class field names are
61
	 * keys for arrays of language values, with language codes as a keys.
62
	 *
63
	 * Example returned variable:
64
	 * ```php
65
	 * [
66
	 * 		'name' => [
67
	 * 			'en' => 'January',
68
	 * 			'pl' => 'Styczeń'
69
	 * 		],
70
	 * 		'description' => [
71
	 * 			'en' => 'First mothn of a year'
72
	 * 			'pl' => 'Pierwszy miesiąc roku'
73
	 * 		]
74
	 * ]
75
	 * ```
76
	 * @return mixed[] Associative array of language values
77
	 * @Ignored
78
	 */
79 14
	public function getRawI18N()
80
	{
81 14
		$meta = ManganMeta::create($this);
82 14
		$fields = $meta->properties('i18n');
83
84
		// Set current model value for current language for each property
85 14
		foreach ($fields as $name => $i18n)
86
		{
87
			// This is to keep rawi18n value in sync with current model value.
88 14
			$this->_rawI18N[$name][$this->getLang()] = $this->$name;
89
		}
90 14
		return $this->_rawI18N;
91
	}
92
93
	/**
94
	 * Set language code. This changes current model language.
95
	 * After setting language model attributes will store values in different locale.
96
	 *
97
	 * Language code must be previously set by `setLanguages`.
98
	 * When trying to set undefined language code, method will do nothing.
99
	 * When setting already choosen language code, method will also ignore this call.
100
	 * Example method calls:
101
	 * ```php
102
	 * // Set available languages
103
	 * $model->setLanguages(['en', 'pl']);
104
	 *
105
	 * // Will ignore as en is by default
106
	 * $model->setLang('en');
107
	 *
108
	 * // Will set pl as language
109
	 * $model->setLang('pl');
110
	 *
111
	 * // Will ignore as ru is not available
112
	 * $model->setLang('ru')
113
	 * ```
114
	 * @param string $code
115
	 * @Ignored
116
	 */
117 62
	public function setLang($code)
118
	{
119 62
		if ($this->_lang === $code)
120
		{
121 7
			return false;
122
		}
123 61
		if (!in_array($code, $this->getLanguages()))
124
		{
125 60
			$this->_languages[] = $code;
126
		}
127 61
		$event = new ModelEvent($this);
128 61
		$event->data = $code;
129 61
		if (!Event::valid($this, InternationalInterface::EventBeforeLangChange, $event))
130
		{
131
			return false;
132
		}
133 61
		$this->_changeAttributesLang($this->_lang, $code);
134 61
		$this->_lang = $code;
135 61
		Event::trigger($this, InternationalInterface::EventAfterLangChange, $event);
136 61
		return true;
137
	}
138
139
	/**
140
	 * Set available languages. This method accepts one parameter,
141
	 * array contaning language codes prefably in short ISO form.
142
	 * Example valid array and method calls:
143
	 * ```php
144
	 * $languages = ['en', 'pl', 'ru'];
145
	 * $model->setLanguages($languages);
146
	 * $model2->setLanguages(['en']);
147
	 * ```
148
	 * @param string[] $languages
149
	 * @Ignored
150
	 */
151 7
	public function setLanguages($languages)
152
	{
153 7
		$event = new ModelEvent($this);
154 7
		$event->data = $languages;
155 7
		if (!Event::valid($this, InternationalInterface::EventBeforeLanguagesSet, $event))
156
		{
157
			return;
158
		}
159 7
		$this->_languages = $languages;
160 7
		Event::trigger($this, InternationalInterface::EventAfterLanguagesSet, $event);
161 7
	}
162
163
	/**
164
	 * Set i18n values in all languages.
165
	 * This method must keep `$values` for further use, by method `getRawI18N`.
166
	 * @param mixed[] $values
167
	 * @Ignored
168
	 */
169 7
	public function setRawI18N($values)
170
	{
171 7
		$this->_rawI18N = $values;
172 7
	}
173
174
	/**
175
	 *
176
	 * @return string
177
	 * @Ignored
178
	 */
179 2
	public function getDefaultLanguage()
180
	{
181 2
		return $this->_defaultLanguage? : 'en';
182
	}
183
184
	/**
185
	 *
186
	 * @param string $language
187
	 * @Ignored
188
	 */
189
	public function setDefaultLanguage($language)
190
	{
191
		$this->_defaultLanguage = $language;
192
	}
193
194
	/**
195
	 * Change i18n attributes values to apropriate language
196
	 * @param string $fromCode
197
	 * @param string $toCode
198
	 */
199 61
	private function _changeAttributesLang($fromCode, $toCode)
200
	{
201 61
		$meta = ManganMeta::create($this);
202 61
		$fields = $meta->properties('i18n');
203 61
		foreach ($fields as $name => $i18n)
204
		{
205 9
			$current = $this->$name;
206 9
			if (isset($this->_rawI18N[$name]) && array_key_exists($toCode, $this->_rawI18N[$name]))
207
			{
208 5
				$new = $this->_rawI18N[$name][$toCode];
209
			}
210
			else
211
			{
212 9
				$new = $meta->$name->default;
213
			}
214 9
			$this->_rawI18N[$name][$fromCode] = $current;
215 9
			$this->$name = $new;
216
		}
217 61
	}
218
219
}
220