Skip to content

Commit

Permalink
refactored DynamicFieldsBehavior:
Browse files Browse the repository at this point in the history
- renamed methods: loadDynamicFields, saveDynamicFields, deleteDynamicFields.

added BaseDynamicFieldsBehavior.
added JsonDynamicFieldsBehavior.
  • Loading branch information
chemezov committed May 20, 2022
1 parent 8f77cb4 commit 6a53d6a
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 45 deletions.
59 changes: 59 additions & 0 deletions BaseDynamicFieldsBehavior.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

namespace chemezov\yii2_dynamic_fields;

use yii\base\Behavior;

abstract class BaseDynamicFieldsBehavior extends Behavior
{
/**
* Fields to store and load with your model. Example: ['address', 'is_client'].
*
* @var string[]
*/
public $fields = [];

/**
* @var array
*/
protected $_values = [];

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;
}
}

/**
* 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;
}
69 changes: 24 additions & 45 deletions DynamicFieldsBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 = [];
Expand All @@ -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'])
Expand All @@ -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();
}
Expand Down
61 changes: 61 additions & 0 deletions JsonDynamicFieldsBehavior.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

namespace chemezov\yii2_dynamic_fields;

use yii\db\ActiveRecord;
use yii\helpers\Json;

/**
* Behavior to store dynamic fields in separate attribute of model.
*
* Class JsonDynamicFieldsBehavior
* @package chemezov\yii2_dynamic_fields
*/
class JsonDynamicFieldsBehavior extends BaseDynamicFieldsBehavior
{
/**
* Attribute name with json data.
*
* @var string
*/
public $attributeName = 'additional_data';

/**
* {@inheritdoc}
*/
public function events()
{
return [
ActiveRecord::EVENT_AFTER_FIND => '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;
}
}

0 comments on commit 6a53d6a

Please sign in to comment.