Browse Source

readme

master
LIERLIER 1 year ago
commit
9aad868b46
  1. 241
      readme.md

241
readme.md

@ -0,0 +1,241 @@
# status-combination 融合状态
### Configuration
##### 添加文件: `StatusBehavior.php`
```php
<?php
namespace {yourApp}\behaviors;
use yii\base\Behavior;
use yii\db\ActiveRecord;
use yii\db\Expression;
class StatusBehavior extends Behavior
{
/**
* [
* 融合属性 => [
* 状态位 => 状态名
* ]
* ...
* ]
* @var array[] $statusAttributes 融合状态表
*/
public $statusAttributes = [];
public function events()
{
return [
ActiveRecord::EVENT_BEFORE_INSERT => 'beforeSave',
ActiveRecord::EVENT_BEFORE_UPDATE => 'beforeUpdate',
ActiveRecord::EVENT_AFTER_FIND => 'afterFind',
];
}
public function beforeSave()
{
foreach ($this->statusAttributes as $field => $attributes) {
$this->owner->$field = 0;
$this->setStatusCombination($field, $attributes);
}
}
public function beforeUpdate()
{
foreach ($this->statusAttributes as $field => $attributes) {
$this->setStatusCombination($field, $attributes);
}
}
public function afterFind()
{
$owner = $this->owner;
foreach ($this->statusAttributes as $field => $attributes) {
$status = $owner->$field;
foreach ($attributes as $pos => $attribute) {
$owner->$attribute = ($status & 1 << $pos) >> $pos;
}
}
}
/**
* 设置融合字段
* @param string $field 融合字段名
* @param string[] $attributes 字段
*/
public function setStatusCombination($field, $attributes)
{
$owner = $this->owner;
foreach ($attributes as $pos => $attribute) {
$status = $owner->$attribute;
if ($status === null) {
continue;
}
$owner->$field = $this->getUpdateStatusCombination($owner->$field, $pos, $status);
}
}
/**
* 获得更新后的融合状态
* @param int $statusCombination 融合状态
* @param int $pos 状态位置
* @param bool|int $status 状态
* @return int
*/
public function getUpdateStatusCombination($statusCombination, $pos, $status)
{
if ($status) {
$statusCombination = $statusCombination | 1 << $pos;
} else {
$statusCombination = $statusCombination & ~(1 << $pos);
}
return $statusCombination;
}
}
```
##### 在需要的`Model`里添加`Behavior`
```php
<?php
namespace {yourApp}\models;
use {yourApp}\behaviors\StatusBehavior;
class MyModel extends base\MyModel
{
/**
* @var int 状态
*/
public $s0;
public $s1;
public $s2;
public $s3;
public $s5;
public $s6;
public $s7;
public $s8;
/**
* 融合状态表:
* [
* 融合属性 => [
* 状态位 => 状态名
* ]
* ...
* ]
*/
const STATUS_ATTRIBUTES = [
'status' => [
's0',
's1',
's2',
's3',
],
// 'flags' => [
// 's5', 's6', 's7', 's8'
// ]
];
// 其他Model代码......
public function behaviors()
{
return [
// 其他Behavior
'statusBehavior' => [
'class' => StatusBehavior::class,
'statusAttributes' => self::STATUS_ATTRIBUTES,
],
];
}
/**
* {@inheritdoc}
* 重写find()返回自定义查询类
*/
public static function find()
{
$config = ['statusAttributes' => self::STATUS_ATTRIBUTES];
return new MyModelQuery(get_called_class(), $config);
}
}
```
##### 添加文件 `MyModelQuery`
```php
<?php
namespace {yourApp}\models;
use yii\db\ActiveQuery;
use yii\db\Expression;
class GoodQuery extends ActiveQuery
{
/**
* [
* 融合属性 => [
* 状态位 => 状态名
* ]
* ...
* ]
* @var array[] $statusAttributes 融合状态表
*/
public $statusAttributes;
/**
* @param string[] $queryParams
* @return GoodQuery
*/
public function andWhereStatus($queryParams = [])
{
return $this->andWhere($this->getStatusCondition($queryParams));
}
/**
* @param string[] $queryParams
* @return GoodQuery
*/
public function orWhereStatus($queryParams = [])
{
return $this->orWhere($this->getStatusCondition($queryParams));
}
/**
* @param array $queryParams
* @return Expression
*/
public function getStatusCondition($queryParams = [])
{
$queryAttributes = array_keys($queryParams);
foreach ($this->statusAttributes as $field => $attributes) {
$mask = $res = 0;
foreach ($attributes as $pos => $attribute) {
if (in_array($attribute, $queryAttributes)) {
$mask += 1 << $pos;
$res += $queryParams[$attribute] << $pos;
}
}
if ($mask != 0) {
$conditions[] = "$field & $mask = $res";
}
}
return new Expression(implode('and', $conditions));
}
}
```
### Usage
##### Search
```php
$myModels = MyModel::find()
->andWhereStatus(['s0' => 1, 's1' => 0])
->orWhereStatus(['s2' => 0, 's3' => 1])
->all();
```
Loading…
Cancel
Save