From 6a53d6a2c9df186d4ce45a3dd5b9cdd2af1059e0 Mon Sep 17 00:00:00 2001 From: Mikhail Chemezov Date: Fri, 20 May 2022 19:49:40 +0500 Subject: [PATCH] refactored DynamicFieldsBehavior: - renamed methods: loadDynamicFields, saveDynamicFields, deleteDynamicFields. added BaseDynamicFieldsBehavior. added JsonDynamicFieldsBehavior. --- BaseDynamicFieldsBehavior.php | 59 ++++++++++++++++++++++++++++++ DynamicFieldsBehavior.php | 69 ++++++++++++----------------------- JsonDynamicFieldsBehavior.php | 61 +++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+), 45 deletions(-) create mode 100644 BaseDynamicFieldsBehavior.php create mode 100644 JsonDynamicFieldsBehavior.php diff --git a/BaseDynamicFieldsBehavior.php b/BaseDynamicFieldsBehavior.php new file mode 100644 index 0000000..3a8cca4 --- /dev/null +++ b/BaseDynamicFieldsBehavior.php @@ -0,0 +1,59 @@ +fields); + } + + public function canSetProperty($name, $checkVars = true) + { + return in_array($name, $this->fields); + } + + public function __get($name) + { + if (array_key_exists($name, $this->_values)) { + return $this->_values[$name]; + } + } + + public function __set($name, $value) + { + if ($this->canSetProperty($name)) { + $this->_values[$name] = $value; + } + } + + /** + * Save dynamic fields from storage. + */ + abstract public function saveDynamicFields(): void; + + /** + * Load dynamic fields from storage. + */ + abstract public function loadDynamicFields(): void; + + /** + * Delete dynamic fields from storage. + */ + abstract public function deleteDynamicFields(): void; +} diff --git a/DynamicFieldsBehavior.php b/DynamicFieldsBehavior.php index f6be805..b9d81c9 100644 --- a/DynamicFieldsBehavior.php +++ b/DynamicFieldsBehavior.php @@ -13,7 +13,13 @@ use yii\helpers\ArrayHelper; use yii\helpers\StringHelper; -class DynamicFieldsBehavior extends Behavior +/** + * 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. @@ -22,58 +28,29 @@ class DynamicFieldsBehavior extends Behavior */ public $modelName; - /** - * Fields to store and load with your model. Example: ['address', 'is_client']. - * - * @var string[] - */ - public $fields = []; - public $tableName = '{{%dynamic_fields}}'; /** - * @var array + * {@inheritdoc} */ - private $_values = []; - public function events() { return [ - ActiveRecord::EVENT_AFTER_FIND => 'loadDynamicFieldsValues', - ActiveRecord::EVENT_AFTER_INSERT => 'saveDynamicFieldsValues', - ActiveRecord::EVENT_AFTER_UPDATE => 'saveDynamicFieldsValues', - ActiveRecord::EVENT_BEFORE_DELETE => 'deleteDynamicFieldsValues', + ActiveRecord::EVENT_AFTER_FIND => 'loadDynamicFields', + ActiveRecord::EVENT_AFTER_INSERT => 'saveDynamicFields', + ActiveRecord::EVENT_AFTER_UPDATE => 'saveDynamicFields', + ActiveRecord::EVENT_BEFORE_DELETE => 'deleteDynamicFields', ]; } - public function canGetProperty($name, $checkVars = true) - { - return in_array($name, $this->fields); - } - - public function canSetProperty($name, $checkVars = true) - { - return in_array($name, $this->fields); - } - - public function __get($name) - { - if (array_key_exists($name, $this->_values)) { - return $this->_values[$name]; - } - } - - public function __set($name, $value) - { - if ($this->canSetProperty($name)) { - $this->_values[$name] = $value; - } - } - - public function saveDynamicFieldsValues() + /** + * Save fields values in separate table. + * + * @throws \yii\db\Exception + */ + public function saveDynamicFields(): void { - /* Save fields values in separate table */ - $this->deleteDynamicFieldsValues(); + $this->deleteDynamicFields(); if (!empty($this->fields)) { $data = []; @@ -91,9 +68,11 @@ public function saveDynamicFieldsValues() } } - public function loadDynamicFieldsValues() + /** + * Load fields values from separate table. + */ + public function loadDynamicFields(): void { - /* Load fields values */ if (!empty($this->fields)) { $query = (new Query()) ->select(['field', 'value']) @@ -108,7 +87,7 @@ public function loadDynamicFieldsValues() } } - public function deleteDynamicFieldsValues() + public function deleteDynamicFields(): void { Yii::$app->db->createCommand()->delete($this->tableName, ['model' => $this->getModelClass(), 'model_id' => $this->getPrimaryKey()])->execute(); } diff --git a/JsonDynamicFieldsBehavior.php b/JsonDynamicFieldsBehavior.php new file mode 100644 index 0000000..4328214 --- /dev/null +++ b/JsonDynamicFieldsBehavior.php @@ -0,0 +1,61 @@ + 'loadDynamicFields', + ActiveRecord::EVENT_BEFORE_INSERT => 'saveDynamicFields', + ActiveRecord::EVENT_BEFORE_UPDATE => 'saveDynamicFields', + ActiveRecord::EVENT_BEFORE_DELETE => 'deleteDynamicFields', + ]; + } + + public function loadDynamicFields(): void + { + $data = $this->owner->{$this->attributeName} ?: []; + + if (is_string($data)) { + $data = Json::decode($data); + } + + foreach ($data as $field => $value) { + if (in_array($field, $this->fields)) { + $this->owner->$field = $value; + } + } + } + + public function saveDynamicFields(): void + { + $this->owner->{$this->attributeName} = Json::encode($this->_values); + } + + public function deleteDynamicFields(): void + { + $this->_values = []; + $this->owner->{$this->attributeName} = null; + } +}