1
|
|
|
<?php |
2
|
|
|
namespace app\models; |
3
|
|
|
|
4
|
|
|
use app\modules\shop\models\FilterSets; |
5
|
|
|
use app\properties\HasProperties; |
6
|
|
|
use app\properties\PropertyHandlers; |
7
|
|
|
use app\traits\GetImages; |
8
|
|
|
use Yii; |
9
|
|
|
use yii\behaviors\AttributeBehavior; |
10
|
|
|
use yii\caching\TagDependency; |
11
|
|
|
use yii\data\ActiveDataProvider; |
12
|
|
|
use yii\db\ActiveRecord; |
13
|
|
|
use yii\helpers\Json; |
14
|
|
|
use \devgroup\TagDependencyHelper\ActiveRecordHelper; |
15
|
|
|
|
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* This is the model class for table "property". |
19
|
|
|
* @property integer $id |
20
|
|
|
* @property integer $property_group_id |
21
|
|
|
* @property string $name |
22
|
|
|
* @property string $key |
23
|
|
|
* @property string $value_type |
24
|
|
|
* @property integer $property_handler_id |
25
|
|
|
* @property integer $has_static_values |
26
|
|
|
* @property integer $has_slugs_in_values |
27
|
|
|
* @property integer $is_eav |
28
|
|
|
* @property integer $is_column_type_stored |
29
|
|
|
* @property integer $multiple |
30
|
|
|
* @property integer $sort_order |
31
|
|
|
* @property string $handler_additional_params |
32
|
|
|
* @property integer $required |
33
|
|
|
* @property integer $interpret_as |
34
|
|
|
* @property integer $captcha |
35
|
|
|
* @property string $mask |
36
|
|
|
* @property integer $alias |
37
|
|
|
* @property PropertyGroup $group |
38
|
|
|
*/ |
39
|
|
|
class Property extends ActiveRecord |
40
|
|
|
{ |
41
|
|
|
use GetImages; |
42
|
|
|
|
43
|
|
|
public static $identity_map = []; |
44
|
|
|
public static $group_id_to_property_ids = []; |
45
|
|
|
private $handlerAdditionalParams = []; |
46
|
|
|
public $required; |
47
|
|
|
public $interpret_as; |
48
|
|
|
public $captcha; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @inheritdoc |
52
|
|
|
*/ |
53
|
|
|
public function behaviors() |
54
|
|
|
{ |
55
|
|
|
return [ |
56
|
|
|
[ |
57
|
|
|
'class' => AttributeBehavior::className(), |
58
|
|
|
'attributes' => [ |
59
|
|
|
ActiveRecord::EVENT_BEFORE_INSERT => 'sort_order', |
60
|
|
|
], |
61
|
|
|
'value' => 0, |
62
|
|
|
], |
63
|
|
|
[ |
64
|
|
|
'class' => ActiveRecordHelper::className(), |
65
|
|
|
], |
66
|
|
|
[ |
67
|
|
|
'class' => HasProperties::className(), |
68
|
|
|
], |
69
|
|
|
]; |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* @inheritdoc |
74
|
|
|
*/ |
75
|
|
|
public static function tableName() |
76
|
|
|
{ |
77
|
|
|
return '{{%property}}'; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @inheritdoc |
82
|
|
|
*/ |
83
|
|
|
public function rules() |
84
|
|
|
{ |
85
|
|
|
return [ |
86
|
|
|
[['property_group_id', 'name', 'property_handler_id', 'handler_additional_params'], 'required'], |
87
|
|
|
[ |
88
|
|
|
[ |
89
|
|
|
'property_group_id', |
90
|
|
|
'property_handler_id', |
91
|
|
|
'has_static_values', |
92
|
|
|
'has_slugs_in_values', |
93
|
|
|
'is_eav', |
94
|
|
|
'is_column_type_stored', |
95
|
|
|
'multiple', |
96
|
|
|
'sort_order', |
97
|
|
|
'alias', |
98
|
|
|
], |
99
|
|
|
'integer' |
100
|
|
|
], |
101
|
|
|
[ |
102
|
|
|
[ |
103
|
|
|
'display_only_on_depended_property_selected', |
104
|
|
|
'depends_on_property_id', |
105
|
|
|
'depends_on_category_group_id', |
106
|
|
|
'hide_other_values_if_selected' |
107
|
|
|
], |
108
|
|
|
'integer' |
109
|
|
|
], |
110
|
|
|
[['interpret_as'], 'string'], |
111
|
|
|
[['name', 'handler_additional_params', 'depended_property_values', 'value_type', 'mask'], 'string'], |
112
|
|
|
[['key'], 'string', 'max' => 20], |
113
|
|
|
[['key'], 'match', 'pattern' => '#^[\w]+$#'], |
114
|
|
|
[['depends_on_property_id', 'depends_on_category_group_id'], 'default', 'value' => 0], |
115
|
|
|
[['required', 'captcha'], 'integer', 'min' => 0, 'max' => 1], |
116
|
|
|
[['dont_filter'], 'safe'], |
117
|
|
|
[['key'], 'unique', 'targetAttribute' => ['key', 'property_group_id']], |
118
|
|
|
]; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* @inheritdoc |
123
|
|
|
*/ |
124
|
|
|
public function attributeLabels() |
125
|
|
|
{ |
126
|
|
|
return [ |
127
|
|
|
'id' => Yii::t('app', 'ID'), |
128
|
|
|
'property_group_id' => Yii::t('app', 'Property Group ID'), |
129
|
|
|
'name' => Yii::t('app', 'Name'), |
130
|
|
|
'key' => Yii::t('app', 'Key'), |
131
|
|
|
'value_type' => Yii::t('app', 'Value Type'), |
132
|
|
|
'property_handler_id' => Yii::t('app', 'Property Handler ID'), |
133
|
|
|
'has_static_values' => Yii::t('app', 'Has Static Values'), |
134
|
|
|
'has_slugs_in_values' => Yii::t('app', 'Has Slugs In Values'), |
135
|
|
|
'is_eav' => Yii::t('app', 'Is Eav'), |
136
|
|
|
'is_column_type_stored' => Yii::t('app', 'Is Column Type Stored'), |
137
|
|
|
'multiple' => Yii::t('app', 'Multiple'), |
138
|
|
|
'sort_order' => Yii::t('app', 'Sort Order'), |
139
|
|
|
'handler_additional_params' => Yii::t('app', 'Handler Additional Params'), |
140
|
|
|
'required' => Yii::t('app', 'Required'), |
141
|
|
|
'interpret_as' => Yii::t('app', 'Interpret Field As'), |
142
|
|
|
'captcha' => Yii::t('app', 'Captcha'), |
143
|
|
|
'dont_filter' => Yii::t('app', 'Don\'t use in filtration'), |
144
|
|
|
'hide_other_values_if_selected' => Yii::t('app', 'Hide Other Values If Selected'), |
145
|
|
|
'display_only_on_depended_property_selected' => Yii::t('app', 'Display Only On Depended Property Selected'), |
146
|
|
|
'depends_on_property_id' => Yii::t('app', 'Depends On Property Id'), |
147
|
|
|
'depended_property_values' => Yii::t('app', 'Depended Property Values'), |
148
|
|
|
'depends_on_category_group_id' => Yii::t('app', 'Depends On Category Group Id'), |
149
|
|
|
'mask' => Yii::t('app', 'Mask'), |
150
|
|
|
'alias' => Yii::t('app', 'Alias'), |
151
|
|
|
]; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Search tasks |
156
|
|
|
* @param $params |
157
|
|
|
* @return ActiveDataProvider |
158
|
|
|
*/ |
159
|
|
|
public function search($params) |
160
|
|
|
{ |
161
|
|
|
/* @var $query \yii\db\ActiveQuery */ |
162
|
|
|
$query = static::find()->where(['property_group_id' => $this->property_group_id]); |
163
|
|
|
$dataProvider = new ActiveDataProvider([ |
164
|
|
|
'query' => $query, |
165
|
|
|
'pagination' => [ |
166
|
|
|
'pageSize' => 10, |
167
|
|
|
], |
168
|
|
|
]); |
169
|
|
|
if (!($this->load($params))) { |
170
|
|
|
return $dataProvider; |
171
|
|
|
} |
172
|
|
|
$query->andFilterWhere(['id' => $this->id]); |
173
|
|
|
$query->andFilterWhere(['like', 'name', $this->name]); |
174
|
|
|
$query->andFilterWhere(['like', 'key', $this->key]); |
175
|
|
|
$query->andFilterWhere(['property_handler_id' => $this->property_handler_id]); |
176
|
|
|
$query->andFilterWhere(['has_static_values' => $this->has_static_values]); |
177
|
|
|
$query->andFilterWhere(['has_slugs_in_values' => $this->has_slugs_in_values]); |
178
|
|
|
$query->andFilterWhere(['is_eav' => $this->is_eav]); |
179
|
|
|
$query->andFilterWhere(['is_column_type_stored' => $this->is_column_type_stored]); |
180
|
|
|
$query->andFilterWhere(['multiple' => $this->multiple]); |
181
|
|
|
return $dataProvider; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* @return \yii\db\ActiveQuery |
186
|
|
|
*/ |
187
|
|
|
public function getGroup() |
188
|
|
|
{ |
189
|
|
|
return $this->hasOne(PropertyGroup::className(), ['id' => 'property_group_id']); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* @return PropertyHandler |
194
|
|
|
*/ |
195
|
|
|
public function getHandler() |
196
|
|
|
{ |
197
|
|
|
// return $this->hasOne(PropertyHandler::className(), ['id' => 'property_handler_id']); |
|
|
|
|
198
|
|
|
return PropertyHandler::findById($this->property_handler_id); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Возвращает модель по ID с использованием IdentityMap |
203
|
|
|
* @param int $id |
204
|
|
|
* @return null|Property |
205
|
|
|
*/ |
206
|
|
View Code Duplication |
public static function findById($id) |
207
|
|
|
{ |
208
|
|
|
if (!isset(static::$identity_map[$id])) { |
209
|
|
|
$cacheKey = "Property:$id"; |
210
|
|
|
if (false === $prop = Yii::$app->cache->get($cacheKey)) { |
211
|
|
|
if (null === $prop = static::findOne($id)) { |
212
|
|
|
return null; |
213
|
|
|
} |
214
|
|
|
Yii::$app->cache->set( |
215
|
|
|
$cacheKey, |
216
|
|
|
$prop, |
217
|
|
|
0, |
218
|
|
|
new TagDependency([ |
219
|
|
|
'tags' => [ |
220
|
|
|
ActiveRecordHelper::getObjectTag($prop, $id) |
|
|
|
|
221
|
|
|
], |
222
|
|
|
]) |
223
|
|
|
); |
224
|
|
|
} |
225
|
|
|
static::$identity_map[$id] = $prop; |
226
|
|
|
} |
227
|
|
|
return static::$identity_map[$id]; |
228
|
|
|
} |
229
|
|
|
|
230
|
|
|
/** |
231
|
|
|
* @param $group_id |
232
|
|
|
* @return null|array<Property> |
233
|
|
|
*/ |
234
|
|
|
public static function getForGroupId($group_id) |
235
|
|
|
{ |
236
|
|
|
if (!isset(static::$group_id_to_property_ids[$group_id])) { |
237
|
|
|
$cacheKey = "PropsForGroup:$group_id"; |
238
|
|
|
if (false === $props = Yii::$app->cache->get($cacheKey)) { |
239
|
|
|
if (null !== $props = static::find()->where(['property_group_id' => $group_id])->orderBy( |
240
|
|
|
'sort_order' |
241
|
|
|
)->all() |
242
|
|
|
) { |
243
|
|
|
Yii::$app->cache->set( |
244
|
|
|
$cacheKey, |
245
|
|
|
$props, |
246
|
|
|
0, |
247
|
|
|
new TagDependency([ |
248
|
|
|
'tags' => [ |
249
|
|
|
ActiveRecordHelper::getObjectTag( |
250
|
|
|
PropertyGroup::className(), |
251
|
|
|
$group_id |
252
|
|
|
) |
253
|
|
|
], |
254
|
|
|
]) |
255
|
|
|
); |
256
|
|
|
} |
257
|
|
|
} |
258
|
|
|
static::$group_id_to_property_ids[$group_id] = []; |
259
|
|
|
foreach ($props as $property) { |
260
|
|
|
static::$identity_map[$property->id] = $property; |
261
|
|
|
static::$group_id_to_property_ids[$group_id][] = $property->id; |
262
|
|
|
} |
263
|
|
|
return $props; |
264
|
|
|
} |
265
|
|
|
$properties = []; |
266
|
|
|
foreach (static::$group_id_to_property_ids[$group_id] as $property_id) { |
267
|
|
|
$properties[] = static::findById($property_id); |
268
|
|
|
} |
269
|
|
|
return $properties; |
|
|
|
|
270
|
|
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* @param $form |
274
|
|
|
* @param $model |
275
|
|
|
* @param $values |
276
|
|
|
* @param string $renderType |
277
|
|
|
* @return string |
278
|
|
|
*/ |
279
|
|
|
public function handler($form, $model, $values, $renderType = 'frontend_render_view') |
280
|
|
|
{ |
281
|
|
|
$handler = $this->handler; |
|
|
|
|
282
|
|
|
if (null === $handler) { |
283
|
|
|
return ''; |
284
|
|
|
} |
285
|
|
|
$handler = PropertyHandlers::createHandler($handler); |
286
|
|
|
if (null === $handler) { |
287
|
|
|
return ''; |
288
|
|
|
} |
289
|
|
|
return $handler->render($this, $model, $values, $form, $renderType); |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* @inheritdoc |
294
|
|
|
*/ |
295
|
|
|
public function afterFind() |
296
|
|
|
{ |
297
|
|
|
parent::afterFind(); |
298
|
|
|
$this->handlerAdditionalParams = Json::decode($this->handler_additional_params); |
|
|
|
|
299
|
|
|
$this->required = isset($this->handlerAdditionalParams['rules']) && is_array( |
300
|
|
|
$this->handlerAdditionalParams['rules'] |
301
|
|
|
) && in_array('required', $this->handlerAdditionalParams['rules']); |
302
|
|
|
$this->interpret_as = isset($this->handlerAdditionalParams['interpret_as']) ? $this->handlerAdditionalParams['interpret_as'] : 0; |
|
|
|
|
303
|
|
|
if (isset($this->handlerAdditionalParams['rules']) && is_array($this->handlerAdditionalParams['rules'])) { |
304
|
|
|
foreach ($this->handlerAdditionalParams['rules'] as $rule) { |
305
|
|
|
if (is_array($rule)) { |
306
|
|
|
if (in_array('captcha', $rule, true)) { |
307
|
|
|
$this->captcha = true; |
308
|
|
|
} |
309
|
|
|
} else { |
310
|
|
|
switch ($rule) { |
311
|
|
|
case 'required': |
312
|
|
|
$this->required = true; |
313
|
|
|
break; |
314
|
|
|
} |
315
|
|
|
} |
316
|
|
|
} |
317
|
|
|
} |
318
|
|
|
} |
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* @inheritdoc |
322
|
|
|
* @param bool $insert |
323
|
|
|
* @return bool |
324
|
|
|
*/ |
325
|
|
|
public function beforeSave($insert) |
326
|
|
|
{ |
327
|
|
|
if (!parent::beforeSave($insert)) { |
328
|
|
|
return false; |
329
|
|
|
} |
330
|
|
|
$handlerAdditionalParams = $this->isNewRecord ? [] : Json::decode($this->handler_additional_params); |
331
|
|
|
$handlerRules = []; |
332
|
|
|
if (1 === intval($this->required)) { |
333
|
|
|
$handlerRules[] = 'required'; |
334
|
|
|
} |
335
|
|
|
if (PropertyHandler::findByName('File') === intval($this->property_handler_id)) { |
336
|
|
|
if (1 === intval($this->multiple)) { |
337
|
|
|
$handlerRules[] = ['file', 'maxFiles' => 0]; |
338
|
|
|
} else { |
339
|
|
|
$handlerRules[] = ['file', 'maxFiles' => 1]; |
340
|
|
|
} |
341
|
|
|
} |
342
|
|
|
if (1 === intval($this->captcha)) { |
343
|
|
|
$handlerRules[] = ['captcha', 'captchaAction' => '/default/captcha']; |
344
|
|
|
} |
345
|
|
|
$handlerAdditionalParams['interpret_as'] = $this->interpret_as; |
346
|
|
|
$handlerAdditionalParams['rules'] = $handlerRules; |
347
|
|
|
$this->handlerAdditionalParams = $handlerAdditionalParams; |
|
|
|
|
348
|
|
|
$this->handler_additional_params = Json::encode($handlerAdditionalParams); |
349
|
|
|
return true; |
350
|
|
|
} |
351
|
|
|
|
352
|
|
|
/** |
353
|
|
|
* |
354
|
|
|
*/ |
355
|
|
|
public function invalidateModelCache() |
356
|
|
|
{ |
357
|
|
|
TagDependency::invalidate( |
358
|
|
|
Yii::$app->cache, |
359
|
|
|
[ |
360
|
|
|
ActiveRecordHelper::getObjectTag( |
361
|
|
|
PropertyGroup::className(), |
362
|
|
|
$this->property_group_id |
363
|
|
|
), |
364
|
|
|
ActiveRecordHelper::getObjectTag(Property::className(), $this->id) |
|
|
|
|
365
|
|
|
] |
366
|
|
|
); |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* @param bool $insert |
371
|
|
|
* @param array $changedAttributes |
372
|
|
|
*/ |
373
|
|
|
public function afterSave($insert, $changedAttributes) |
374
|
|
|
{ |
375
|
|
|
// @todo clear table schema |
|
|
|
|
376
|
|
|
$this->invalidateModelCache(); |
377
|
|
|
parent::afterSave($insert, $changedAttributes); |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
/** |
381
|
|
|
* @return bool |
382
|
|
|
*/ |
383
|
|
|
public function beforeDelete() |
384
|
|
|
{ |
385
|
|
|
$this->invalidateModelCache(); |
386
|
|
|
return parent::beforeDelete(); |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
public function afterDelete() |
390
|
|
|
{ |
391
|
|
|
$object = Object::findById($this->group->object_id); |
392
|
|
|
$staticValues = PropertyStaticValues::find()->where(['property_id' => $this->id])->all(); |
393
|
|
|
foreach ($staticValues as $psv) { |
394
|
|
|
$psv->delete(); |
395
|
|
|
} |
396
|
|
|
if (null !== $object) { |
397
|
|
|
if ($this->is_eav) { |
398
|
|
|
Yii::$app->db->createCommand()->delete( |
399
|
|
|
$object->eav_table_name, |
400
|
|
|
['key' => $this->key, 'property_group_id' => $this->group->id] |
401
|
|
|
)->execute(); |
402
|
|
|
} |
403
|
|
|
if ($this->is_column_type_stored) { |
404
|
|
|
Yii::$app->db->createCommand()->dropColumn($object->column_properties_table_name, $this->key)->execute(); |
|
|
|
|
405
|
|
|
// if ($object->object_class == Form::className()) { |
|
|
|
|
406
|
|
|
// $submissionObject = Object::getForClass(Submission::className()); |
|
|
|
|
407
|
|
|
// Yii::$app->db->createCommand() |
|
|
|
|
408
|
|
|
// ->dropColumn($submissionObject->column_properties_table_name, $this->key) |
|
|
|
|
409
|
|
|
// ->execute(); |
|
|
|
|
410
|
|
|
// } |
411
|
|
|
} |
412
|
|
|
} |
413
|
|
|
FilterSets::deleteAll(['property_id' => $this->id]); |
414
|
|
|
parent::afterDelete(); |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
/** |
418
|
|
|
* @param $name |
419
|
|
|
* @return null|mixed |
420
|
|
|
*/ |
421
|
|
|
public function getAdditionalParam($name) |
422
|
|
|
{ |
423
|
|
|
if (isset($this->handlerAdditionalParams[$name])) { |
424
|
|
|
return $this->handlerAdditionalParams[$name]; |
425
|
|
|
} |
426
|
|
|
return null; |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
/** |
430
|
|
|
* @return array |
|
|
|
|
431
|
|
|
*/ |
432
|
|
|
public static function getAliases() |
433
|
|
|
{ |
434
|
|
|
return [ |
435
|
|
|
0 => Yii::t('app', 'Not selected'), |
436
|
|
|
1 => 'date', |
437
|
|
|
2 => 'ip', |
438
|
|
|
3 => 'url', |
439
|
|
|
4 => 'email', |
440
|
|
|
]; |
441
|
|
|
} |
442
|
|
|
} |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.