circulon / yii2-flag-behavior
为 Yii 2.x 实现位运算标志设置
v1.2.2
2015-08-05 10:31 UTC
Requires
- yiisoft/yii2: ~2.0.0
README
为模型管理多个(虚拟)布尔属性提供 Yii 2.x 行为,这些属性存储为单个整数属性。
安装
安装此扩展的首选方式是通过 composer。
运行
$ php composer.phar require circulon/yii2-flag-behavior "*"
或在您的 composer.json
文件的 require
部分添加
"circulon/yii2-flag-behavior": "*"
。
注意
在 MySQL(我没有使用其他数据库)中,我们可以使用 TINYINT、SMALLINT、MEDIUMINT、INT & BIGINT,分别提供 8、16、24、32 & 64 标志。通常,TINYINT(8) 或 SMALLINT(16) 是一个好的起点,这也有助于减少数据库的负担。
使用方法
重要:属性名称必须根据标准属性命名规则在模型中唯一
重要:记录插入后,属性的顺序(即位位置)不能更改。请在第一次插入之前检查您的顺序。
可以无问题地添加额外的标志
将行为添加到模型中
use circulon\flag\FlagBehavior; // Recommended to use constants for // virtual attribute names const SETTINGS_ACTIVE = 'active'; const SETTINGS_ADMIN = 'admin'; const SETTINGS_POST_COMMENTS = 'postComments'; const SETTINGS_VIEW_REPORTS = 'voewReports'; const SETTINGS_CREATE_REPORTS = 'createReports'; public function behaviors() { return [ 'FlagBehavior'=> [ 'class'=> FlagBehavior::className(), 'fieldattribute' => 'flags', // the db field attribute. Default : 'flags' // attributes: $flag => $position // $flag : the attribute name // $position : the bit position (starting at 0) 'attributes' => [ $this::SETTINGS_ACTIVE => 0, // The bit position order once set $this::SETTINGS_ADMIN => 1, // MUST NOT BE CHANGED $this::SETTINGS_POST_COMMENTS => 2, // after any records have been inserted ], // options: $flag => $options // $flag : the source attribute // $options : an array of $operator => $fields // $operator : (set|clear|not) // set: sets the attribute to a given value (true|false|'source') // 'source' will set the attribute to the same as the source ttributes value // if only the attribute name is provided the attribute is set to true // // clear: clears the attributes listed // not: sets the value of the attributes to the inverse/complement of the source attribute 'options' = [ $this::SETTINGS_ADMIN => [ 'set' => [ $this::SETTINGS_POST_COMMENTS, // set to true $this::SETTINGS_ACTIVE, // set to true ] ], $this::SETTINGS_ACTIVE => [ 'set' => [ $this::SETTINGS_POST_COMMENTS => 'source' ], // set same as SETTINGS_ACTIVE ], $this::SETTINGS_CREATE_REPORTS => [ 'set' => [ $this::SETTINGS_VIEW_REPORTS], ], ], ], ]; }
访问
注意:建议使用常量作为属性名称。如果您决定更改属性名称(而非位置),这将适用于所有访问标志的模型。
// get/set db attribute directly $value = $model->fieldAttribute; // initialy set to 0 $model->fieldAttribute = 6; // set flags to admin and post comments (110) // change flags // NOTE: // $model->{<class name>::SETTINGS_ACTIVE} = true; // set flag (now 111) $model->active = true; $model->setFlag({<class name>::SETTINGS_ADMIN}, false); // clear flag (now 101) $model->setFlag('postComments', false); // clear flag (now 001) $model->{<class name>::SETTINGS_ACTIVE} = false; // clear flag (now 000) // check if a flag/setting is set if ($model->{<class name>::SETTINGS_POST_COMMENTS}) { // do something here } if (!$model->active) { // show error message } if ($model->hasFlag({<class name>::SETTINGS_ADMIN})) { // allow admin user to .... }
搜索
您可以简单地为您模型的标志添加条件
注意:这看起来可能有些反直觉(即创建一个空模型),但当创建多模型查询时,这是最简单的方法。如果您有更好或更简单的方法,请告诉我或发送一个 pull request。
示例 1 -- 单个模型搜索
// $model = new MyModelWithFlags() $query = MyModelWithFlags::find(); // add additional criteria as required $query = $model->addFlagsCriteria($query, [ MyModelWithFlags::SETTING_ACTIVE, // Flags with no value are assumed true MyModelWithFlags::SETTING_VIEW_REPORTS => false // optionally set the specific (bool or int 1/0) search value ]); // get records $query->all(); // DataProvider $dataProvider = new ActiveDataProvider(['query' => $query]);
示例 2 -- 复杂(多模型)搜索
$searchQuery = PrimarySearchModel::find(); // add criteria.... $model = new MyModelWithFlags() $searchQuery = $model->addFlagsCriteria($searchQuery, [ MyModelWithFlags::SETTING_ACTIVE, // Flags with no value are assumed true MyModelWithFlags::SETTING_VIEW_REPORTS => false // optionally set the specific (bool or int 1/0) search value ], true); // generate tablename prefixes $otherModel = new MyOtherModelWithFlags() // add additional criteria as required $searchQuery = $otherModel->addFlagsCriteria($searchQuery, [ MyOtherModelWithFlags::SETTING_OTHER => true, MyOtherModelWithFlags::SETTING_SOME_SETTING => false, MyOtherModelWithFlags::SETTING_WORKING, ], true); // generate tablename prefixes // get records $searchQuery->all(); // DataProvider $dataProvider = new ActiveDataProvider(['query' => $searchQuery]);