-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
584 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
|
||
namespace ethercap\common\behaviors; | ||
|
||
use ethercap\common\helpers\ArrayHelper; | ||
use ethercap\common\helpers\RuleHelper; | ||
|
||
/** | ||
* 主要是与DictValidator配合使用 | ||
* 提供getter方法,可以通过 $model->{attribute}_desc获取值的描述 | ||
* 提供setter方法,可以通过 $model->{attribute}_desc = $value | ||
* | ||
* 用法: | ||
* 在model的behaviors中加入如下行: | ||
* [ | ||
* 'class' => DictBehavior, | ||
* 'attributes' => ['status', 'type'], | ||
* ], | ||
* | ||
* //同时,请确保你在rules中加入了DictValidator, 如下为示例: | ||
* [ | ||
* ['status', DictValidator::class, 'list'=> self::$statusArr], | ||
* // ... | ||
* ] | ||
* | ||
* // 然后你就可以很方便的访问值了. | ||
* echo $model->status_desc; | ||
*/ | ||
class DictBehavior extends PropertyBehavior | ||
{ | ||
public $ending = '_desc'; | ||
public $validatorClass = \ethercap\common\validators\DictValidator::class; | ||
|
||
protected function getValueByName($name) | ||
{ | ||
is_null($this->defaultValue) && $this->defaultValue = $this->owner->$name; | ||
$validator = RuleHelper::getAttributeValidator($this->owner, $name, $this->validatorClass); | ||
if ($validator) { | ||
return $this->getValueByValidator($validator, $name); | ||
} | ||
return $this->defaultValue; | ||
} | ||
|
||
protected function getValueByValidator($validator, $name) | ||
{ | ||
$value = $this->owner->$name; | ||
is_null($this->defaultValue) && $this->defaultValue = $value; | ||
if ($validator) { | ||
if (is_array($value)) { | ||
$ret = []; | ||
foreach ($value as $val) { | ||
$ret[] = ArrayHelper::getValue($validator->list, $val, $this->defaultValue); | ||
} | ||
return $ret; | ||
} else { | ||
return ArrayHelper::getValue($validator->list, $value, $this->defaultValue); | ||
} | ||
} else { | ||
throw new \Exception("{$name} 不存在 {$this->validatorClass}"); | ||
} | ||
return $value; | ||
} | ||
|
||
public function setValueByName($name, $value) | ||
{ | ||
$validator = RuleHelper::getAttributeValidator($this->owner, $name, $this->validatorClass); | ||
if ($validator) { | ||
$list = $validator->list; | ||
foreach ($validator->list as $key => $val) { | ||
if ($val === $value) { | ||
$this->owner->$name = $key; | ||
return; | ||
} | ||
} | ||
} else { | ||
throw new \Exception("{$name} 不存在 {$this->validatorClass}"); | ||
} | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
|
||
namespace ethercap\common\behaviors; | ||
|
||
use Closure; | ||
|
||
/** | ||
* 提供jsonModel的便利使用 | ||
* [ | ||
* 'class' => JsonModelBehavior::class, | ||
* 'attributes' => ['attr'], | ||
* 'modelClass' => xxModel::class, // 也可以传入匿名函数 function($val) {return xxModelClass; } | ||
* ] | ||
* | ||
* //访问attr的model | ||
* $model->attr_jmodel | ||
* $model->attr_jmodel = new xxxModel(); | ||
* $model->attr_jmodel->attribute = "hello world"; | ||
* // save时会将model的数据自动存入数据库中 | ||
* $model->save() | ||
*/ | ||
class JsonModelBehavior extends SerializeBehavior | ||
{ | ||
public $ending = '_jmodel'; | ||
public $defaultValue = '{}'; | ||
public $modelClass = null; | ||
|
||
//通过数组获取Model | ||
public function getModelByValue($arr) | ||
{ | ||
$modelClass = $this->modelClass; | ||
if ($modelClass instanceof Closure || (is_array($modelClass) && is_callable($modelClass))) { | ||
$modelClass = call_user_func($modelClass, $arr); | ||
} | ||
empty($modelClass) && $modelClass = \yii\base\DynamicModel::class; | ||
$model = new $modelClass(); | ||
if (!($model instanceof \yii\base\Model)) { | ||
throw new \Exception("modelClass 必须是\yii\base\Model类"); | ||
} | ||
if ($model instanceof \yii\base\DynamicModel) { | ||
foreach ($arr as $key => $val) { | ||
$model->defineAttribute($key, $val); | ||
} | ||
} else { | ||
$model->load($arr, ''); | ||
} | ||
return $model; | ||
} | ||
|
||
protected function serializeValue($value) | ||
{ | ||
return parent::serializeValue($value->toArray()); | ||
} | ||
|
||
protected function unSerializeValue($value) | ||
{ | ||
$arr = parent::unSerializeValue($value); | ||
return $this->getModelByValue($arr); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
namespace ethercap\common\behaviors; | ||
|
||
use Closure; | ||
|
||
/** | ||
* 提供jsonModel的便利使用 | ||
* [ | ||
* 'class' => JsonModelBehavior::class, | ||
* 'attributes' => ['attr'], | ||
* 'modelClass' => xxModel::class, // 也可以传入匿名函数 function($val) {return xxModelClass; } | ||
* ] | ||
* | ||
* //访问attr的model | ||
* $model->attr_jmodels | ||
* $model->attr_jmodels =[ new xxxModel()]; | ||
* $model->attr_jmodels[0]->attribute = "hello world"; | ||
* // save时会将model的数据自动存入数据库中 | ||
* $model->save() | ||
*/ | ||
class JsonModelsBehavior extends SerializeBehavior | ||
{ | ||
public $ending = '_jmodels'; | ||
public $defaultValue = '[]'; | ||
public $modelClass = null; | ||
|
||
//通过数组获取Model | ||
public function getModelByValue($arr) | ||
{ | ||
$modelClass = $this->modelClass; | ||
if ($modelClass instanceof Closure || (is_array($modelClass) && is_callable($modelClass))) { | ||
$modelClass = call_user_func($modelClass, $arr); | ||
} | ||
empty($modelClass) && $modelClass = \yii\base\DynamicModel::class; | ||
$model = new $modelClass(); | ||
if (!($model instanceof \yii\base\Model)) { | ||
throw new \Exception("modelClass 必须是\yii\base\Model类"); | ||
} | ||
if ($model instanceof \yii\base\DynamicModel) { | ||
foreach ($arr as $key => $val) { | ||
$model->defineAttribute($key, $val); | ||
} | ||
} else { | ||
$model->load($arr, ''); | ||
} | ||
return $model; | ||
} | ||
|
||
protected function serializeValue($value) | ||
{ | ||
$list = []; | ||
foreach ($value as $key => $val) { | ||
$list[$key] = $val->toArray(); | ||
} | ||
return parent::serializeValue($list); | ||
} | ||
|
||
protected function unSerializeValue($value) | ||
{ | ||
$arr = parent::unSerializeValue($value); | ||
$models = []; | ||
foreach ($arr as $key => $val) { | ||
$models[$key] = $this->getModelByValue($val); | ||
} | ||
return $models; | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
namespace ethercap\common\behaviors; | ||
|
||
use yii\helpers\StringHelper; | ||
|
||
/** | ||
* 提供getter/setter方法,可以通过 $model->attribute{ending}获取/改变值 | ||
*/ | ||
abstract class PropertyBehavior extends \yii\base\Behavior | ||
{ | ||
public $ending = '_desc'; | ||
public $defaultValue = null; | ||
public $attributes = []; | ||
|
||
public $canSet = true; | ||
public $canGet = true; | ||
|
||
public function init() | ||
{ | ||
parent::init(); | ||
} | ||
|
||
public function __get($name) | ||
{ | ||
if ($name = $this->getAttributeByStr($name)) { | ||
return $this->getValueByName($name); | ||
} | ||
return parent::__get($name); | ||
} | ||
|
||
public function __set($name, $value) | ||
{ | ||
if ($name = $this->getAttributeByStr($name)) { | ||
return $this->setValueByName($name, $value); | ||
} | ||
return parent::__set($name, $value); | ||
} | ||
|
||
abstract protected function getValueByName($name); | ||
|
||
abstract protected function setValueByName($name, $value); | ||
|
||
protected function getAttributeByStr($name, $ending = null) | ||
{ | ||
empty($ending) && $ending = $this->ending; | ||
if (StringHelper::endsWith($name, $ending)) { | ||
$name = substr($name, 0, -1 * strlen($ending)); | ||
if (in_array($name, $this->attributes)) { | ||
return $name; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
public function canGetProperty($name, $checkVars = true) | ||
{ | ||
$name = $this->getAttributeByStr($name); | ||
if ($name) { | ||
return $this->canGet; | ||
} | ||
return parent::canGetProperty($name, $checkVars); | ||
} | ||
|
||
public function canSetProperty($name, $checkVars = true) | ||
{ | ||
if ($name = $this->getAttributeByStr($name)) { | ||
return $this->canSet; | ||
} | ||
return parent::canSetProperty($name, $checkVars); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
<?php | ||
|
||
namespace ethercap\common\behaviors; | ||
|
||
use Closure; | ||
use yii\db\ActiveRecord; | ||
|
||
/** | ||
* 支持将model上的某个值以其它格式保存和使用 | ||
* // 如下为一个示例,假设 $price存的为分, 我们可以通过如下配置, 然后$model->price_money 获取对应的元 | ||
* [ | ||
* 'class' => SerializeBehavior::class, | ||
* 'ending' => '_money'; | ||
* 'attributes' => ['price'], | ||
* 'unSerializeFunc' => function($val) { | ||
* return number_format($val / 100, 2); | ||
* }, | ||
* 'serializeFunc' => function($val) { | ||
* return intval($val * 100); | ||
* } | ||
* ] | ||
*/ | ||
class SerializeBehavior extends PropertyBehavior | ||
{ | ||
public $ending = '_unser'; | ||
public $defaultValue = null; | ||
|
||
// 如何将数据从原来的格式转为你希望为的格式 | ||
public $unSerializeFunc = [self::class, 'jsonDecode']; | ||
// 如何将数据从你希望为的格式转为原来的格式 | ||
public $serializeFunc = [self::class, 'jsonEncode']; | ||
|
||
private $_buffer = []; | ||
|
||
public function init() | ||
{ | ||
parent::init(); | ||
|
||
if (!($this->unSerializeFunc instanceof Closure || (is_array($this->unSerializeFunc) && is_callable($this->unSerializeFunc)))) { | ||
throw new \Exception('unSerializeFunc 必须是一个可以被调用的函数'); | ||
} | ||
if (!($this->serializeFunc instanceof Closure || (is_array($this->serializeFunc) && is_callable($this->serializeFunc)))) { | ||
throw new \Exception('serializeFunc 必须是一个可以被调用的函数'); | ||
} | ||
} | ||
|
||
public static function returnOrigin($val) | ||
{ | ||
return $val; | ||
} | ||
|
||
public function events() | ||
{ | ||
return [ | ||
ActiveRecord::EVENT_BEFORE_INSERT => 'syncToOrigin', | ||
ActiveRecord::EVENT_BEFORE_UPDATE => 'syncToOrigin', | ||
]; | ||
} | ||
|
||
public static function jsonDecode($value) | ||
{ | ||
$arr = @json_decode($value, true); | ||
empty($arr) && $arr = []; | ||
return $arr; | ||
} | ||
|
||
public static function jsonEncode($value) | ||
{ | ||
return json_encode($value); | ||
} | ||
|
||
protected function unSerializeValue($value) | ||
{ | ||
return call_user_func($this->unSerializeFunc, $value); | ||
} | ||
|
||
protected function serializeValue($value) | ||
{ | ||
return call_user_func($this->serializeFunc, $value); | ||
} | ||
|
||
public function getValueByName($name) | ||
{ | ||
if (isset($this->_buffer[$name])) { | ||
return $this->_buffer[$name]; | ||
} | ||
|
||
$value = $this->owner->$name; | ||
$result = $this->unSerializeValue($value); | ||
$this->_buffer[$name] = $result; | ||
return $result; | ||
} | ||
|
||
public function setValueByName($name, $value) | ||
{ | ||
$this->_buffer[$name] = $value; | ||
} | ||
|
||
// 在更改数据之前,将数据置回 | ||
public function syncToOrigin() | ||
{ | ||
foreach ($this->_buffer as $key => $value) { | ||
$this->owner->$key = $this->serializeValue($value); | ||
} | ||
$this->_buffer = []; | ||
} | ||
} |
Oops, something went wrong.