circulon/yii2-flag-behavior

为 Yii 2.x 实现位运算标志设置

安装数: 11,465

依赖项: 0

建议者: 0

安全: 0

星标: 4

关注者: 2

分支: 3

开放问题: 0

类型:yii2-extension

v1.2.2 2015-08-05 10:31 UTC

This package is auto-updated.

Last update: 2024-09-04 22:37:58 UTC


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]);