datomatic/laravel-enum-helper

简单的、有偏见的、框架无关的PHP 8.1枚举助手,用于Laravel

v1.1.0 2024-03-14 14:35 UTC

This package is auto-updated.

Last update: 2024-09-14 15:54:41 UTC


README

Enum Helper-DarkEnum Helper-Light

Laravel 枚举助手

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

这是基于 Laravel 框架的 datomatic/enum-helper 包的扩展。该包包含一个 LaravelEnumHelper 特性,它扩展了 EnumInvokableEnumFromsEnumNamesEnumValuesEnumEqualityEnumDescription,并添加了动态方法以返回翻译或“属性”方法和相关辅助方法。

您可以将它视为一个完全动态的 EnumDescription 特性

因此,您可以定义一个自定义 method() 并拥有以下函数:[method]s()[method]sByName()[method]sByValue()。例如,使用 color(),您将获得 colors()colorsByName()colorsByValue() 方法。

酷的地方在于,您还可以避免编写方法,只编写翻译。例如,您可以通过在 enums.php 中仅编写翻译来定义属性 excerpt(参见下面的说明),并获得 excerpt()excerpts()excerptsByName()excerptsByValue() 方法。

该包使用 Laravel Pluralizer 组件 来获取要调用的单数方法或进行翻译。

相关包

enum-helper 基础包总结

