-
-
Save janusnic/889313b16f030ebc7023 to your computer and use it in GitHub Desktop.
OctoberCMS Model behavior that allows to store some model's attributes in json format in grouping fields in db.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php namespace Path\To\Behaviors; | |
use System\Classes\ModelBehavior; | |
/** | |
* Model behavior that allows to store some model's attributes | |
* in json format in grouping fields in db. | |
* | |
* USAGE: In your model add | |
* | |
* public $implement = ['Path.To.Behaviors.SerializableModel']; | |
* | |
* And define property "serializable": | |
* | |
* $serializable = [ | |
* 'my_settings' => [ | |
* 'rows_count', | |
* 'cols_count', | |
* 'some_another_attribute' | |
* ], | |
* 'another_json_group_field' => [ | |
* 'attribute3', | |
* 'attribute4' | |
* ] | |
* ]; | |
*/ | |
class SerializableModel extends ModelBehavior | |
{ | |
protected $requiredProperties = ['serializable']; | |
protected $serializableKeys = []; | |
protected $additionalFields = []; | |
public function __construct($model) | |
{ | |
parent::__construct($model); | |
$jsonable = $this->model->jsonable; | |
foreach ($this->model->serializable as $json_field => $serializable_fields) { | |
array_push($jsonable, $json_field); | |
array_push($this->serializableKeys, $json_field); | |
} | |
$this->model->jsonable = $jsonable; | |
$this->model->bindEvent('model.afterFetch', [$this, 'afterModelFetch']); | |
$this->model->bindEvent('model.saveInternal', [$this, 'saveModelInternal']); | |
$this->model->bindEvent('model.beforeSave', [$this, 'beforeModelSave']); | |
} | |
/** | |
* Populate the field values from the database record. | |
*/ | |
public function afterModelFetch() | |
{ | |
foreach ($this->serializableKeys as $json_field) { | |
// Get additional fields from db (auto converted from json) | |
$this->additionalFields[$json_field] = $this->model->$json_field ?: []; | |
// Add additional fields to model's regular attributes | |
$this->model->attributes = array_merge($this->additionalFields[$json_field], $this->model->attributes); | |
} | |
} | |
/** | |
* Internal save method for the model | |
* @return void | |
*/ | |
public function saveModelInternal() | |
{ | |
foreach ($this->serializableKeys as $json_field) { | |
$serializableKeys = array_flip($this->model->serializable[$json_field]); | |
// Purge the field values from the attributes | |
$attributes = array_diff_key($this->model->attributes, $serializableKeys); | |
$this->additionalFields[$json_field] = array_intersect_key($this->model->attributes, $serializableKeys); | |
$this->model->attributes = $attributes; | |
} | |
} | |
/** | |
* Before the model is saved, ensure the record code is set | |
* and the jsonable field values | |
*/ | |
public function beforeModelSave() | |
{ | |
foreach ($this->serializableKeys as $json_field) { | |
if ($this->additionalFields[$json_field]) { | |
$this->model->$json_field = $this->additionalFields[$json_field]; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
awesome code ! thanks !
line 3ç need to be changed to $jsonable = $this->model->getJsonable();
it does not seems to work entirely with a pivot model.
the data are well saved but there are not fetched back up, the event afterFetch is never trigered in the pivot model. Any idea why ?