d55d2fe0
Yarik
Multilanguage
|
1
2
3
4
|
<?php
namespace common\modules\language\behaviors;
use common\modules\language\models\Language;
|
d55d2fe0
Yarik
Multilanguage
|
5
6
7
8
|
use yii\base\Behavior;
use yii\base\InvalidConfigException;
use yii\db\ActiveQuery;
use yii\db\ActiveRecord;
|
14cd7eed
Yarik
LanguageBehavior ...
|
9
|
use yii\db\Transaction;
|
d55d2fe0
Yarik
Multilanguage
|
10
11
12
13
|
use yii\web\Request;
/**
* Class LanguageBehavior
|
14cd7eed
Yarik
LanguageBehavior ...
|
14
15
16
|
* @property ActiveRecord $owner
* @property string $ownerKey
* @property string $langKey
|
d55d2fe0
Yarik
Multilanguage
|
17
|
* @property ActiveRecord[] $langs
|
14cd7eed
Yarik
LanguageBehavior ...
|
18
|
* @property ActiveRecord $lang
|
d55d2fe0
Yarik
Multilanguage
|
19
20
21
22
23
|
*/
class LanguageBehavior extends Behavior
{
/**
|
8af13427
Yarik
For leha commit.
|
24
|
* @var ActiveRecord $objectLang Empty language model for $owner
|
d55d2fe0
Yarik
Multilanguage
|
25
|
*/
|
8af13427
Yarik
For leha commit.
|
26
|
public $objectLang;
|
d55d2fe0
Yarik
Multilanguage
|
27
|
|
14cd7eed
Yarik
LanguageBehavior ...
|
28
|
/**
|
8af13427
Yarik
For leha commit.
|
29
|
* @var ActiveRecord[] $modelLangs
|
14cd7eed
Yarik
LanguageBehavior ...
|
30
|
*/
|
8af13427
Yarik
For leha commit.
|
31
|
public $modelLangs = [];
|
14cd7eed
Yarik
LanguageBehavior ...
|
32
|
|
8af13427
Yarik
For leha commit.
|
33
|
private $ownerKey;
|
d55d2fe0
Yarik
Multilanguage
|
34
|
|
8af13427
Yarik
For leha commit.
|
35
|
private $langKey;
|
d55d2fe0
Yarik
Multilanguage
|
36
37
|
/**
|
8af13427
Yarik
For leha commit.
|
38
|
* @var Transaction $transaction
|
14cd7eed
Yarik
LanguageBehavior ...
|
39
|
*/
|
8af13427
Yarik
For leha commit.
|
40
|
private $transaction;
|
14cd7eed
Yarik
LanguageBehavior ...
|
41
42
|
/**
|
8af13427
Yarik
For leha commit.
|
43
|
* @var bool $transactionStatus
|
14cd7eed
Yarik
LanguageBehavior ...
|
44
|
*/
|
8af13427
Yarik
For leha commit.
|
45
|
private $transactionStatus = false;
|
14cd7eed
Yarik
LanguageBehavior ...
|
46
47
48
49
50
51
52
53
54
55
56
57
|
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_INSERT => 'beforeSave',
ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeSave',
ActiveRecord::EVENT_AFTER_INSERT => 'afterSave',
ActiveRecord::EVENT_AFTER_UPDATE => 'afterSave',
];
}
/**
|
d55d2fe0
Yarik
Multilanguage
|
58
59
60
61
62
|
* Get $owner primary key to link language model
* @return string
*/
public function getOwnerKey():string
{
|
8af13427
Yarik
For leha commit.
|
63
64
|
if(!empty( $this->ownerKey )) {
return $this->ownerKey;
|
d55d2fe0
Yarik
Multilanguage
|
65
66
67
68
69
70
71
72
73
74
75
76
|
} else {
return $this->owner->primaryKey()[ 0 ];
}
}
/**
* Set which attribute to use as $owner primary key to link language model
*
* @param string $value
*/
public function setOwnerKey(string $value)
{
|
8af13427
Yarik
For leha commit.
|
77
|
$this->ownerKey = $value;
|
d55d2fe0
Yarik
Multilanguage
|
78
79
80
81
82
83
84
85
|
}
/**
* Get language model attribute that is used as foreign key to $owner
* @return string
*/
public function getLangKey():string
{
|
8af13427
Yarik
For leha commit.
|
86
87
|
if(!empty( $this->langKey )) {
return $this->langKey;
|
d55d2fe0
Yarik
Multilanguage
|
88
89
90
91
92
93
94
95
96
97
98
99
100
|
} else {
$owner = $this->owner;
return $owner::getTableSchema()->name . '_id';
}
}
/**
* Set which attribute to use as language model foreign key to $owner
*
* @param $value
*/
public function setLangKey(string $value)
{
|
8af13427
Yarik
For leha commit.
|
101
|
$this->langKey = $value;
|
d55d2fe0
Yarik
Multilanguage
|
102
103
104
105
106
107
108
109
110
111
112
|
}
/**
* Additional checks to attach this behavior
*
* @param ActiveRecord $owner
*
* @throws InvalidConfigException
*/
public function attach($owner)
{
|
8af13427
Yarik
For leha commit.
|
113
114
115
|
if(empty( $this->objectLang )) {
$this->objectLang = $owner::className() . 'Lang';
} elseif(!is_string($this->objectLang)) {
|
d55d2fe0
Yarik
Multilanguage
|
116
117
118
|
throw new InvalidConfigException('Object lang must be fully classified namespaced classname');
}
try {
|
8af13427
Yarik
For leha commit.
|
119
|
$this->objectLang = \Yii::createObject($this->objectLang);
|
d55d2fe0
Yarik
Multilanguage
|
120
121
122
|
} catch(\ReflectionException $exception) {
throw new InvalidConfigException('Object lang must be fully classified namespaced classname');
}
|
8af13427
Yarik
For leha commit.
|
123
|
if(( !$owner instanceof ActiveRecord ) || ( !$this->objectLang instanceof ActiveRecord )) {
|
d55d2fe0
Yarik
Multilanguage
|
124
125
126
127
128
129
130
131
132
133
134
|
throw new InvalidConfigException('Object lang must be fully classified namespaced classname');
}
parent::attach($owner);
}
/**
* Get query to get all language models for $owner indexed by language_id
* @return ActiveQuery
*/
public function getLangs()
{
|
8af13427
Yarik
For leha commit.
|
135
|
$objectLang = $this->objectLang;
|
d55d2fe0
Yarik
Multilanguage
|
136
|
$owner = $this->owner;
|
8af13427
Yarik
For leha commit.
|
137
|
return $owner->hasMany($objectLang::className(), [ $this->getLangKey() => $this->getOwnerKey() ])
|
d55d2fe0
Yarik
Multilanguage
|
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
->indexBy('language_id');
}
/**
* Get query to get language model for $owner for language_id, default to
* Language::getCurrent()
*
* @param int $language_id
*
* @return ActiveQuery
*/
public function getLang(int $language_id = NULL)
{
if(empty( $language_id )) {
|
8af13427
Yarik
For leha commit.
|
152
|
$language_id = Language::getCurrent()->id;
|
d55d2fe0
Yarik
Multilanguage
|
153
|
}
|
8af13427
Yarik
For leha commit.
|
154
155
|
$objectLang = $this->objectLang;
$table_name = $objectLang::getTableSchema()->name;
|
d55d2fe0
Yarik
Multilanguage
|
156
|
$owner = $this->owner;
|
8af13427
Yarik
For leha commit.
|
157
|
return $owner->hasOne($objectLang::className(), [ $this->getLangKey() => $this->getOwnerKey() ])
|
14cd7eed
Yarik
LanguageBehavior ...
|
158
|
->where([ $table_name . '.language_id' => $language_id ]);
|
d55d2fe0
Yarik
Multilanguage
|
159
160
161
162
163
|
}
/**
* Generate language models for $owner for active languages. If $owner not new and language
* models already inserted, models will be filled with them.
|
14cd7eed
Yarik
LanguageBehavior ...
|
164
|
* @return void
|
d55d2fe0
Yarik
Multilanguage
|
165
166
167
168
169
170
|
*/
public function generateLangs()
{
$owner = $this->owner;
$languages = Language::find()
->where([ 'status' => true ])
|
8af13427
Yarik
For leha commit.
|
171
|
->orderBy([ 'id' => SORT_ASC ])
|
d55d2fe0
Yarik
Multilanguage
|
172
173
|
->asArray()
->column();
|
8af13427
Yarik
For leha commit.
|
174
|
$objectLang = $this->objectLang;
|
d55d2fe0
Yarik
Multilanguage
|
175
176
177
178
179
|
$owner_key = $this->getOwnerKey();
$langs = [];
if(!$owner->isNewRecord) {
$langs = $this->getLangs()
->andFilterWhere([ 'language_id' => $languages ])
|
14cd7eed
Yarik
LanguageBehavior ...
|
180
|
->orderBy([ 'language_id' => SORT_ASC ])
|
d55d2fe0
Yarik
Multilanguage
|
181
182
183
184
185
|
->all();
}
foreach($languages as $language) {
if(!array_key_exists($language, $langs)) {
$langs[ $language ] = \Yii::createObject([
|
8af13427
Yarik
For leha commit.
|
186
|
'class' => $objectLang::className(),
|
d55d2fe0
Yarik
Multilanguage
|
187
188
189
190
191
|
'language_id' => $language,
$this->getLangKey() => ( $owner->isNewRecord ? NULL : $owner->$owner_key ),
]);
}
}
|
8af13427
Yarik
For leha commit.
|
192
|
$this->modelLangs = $langs;
|
d55d2fe0
Yarik
Multilanguage
|
193
194
195
196
197
|
}
/**
* Load language models with post data.
*
|
14cd7eed
Yarik
LanguageBehavior ...
|
198
|
* @param Request $request
|
d55d2fe0
Yarik
Multilanguage
|
199
|
*/
|
14cd7eed
Yarik
LanguageBehavior ...
|
200
|
public function loadLangs(Request $request)
|
d55d2fe0
Yarik
Multilanguage
|
201
|
{
|
8af13427
Yarik
For leha commit.
|
202
203
204
205
|
foreach($request->post($this->objectLang->formName(), []) as $lang => $value) {
if(!empty( $this->modelLangs[ $lang ] )) {
$this->modelLangs[ $lang ]->attributes = $value;
$this->modelLangs[ $lang ]->language_id = $lang;
|
d55d2fe0
Yarik
Multilanguage
|
206
207
208
209
210
211
212
|
}
}
}
/**
* Link language models with $owner by setting language model language key to owner key of
* owner
|
d55d2fe0
Yarik
Multilanguage
|
213
214
|
* @return bool If $owner is new record then return false else true
*/
|
14cd7eed
Yarik
LanguageBehavior ...
|
215
|
public function linkLangs()
|
d55d2fe0
Yarik
Multilanguage
|
216
217
|
{
$owner = $this->owner;
|
5c2eb7c8
Yarik
Big commit almost...
|
218
219
220
|
// if($owner->isNewRecord) {
// return false;
// }
|
d55d2fe0
Yarik
Multilanguage
|
221
222
|
$lang_key = $this->getLangKey();
$owner_key = $this->getOwnerKey();
|
8af13427
Yarik
For leha commit.
|
223
224
|
$modelLangs = $this->modelLangs;
foreach($modelLangs as $model_lang) {
|
d55d2fe0
Yarik
Multilanguage
|
225
226
227
228
229
230
231
|
$model_lang->$lang_key = $owner->$owner_key;
}
return true;
}
/**
* Try to save all language models to the db. Validation function is run for all models.
|
d55d2fe0
Yarik
Multilanguage
|
232
233
|
* @return bool Whether all models are valid
*/
|
14cd7eed
Yarik
LanguageBehavior ...
|
234
|
public function saveLangs()
|
d55d2fe0
Yarik
Multilanguage
|
235
236
|
{
$success = true;
|
8af13427
Yarik
For leha commit.
|
237
238
|
$modelLangs = $this->modelLangs;
foreach($modelLangs as $model_lang) {
|
18d6bf69
Yarik
Import browser be...
|
239
|
if($model_lang->save() === false) {
|
2e91abdd
Yarik
Import browser be...
|
240
|
$success = false;
|
d55d2fe0
Yarik
Multilanguage
|
241
242
243
244
|
}
}
return $success;
}
|
14cd7eed
Yarik
LanguageBehavior ...
|
245
246
247
248
249
250
251
252
|
public function beforeSave($event)
{
/**
* @var ActiveRecord $owner
*/
$owner = $this->owner;
$db = $owner::getDb();
|
8af13427
Yarik
For leha commit.
|
253
|
$this->transaction = $db->beginTransaction();
|
5c2eb7c8
Yarik
Big commit almost...
|
254
255
|
if($owner->hasAttribute('remote_id') && empty( $owner->remote_id )) {
$owner->remote_id = strval(microtime(true) * 10000);
|
72a992f5
Yarik
Import browser v1.0
|
256
|
}
|
14cd7eed
Yarik
LanguageBehavior ...
|
257
258
259
260
|
}
public function afterSave($event)
{
|
8af13427
Yarik
For leha commit.
|
261
|
if(!empty( $this->modelLangs )) {
|
14cd7eed
Yarik
LanguageBehavior ...
|
262
|
if($this->linkLangs() && $this->saveLangs()) {
|
8af13427
Yarik
For leha commit.
|
263
264
|
$this->transaction->commit();
$this->transactionStatus = true;
|
14cd7eed
Yarik
LanguageBehavior ...
|
265
|
} else {
|
8af13427
Yarik
For leha commit.
|
266
267
|
$this->transaction->rollBack();
$this->transactionStatus = false;
|
14cd7eed
Yarik
LanguageBehavior ...
|
268
269
|
}
} else {
|
8af13427
Yarik
For leha commit.
|
270
271
|
$this->transaction->commit();
$this->transactionStatus = true;
|
14cd7eed
Yarik
LanguageBehavior ...
|
272
|
}
|
14cd7eed
Yarik
LanguageBehavior ...
|
273
274
275
276
277
278
279
|
}
/**
* @return bool
*/
public function getTransactionStatus():bool
{
|
8af13427
Yarik
For leha commit.
|
280
|
return $this->transactionStatus;
|
14cd7eed
Yarik
LanguageBehavior ...
|
281
|
}
|
d55d2fe0
Yarik
Multilanguage
|
282
|
}
|