您可以在 其存储库 上看到 datomatic/enum-helper 的详细信息,这是一个总结。

  • 可调用情况:通过静态调用枚举值来获取枚举值
  • 按名称或值构造枚举:为所有枚举提供 from()tryFrom()fromName()tryFromName()
  • 枚举检查:提供 isPure()isBacked()has()hasName()hasValue() 方法
  • 枚举相等性:提供 is()isNot()in()notIn() 方法
  • 名称:提供获取案例名称列表的方法(names()namesByValue()
  • :提供获取案例值列表的方法(values()valuesByName()
  • 唯一 ID:从实例或标识符获取唯一标识符(uniqueId()fromUniqueId()
  • 描述和翻译:为枚举添加描述(可选翻译)(description()descriptions()descriptionsByName()descriptionsByValue()

安装

需要 Laravel 8 或以上版本和 PHP 8.1+。

composer require datomatic/laravel-enum-helper

使用方法

您可以通过使用 LaravelEnumHelper 特性来简单地使用此功能。

use Datomatic\LaravelEnumHelper\LaravelEnumHelper;

// Pure enum 
enum Status
{
    use LaravelEnumHelper;

    case PENDING;
    case ACCEPTED;
    case DISCARDED;
    case NO_RESPONSE;

    public function color(): string
    {
        return match ($this) {
            self::PENDING => '#000000',
            self::ACCEPTED => '#0000FF',
            self::DISCARDED => '#FF0000',
            self::NO_RESPONSE => '#FFFFFF',
        };
    }
}

// BackedEnum
enum StatusString
{   
    use LaravelEnumHelper;

    case PENDING = 'P';
    case ACCEPTED = 'A';
    case DISCARDED = 'D';
    case NO_RESPONSE = 'N';
    
    // or public function color(?string $lang = null): string
    public function color(): string
    {
        ...
    }

之后,您可以定义一个自定义的 "属性" 方法,如 color()color(?string $lang = null),或者定义翻译。

翻译

使用此特性,有两种方式来管理翻译字符串。

使用简短键

语言字符串可以存储在 lang 目录下的 enums.php 文件中。在此目录中,可能存在每个由应用程序支持的子目录。

/lang
    /en
        enums.php
    /it
        enums.php

所有语言文件都返回一个键字符串数组。数组有3级

  • 第一级键:枚举的完整类名
  • 第二级键:要翻译的属性名
  • 第三级键:枚举情况的名字/值。

默认属性是 description,因此如果您只使用该属性,则可以使用仅两级数组的结构。

// /lang/it/enums.php

return [
    // If you need to translate just the description property
    Status::class => [
        Status::PENDING() => 'In attesa', // using invokable trait functionality
        'ACCEPTED' => 'Accettato', // using the name of pure enum case
        'DISCARDED' => 'Rifiutato',
        'NO_RESPONSE' => 'Nessuna Risposta',
    ],
     // If you need to translate multiple properties (e.g. description, excerpt)
    StatusString::class => [
        'description' => [ // using invokable trait functionality
            StatusString::PENDING() => 'In attesa',
            StatusString::ACCEPTED() => 'Accettato',
            ...
        ],
        'excerpt' => [ // using the value of BackedEnum case
            "P" => 'In attesa',
            "A" => 'Accettato',
    ...

使用翻译字符串作为键

语言字符串以 JSON 文件的形式存储在 lang 目录中(例如,lang/it.json)。在此示例中,已翻译 description 属性。

{
  "enums.Namespace\\StatusString.description.P": "In attesa",
  "...":"..."
}

但是,如果您想使用这种方式,您只需在枚举类上定义该方法即可,如 description 方法。

public function description(?string $lang = null): string
{
    return match ($this) {
        self::PENDING => __('Await decision', $lang),
        self::ACCEPTED => __('Recognized valid', $lang),
        self::DISCARDED => __('No longer useful', $lang),
        self::NO_RESPONSE => __('No response', $lang),
    };

[property]() 方法

此动态方法尝试在枚举上解析 property() 方法。
如果不存在该方法,则尝试使用框架的翻译函数 __("enums.Namespace\EnumClass.property.CASE_NAME") 将实例值翻译。
因为默认属性是 description,如果没有翻译该属性,将使用人类化的情况名称作为后备。对于其他属性,如果不存在翻译,则包抛出 TranslationMissing 异常。

静态 [property]s() 方法

此动态方法获取枚举返回的案例 property() 列表。方法名称是属性的复数形式,因此如果您使用 property,则将是 properties()

StatusString::descriptions(); // ['Await decision','Recognized valid','No longer useful','No response']
StatusString::colors(); // ['#000000','#0000FF','#FF0000','#FFFFFF']
// Subset
StatusString::descriptions([StatusString::ACCEPTED, StatusString::NO_RESPONSE]); // ['Recognized valid','No response']
StatusString::colors([StatusString::ACCEPTED, StatusString::NO_RESPONSE]); // ['#0000FF','#FFFFFF']
// Forcing language
Status::descriptions(null, 'it'); // 🇮🇹 ['In attesa','Accettato','Rifiutato','Nessuna Risposta']
StatusString::colors(null, 'it'); // ['#000000','#0000FF','#FF0000','#FFFFFF']
// Subset and language 
Status::descriptions([Status::NO_RESPONSE, Status::DISCARDED], 'it'); // 🇮🇹 ['Nessuna Risposta', 'Rifiutato']
StatusString::colors([StatusString::ACCEPTED, StatusString::NO_RESPONSE], 'it'); // ['#0000FF','#FFFFFF']

静态 [property]sByName() 方法

此动态方法返回一个关联数组 [case name => property() 结果]。方法名称是属性的复数形式,因此如果您使用 property,则将是 propertiesByName()

StatusString::descriptionsByName(); // ['PENDING' => 'Await decision', 'ACCEPTED' => 'Recognized valid',...
StatusString::colorsByName(); // ['PENDING' => '#000000','ACCEPTED' => '#0000FF',...
Status::descriptionsByName(); // ['PENDING' => 'Await decision', 'ACCEPTED' => 'Recognized valid',...
// Subset
StatusString::descriptionsByName([StatusString::DISCARDED, StatusString::ACCEPTED]); // ['DISCARDED' => 'No longer useful', 'ACCEPTED' => 'Recognized valid']
Status::descriptionsByName([[Status::PENDING, Status::DISCARDED]); // ['PENDING' => 'Await decision', 'DISCARDED' => 'No longer useful']
// Forcing language
StatusString::descriptionsByName(null, 'it'); // 🇮🇹 ['P' => 'In attesa','A' => 'Accettato',...
// Subset and language 
Status::descriptionsByName([Status::DISCARDED, Status::NO_RESPONSE], 'it'); // 🇮🇹 ['DISCARDED' => 'Rifiutato','NO_RESPONSE' => 'Nessuna Risposta',...

静态 [property]sByValue() 方法

此动态方法返回一个关联数组 [case value => property() 结果] 在 BackedEnum 上,[case name => property() 结果] 否则。方法名称是属性的复数形式,因此如果您使用 property,则将是 propertiesByValue()

Status::descriptionsByValue(); // ['PENDING' => 'Await decision', 'ACCEPTED' => 'Recognized valid',...
StatusString::descriptionsByValue(); // ['P' => 'Await decision', 'A' => 'Recognized valid',...
StatusString::colorsByValue(); // ['P' => '#000000','A' => '#0000FF',...
// Subset
Status::descriptionsByValue([Status::PENDING, Status::DISCARDED]); // ['PENDING' => 'Await decision', 'DISCARDED' => 'No longer useful']
StatusString::descriptionsByValue([StatusString::DISCARDED, StatusString::ACCEPTED]); // ['D' => 'No longer useful', 'A' => 'Recognized valid']
StatusString::colorsByValue([[Status::PENDING, Status::DISCARDED]); // ['P' => '#000000', 'D' => '#FF0000']
// Forcing language
StatusString::descriptionsByValue(null, 'it'); // 🇮🇹 ['P' => 'In attesa','A' => 'Accettato',...
// Subset and language 
Status::descriptionsByValue([StatusString::DISCARDED, StatusString::NO_RESPONSE], 'it'); // 🇮🇹 ['DISCARDED' => 'Rifiutato','NO_RESPONSE' => 'Nessuna Risposta',...