paulzi / yii2-json-behavior
Yii2 json attribute behavior
Installs: 275 758
Dependents: 8
Suggesters: 0
Security: 0
Stars: 76
Watchers: 7
Forks: 13
Open Issues: 4
Type:yii2-extension
Requires
- php: >=5.4.0
- yiisoft/yii2: ~2.0.0
Requires (Dev)
- phpunit/phpunit: ~4.0
This package is auto-updated.
Last update: 2024-10-30 02:16:05 UTC
README
Auto decode/encode attribute value in json, provide array access and json validator.
WARNING! From version 2.0.14 Yii has built-in DB JSON-type, and this behavior is no longer required.
Install
Install via Composer:
composer require paulzi/yii2-json-behavior
or add
"paulzi/yii2-json-behavior" : "~1.0.0"
to the require
section of your composer.json
file.
Usage
JsonBehavior
Configure your model:
use paulzi\jsonBehavior\JsonBehavior; class Item extends \yii\db\ActiveRecord { public function behaviors() { return [ [ 'class' => JsonBehavior::className(), 'attributes' => ['params'], ], ]; } }
Now you can access to attribute as array:
$item = Item::findOne(1); $item->params['one'] = 'two'; $item->params['two'] = []; $item->params['two']['key'] = true; $item->save(); $item = Item::findOne(1); echo $item['two']['key']; // true
Set attribute via json string:
$item = new Item(); $item->params->set('[2, 4, 42]'); echo $item->params[2]; // 42
Set attribute via array:
$item = new Item(); $item->params->set(['test' => ['one' => 1]]); echo $item->params['test']['one']; // 1
Convert to json string:
$item = new Item(); $item->params['test'] = ['one' => false, 'two' => [1, 2, 3]]; var_dump((string)$item->params); // {"one":false,"two":[1,2,3]}
Convert to array:
$item = new Item(); $item->params->set('{ "one": 1, "two": null, "three": false, "four": "four" }'); var_dump($item->params->toArray());
Check empty:
$item = new Item(); $item->params->set('{}'); var_dump($item->params->isEmpty()); // true
emptyValue
You can set emptyValue
option to define an empty JSON value (default null
). Can be '{}'
, '[]''
or null
.
JsonValidator
Configure your model (see behavior config upper):
use paulzi\jsonBehavior\JsonValidator; class Item extends \yii\db\ActiveRecord { public function rules() { return [ [['params'], JsonValidator::className()], ]; } }
Validate:
$item = new Item(); $item->attributes = ['params' => '{ test: }']; var_dump($item->save()); // false var_dump($item->errors); // ['params' => ['Value is not valid JSON or scalar']]
You can set merge = true
, in this case, instead of replacing all field data of the transmitted data, array_merge()
will be applied with old data in the field (which are taken from oldAttributes
of ActiveRecord). This option can be apply only with ActiveRecord:
use paulzi\jsonBehavior\JsonValidator; class Item extends \yii\db\ActiveRecord { public function rules() { return [ [['params'], JsonValidator::className(), 'merge' => true], ]; } }
JsonField
You can use JsonField
class for other models:
class Item { public $params; public function __constructor() { $this->params = new JsonField(); } } // ... $item = new Item(); $item->params['one'] = 1; var_dump((string)$item->params); // {"one":1}
How To
Usage isAttributeChanged() and getDirtyAttributes()
Yii2 does not provide the ability to inject code to check attribute dirty.
If you need to use methods isAttributeChanged()
or getDirtyAttributes()
, you can override them in model:
/** * @inheritdoc */ public function isAttributeChanged($name, $identical = true) { if ($this->$name instanceof JsonField) { return (string)$this->$name !== $this->getOldAttribute($name); } else { return parent::isAttributeChanged($name, $identical); } } /** * @inheritdoc */ public function getDirtyAttributes($names = null) { $result = []; $data = parent::getDirtyAttributes($names); foreach ($data as $name => $value) { if ($value instanceof JsonField) { if ((string)$value !== $this->getOldAttribute($name)) { $result[$name] = $value; } } else { $result[$name] = $value; } } return $result; }