ancor/yii2-bitmask

模型中的位掩码行为和验证器

安装数: 8 178

依赖关系: 0

建议者: 0

安全性: 0

星星: 5

关注者: 2

分支: 0

类型:yii2-extension

dev-master 2016-03-17 11:33 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:04:01 UTC


README

描述

本扩展旨在处理位掩码。

例如,您想将多个开关的值存储在类型为 int 的字段中。

会产生一些问题

  • 如何根据场景允许只分配或取消分配某些位,而禁止其他位
  • 如何将 input[type=checkbox] 标签绑定到相应的位
  • 在哪里存储输入字段的标签
  • 如何输出选中的位
  • 如何方便地检查模型字段中是否存在位
  • 最后如何方便地设置或取消位

yii2-bitmask 解决了所有这些问题

欢迎通过以下方式告诉我您想添加的其他内容

安装

安装此扩展的首选方法是通过 composer

运行以下命令之一

$ php composer.phar require ancor/yii2-bitmask

"ancor/yii2-bitmask": "dev-master"

将以下内容添加到您的 composer.json 文件的 require 部分中。

扩展包含三个类

BitmaskBehavior

模型配置

use ancor\bitmask\BitmaskBehavior;

/**
 * @property integer $options
 * ...
 * @property string $spamOption
 * @property string $deletedOption
 * ...
 */
class User extends \yii\db\ActiveRecord
{
    const OPT_SPAM    = 1<<0;
    const OPT_DELETED = 1<<1;

    public function behaviors()
    {
        return [
            'bitmask' => [
                'options' => [
                    'spamOption'    => static::OPT_SPAM,
                    'deletedOption' => static::OPT_DELETED,
                ],
                // 'bitmaskAttribute' => 'options', // an attribute which is the mask itself
            ],
        ];
    }

    public function rules()
    {
        return [
            [['spamOption', 'deletedOption'], 'safe'],
        ];
    }

    public function attributeLabels()
    {
        return [
            ...
            'spamOption'       => 'This user is spammer',
            'emailNotVerified' => 'User is deleted',
            ...
        ];
    }
}

示例用法

$model = new User();

echo $model->options; // 0

// Назначить бит
$model->spamOption = true; // $model->options == User::OPT_SPAM == 1<<0 == 1
// Это эквивалентно следующей строке
$model->options = $model->options | User::OPT_SPAM;
// Внимание! При присваивании значения - любое значение принудительно преобразуется в boolean

// Снять бит
$model->spamOption = false; // $model->options == 0
// Это эквивалентно следующей строке
$model->options = $model->options & ~User::OPT_SPAM;

// Проверить наличие бита
if ($model->spamOption) ...
// Это эквивалентно следующей строке
if ($model->options & User::OPT_SPAM) ...

分组分配

// Предположим пришла форма
$post = [
    'User' => [
        ...
        'spamOption'    => false,
        'deletedOption' => true,
        ...
    ],
];

/**
 * Загрузка одной коммандой
 */
echo $model->options; // 0
$model->load($post); 

echo $model->options; // $model->options == 1<<1 == 2
var_dump($model->spamOption);    // false
var_dump($model->deletedOption); // true


/**
 * Пример БЕЗ BitmaskBehavior, при отправке той же самой формы
 * Предположим что в модели объявлены 2 свойства
 *   public $spamOption;
 *   public $deletedOption;
 */

echo $model->options; // 0
$model->load($post);

// Свойство options, конечно же осталось без изменений
echo $model->options; // 0

if ($post['User']['spamOption']) {
	$model->options |= User::OPT_SPAM;
} else {
	$model->options &= ~User::OPT_SPAM;
}
if ($post['User']['deletedOption']) {
	$model->options |= User::OPT_DELETED;
} else {
	$model->options &= ~User::OPT_DELETED;
}

使用 ActiveForm 的模板示例

$form->field($model, 'spamOption')->checkbox();
$form->field($model, 'deletedOption')->checkbox();

注意:如果您想禁止更改某些位,则只需不要在 safe 验证器中列出它们即可

模型的新方法和属性

php public integer[] getBitmaskFields(void)

此方法返回一个包含字段名称及其对应位的数组。默认无值

示例响应(在我们的案例中)

[
    'spamOption'    => 1, // 1<<0
    'deletedOption' => 2, // 1<<1
]

php public boolean[] getBitmaskValues(void) 此方法返回包含字段名称及其值的 true\false 数组。

示例响应(在我们的案例中)

[
    'spamOption'    => false,
    'deletedOption' => true,
]

php public boolean getOldBit(string $field) 返回“旧”属性的值。(通过调用 ->getOldAttribute() 实现)

行为自定义静态方法

将位添加到掩码中\从掩码中删除位

public static integer modifyBitmask(int $mask, int $bit, boolean $exists)
$mask = 0b00100001;
$bit  = 0b00000100;

// Добавить бит
$options = BitmaskBehavior::modifyBitmask($mask, $bit, true); // 0b00100101
// Убрать бит
$options = BitmaskBehavior::modifyBitmask($mask, $bit, false); // 0b00100001

根据位掩码获取位数组

public static boolean[] parseBitmask(int $mask, int[] $fields)
$mask = 0b00100000;
$fields = [
    'firstOption'  => 0b00000001,
    'secondOption' => 0b00100000,
];

$values = BitmaskBehavior::parseBitmask($mask, $fields);
print_r($values); // ['firstOption' => false, 'secondOption' => true]

根据位数组创建位掩码

php public static int makeBitmask(boolean[] $values, int[] $fields)

$fields = [
    'firstOption'  => 0b00000001,
    'secondOption' => 0b00100000,
];
$values = [
    'firstOption'  => false,
    'secondOption' => true
];

$mask = BitmaskBehavior::makeBitmask($values, $fields);
echo $mask; // 0b00100000

BitmaskValidator

描述: 允许指定哪些位可以更改,哪些位不可以。

注意:此验证器可以在没有 BitmaskBehavior 的情况下使用。

public function rules()
{
    return [
        ['options', BitmaskValidator::className(), 'mask' => 1<<3 | 1<<4 | 1<<6],
        // Или с переводом сообщения
        ['options', BitmaskValidator::className(), 'mask' => 1<<3 | 1<<4 | 1<<6, 'message' => ...],
        // Можно так же использовать константы
        ['options', BitmaskValidator::className(), 'mask' => static::OPT_SPAM],
    ];
}

BitmaskFieldsValidator

描述

  • 此验证器类似于 BitmaskValidator
  • 旨在与 BitmaskBehavior 一起使用。
  • 用于替代 safe 验证器。但这不仅仅如此。
  • 验证器与 BitmaskValidator 一样,阻止更改所有位,除非验证器应用于它们。

示例用法

return [
    [
        ['spamOption', 'deletedOption'],
        BitmaskFieldsValidator::className(),
        // 'maskAttribute' => 'options', // По умолчанию
    ],
];