-
Notifications
You must be signed in to change notification settings - Fork 0
/
DynamicFieldsBehavior.php
104 lines (89 loc) · 2.71 KB
/
DynamicFieldsBehavior.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?php
/**
* Behavior for adding dynamic fields to your ActiveRecord model.
*/
namespace chemezov\yii2_dynamic_fields;
use Yii;
use yii\base\Behavior;
use yii\db\ActiveRecord;
use yii\db\Query;
use yii\helpers\ArrayHelper;
use yii\helpers\StringHelper;
/**
* Behavior to store dynamic fields in separate table.
*
* Class DynamicFieldsBehavior
* @package chemezov\yii2_dynamic_fields
*/
class DynamicFieldsBehavior extends BaseDynamicFieldsBehavior
{
/**
* You can set custom model class. Default is short name of owner class.
*
* @var string
*/
public $modelName;
public $tableName = '{{%dynamic_fields}}';
/**
* {@inheritdoc}
*/
public function events()
{
return [
ActiveRecord::EVENT_AFTER_FIND => 'loadDynamicFields',
ActiveRecord::EVENT_AFTER_INSERT => 'saveDynamicFields',
ActiveRecord::EVENT_AFTER_UPDATE => 'saveDynamicFields',
ActiveRecord::EVENT_BEFORE_DELETE => 'deleteDynamicFields',
];
}
/**
* Save fields values in separate table.
*
* @throws \yii\db\Exception
*/
public function saveDynamicFields(): void
{
$this->deleteDynamicFields();
if (!empty($this->fields)) {
$data = [];
foreach ($this->fields as $field) {
$data[] = [
$this->getModelClass(),
$this->getPrimaryKey(),
$field,
$this->owner->$field,
];
}
Yii::$app->db->createCommand()->batchInsert($this->tableName, ['model', 'model_id', 'field', 'value'], $data)->execute();
}
}
/**
* Load fields values from separate table.
*/
public function loadDynamicFields(): void
{
if (!empty($this->fields)) {
$query = (new Query())
->select(['field', 'value'])
->from($this->tableName)
->where(['model' => $this->getModelClass(), 'model_id' => $this->getPrimaryKey()]);
foreach (ArrayHelper::map($query->all(), 'field', 'value') as $field => $value) {
if (in_array($field, $this->fields)) {
$this->owner->$field = $value;
}
}
}
}
public function deleteDynamicFields(): void
{
Yii::$app->db->createCommand()->delete($this->tableName, ['model' => $this->getModelClass(), 'model_id' => $this->getPrimaryKey()])->execute();
}
protected function getModelClass()
{
return $this->modelName ?: StringHelper::basename(get_class($this->owner));
}
protected function getPrimaryKey()
{
return $this->owner->getPrimaryKey();
}
}