matthewpageuk/laravel-bitty-enums

本包帮助您在 PHP 和 Laravel 中使用位枚举。

v1.0.1 2024-02-11 20:35 UTC

This package is auto-updated.

Last update: 2024-09-11 22:14:40 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads GitHub Issues

如果您选择在 Laravel 应用程序中使用位枚举,此包可以帮助您做到。在使用之前请三思,它提供了一个枚举容器、用于模型查询作用域的 trait 以及模型属性转换。

您可以将此视为一个 hasMany 关系,但使用单个整数列来存储数据。

bitty1

安装

您可以通过 composer 将此包安装到您的 Laravel 项目中。

composer require matthewpageuk/laravel-bitty-enums

使用

创建枚举

您可以使用 bitty-enum:make Artisan 命令创建新的 enum。此命令将在 app/Enums 目录中创建一个新的枚举类,带有您提供的 cases。它将确保值和名称适合与包一起使用。

php artisan bitty-enum:make Colours

要使用自己的 enum 与此包一起使用,它们必须

  • 实现 MatthewPageUK\BittyEnums\Contracts\BittyEnum 接口。
  • 返回类型 int
  • 值应为从 1 开始的 2 的幂

无效的枚举在使用容器时将抛出 BittyEnumException

每个枚举的案例(位)当前限制为 16 个。这可以在您的配置文件中覆盖。

颜色枚举的示例

use MatthewPageUK\BittyEnums\Contracts\BittyEnum;

enum Colour: int implements BittyEnum
{
    case Red = 1;
    case Green = 2;
    case Blue = 4;
    case White = 8;
    case Black = 16;
    case Pink = 32;
}

使用 Bitty Enum 容器

容器用于存储选定的枚举值。它是整数值的包装器,并提供管理检查值的方法。它还执行您设置的值的验证,以防止意外滥用。

创建容器

您可以使用 Laravel 应用中的 Contract 绑定创建新容器。

use App\Enums\Colour;
use MatthewPageUK\BittyEnums\Contracts\BittyContainer;

$container = app()->make(BittyContainer::class)->setClass(Colour::class);

这将创建一个适合 Colour 枚举的容器。

您还可以直接使用 MatthewPageUK\BittyEnums\Support\Container

use MatthewPageUK\BittyEnums\Support\Container as BittyContainer;

$favouriteColours = (new BittyContainer(Colour::class))
    ->set(Colour::Red)
    ->set(Colour::Green)
    ->set(Colour::Blue);

示例用法

// Set values
$favouriteColours = app()->make(BittyContainer::class)
    ->setClass(Colour::class)
    ->set(Colour::Red)
    ->set(Colour::Green)
    ->set(Colour::Blue);

// Passing an array of values
$favouriteColours = app()->make(BittyContainer::class)
    ->setClass(Colour::class)
    ->set([Colour::Red, Colour::Green, Colour::Blue]);

// Unset a value
$favouriteColours->unset(Colour::Red);

// Check if the container has a value
if ($favouriteColours->has(Colour::Red)) {
    echo 'Red is one of your favourite colours';
}

// Check if the container has any of the values
if ($favouriteColours->hasAny([Colour::Red, Colour::Green])) {
    echo 'You like red or green';
}

// Check if the container has all of the values
if ($favouriteColours->hasAll([Colour::Red, Colour::Green])) {
    echo 'You like red and green';
}

// Pass another container to check if any of the values exist
if ($product->colours->hasAny($favouriteColours)) {
    echo 'This product is available in one of your favourite colours';
}

容器公共方法

public function __construct(string $class, int $selected = 0);

public function clear(): BittyContainer;

public function getChoices(): array;

public function getValue(): int;

public function has(BittyEnum $choice): bool;

public function hasAll(array|BittyContainer $choices): bool;

public function hasAny(array|BittyContainer $choices): bool;

public function set(array|BittyContainer|BittyEnum $choice): BittyContainer;

public function setAll(): BittyContainer;

public function unset(array|BittyContainer|BittyEnum $choice): BittyContainer;

验证

容器还对您设置的值执行验证,如果您尝试设置无效的值或枚举格式不正确,将抛出 BittyEnumException

模型属性转换

您可以使用 MatthewPageUK\BittyEnums\Casts\BittyEnumCast 转换将模型上的 integer 列转换为 BittyEnumContainer

您必须将您打算使用的枚举类作为第二个参数传递。

您的数据库列应该是 BIGINT

@todo 请参阅枚举的位限制,我们能有几个?

示例 Laravel 模型

Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->unsignedBigInteger('colours');
    $table->unsignedInteger('price');
    $table->timestamps();
});

use App\Enums\Colour;
use MatthewPageUK\BittyEnums\Casts\BittyEnumCast;

class Product extends Model
{
    protected $casts = [
        'colours' => BittyEnumCast::class . ':' . Colour:class,
    ];
}

现在您可以使用容器方法直接从模型属性更新和检索枚举值。

示例用法

$product = Product::find(1);
$product->colours->set(Colour::Blue)->unset(Colours::Red);
$product->save();
// Check if value exists
$product = Product::find(1);
if ($product->colours->has(Colour::Blue)) {
    echo 'This product is available in blue';
}
// Check if any of the values exist
$customerPreferences = app()->make(BittyContainer::class)
    ->setClass(Colour::class)
    ->set(Colour::Blue)
    ->set(Colour::Red)
    ->set(Colour::Green);

$product = Product::find(1);
if ($product->colours->hasAny($customerPreferences)) {
    echo 'This product is available in one of the customers preferred colours';
}

作用域查询

要访问模型中的作用域查询,您需要使用 MatthewPageUK\BittyEnums\Traits\WithBittyEnumQueryScope trait。

您还应该确保模型具有要在查询上设置的 BittyEnumCast

示例模型

use App\Enums\Colours;
use MatthewPageUK\BittyEnums\Traits\WithBittyEnumQueryScope;

class Product extends Model
{
    use WithBittyEnumQueryScope;

    ...
}

示例查询

// Products with the colour blue
Product::whereBittyEnumHas('colours', Colour::Blue)->get();

// Products with the colour blue or red
Product::whereBittyEnumHasAny('colours', [Colour::Blue, Colour::Red])->get();

// Products with the colour blue and red
Product::whereBittyEnumHasAll('colours', [Colour::Blue, Colour::Red])->get();

// Products without the colour blue
Product::whereBittyEnumDoesntHave('colours', Colour::Blue)->get();

// Products without the colour blue or red
$customerPreferences = new BittyEnumContainer(Colour::class)
    ->set(Colour::Blue)
    ->set(Colour::Red);

Product::whereBittyEnumDoesntHaveAny('colours', $customerPreferences)->get();

接受多个选项的方法可以是 BittyEnumBittyEnumContainer 的数组。

如果您传递错误的类型或无效的枚举到查询作用域,将抛出 BittyEnumException

配置设置

您可以在配置文件中设置容器的最大位数。

return [
    'max_bits' => 16,
];

包测试

composer test

变更日志

请参阅变更日志以获取有关最近更改的更多信息。

贡献

请参阅贡献指南以获取详细信息。

致谢

许可协议

MIT 许可协议 (MIT)。请参阅许可文件以获取更多信息。