faizansf/laravel-metafields

此包通过引入元字段功能来增强Laravel模型。

1.0.2 2024-01-31 19:00 UTC

This package is auto-updated.

Last update: 2024-10-01 00:17:15 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status

Laravel Metafields 包是一个灵活且强大的工具,专为需要通过元字段功能扩展其模型的Laravel开发者设计。此包使您能够轻松地将附加的自定义字段(元字段)附加到Laravel应用程序中的任何Eloquent模型,提供了一个无缝的方式,在不更改数据库模式的情况下增强模型。

用例

此包非常适合需要额外数据存储的项目,如CMS、电子商务平台和自定义CRM系统。当需要保持数据库模式不变的同时允许数据扩展时,尤其有用。

安装

您可以通过composer安装此包

composer require faizansf/laravel-metafields

您可以使用以下命令发布和运行迁移

php artisan vendor:publish --tag="metafields-migrations"
php artisan migrate

注意
在运行迁移之前,请确保您已设置正确的配置

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="metafields-config"

配置

return [
    // The name of the database table to store metafields.
    'table' => 'metafields',

    // The name of the column in the 'meta_fields' table that references the model.
    'model_column_name' => 'model',

    // An array of classes that are allowed to be unserialized.
    'unserialize_allowed_class' => [],

    // The class responsible for serializing the values stored in metafields.
    'default_serializer' => \FaizanSf\LaravelMetafields\Support\ValueSerializers\StandardValueSerializer::class,

    // Flag to enable or disable caching of metafields.
    'cache_metafields' => true,

    // Time-to-live for cached meta fields. Null indicates caching forever.
    'cache_ttl' => null,

    // The prefix used for cache keys when storing individual metafield values.
    'cache_key_prefix' => 'LaravelMetafields',

    //Block keys from being used as metafield keys
    'not_allowed_keys' => [],
    
    //Cache key for all metafields collection
    'all_metafields_cache_key' => 'all-metafields'
];

在模型中集成

Metafiedable 协议和 HasMetafields 特性集成到您的模型中

...
use FaizanSf\LaravelMetafields\Concerns\HasMetafields;
use FaizanSf\LaravelMetafields\Contracts\Metafieldable;

class Person extends Model implements Metafieldable
{
    use HasMetafields;
     
    ...
}

用法

要设置元字段,使用以下字符串或字符串支持的枚举键和值

$person = Person::find(1);

//using HasMetafields trait
$person->setMetafield('some-key', 'value')

要获取元字段值,请使用

//using HasMetafields trait
$person->getMetafield('some-key');
$person->getAllMetafields();

在获取元字段时,您也可以提供一个默认值

//using HasMetafields trait
$person->getMetafield('some-key', 'default value');

注意
默认值不会持久化到数据库中,只是在实际值为null时返回

同样,可以按以下方式删除元字段

//using HasMetafields trait
$person->deleteMetafield('some-key');
$person->deleteAllMetaField('some-key');

缓存

默认启用缓存,但可以在您的 metafields.php 配置文件中禁用。要控制模型类中的缓存行为,请添加 $shouldCacheMetafields 属性。在模型中设置此属性将覆盖默认的缓存配置。此外,您可以通过添加 $ttl 属性到您的模型中,指定自定义的时间到生存期(TTL),从而实现精细的缓存持续时间控制。


metafields.php 配置文件中

[
    ...
    // Flag to enable or disable caching of metafields.
    'cache_metafields' => true,
    ...
]

或在您的模型类中

...
class Person extends Model implements Metafieldable
{
    use HasMetafields;
    
    protected $shouldCacheMetafields = true;
    protected $ttl = 600
}

您可以使用 withoutCache() 方法检索非缓存的版本数据。此方法提供了一个简单的方法来绕过缓存,确保您获取最新数据。

//using HasMetafields trait
$person->withoutCache()->getMetafield('some-key');
$person->withoutCache()->getAllMetafields();

序列化

此包包括 StandardValueSerializerDirectValueSerializerJsonValueSerializer 类。您可以在 metafields.php 配置文件中为所有字段选择默认序列化器。此外,您可以在模型中定义 $metafieldSerializers 数组,或者您可以在模型中实现受保护的 registerSerializers() 方法来覆盖默认序列化行为。然后,registerSerializers() 方法将使用 HasMetafields 特性提供的 mapSerializer() 方法注册序列化器。任何添加的自定义序列化器类都必须实现 FaizanSf\LaravelMetafields\Contracts\ValueSerializer 接口。


namespace App\ValueSerializers;

use FaizanSf\LaravelMetafields\Contracts\ValueSerializer;
use Illuminate\Support\Arr;

class CustomSerializer implements ValueSerializer
{
    public function unserialize($serialized): mixed
    {
        //Do some custom logic here
    }

    public function serialize($value): string
    {
        //Do some custom logic here
    }
}

然后在您的模型中

...
class Person extends Model implements Metafieldable
{
    use HasMetafields;
    
    protected function registerSerializers(){
        $this
            ->mapSerializer('some-key', CustomSerializer::class)
            ->mapSerializer(PersonMetafieldsEnum::Name, CustomSerializer::class)
    }
}

或者,您也可以直接在模型中定义 $metafieldSerializers 属性

...
class Person extends Model implements Metafieldable
{
    use HasMetafields;
    
    protected array $metafieldSerializers  = [
         'my-custom-metafield' => CustomSerializer::class,
         ExampleMetafieldsEnum::ExampleField->value => CustomSerializer::class
    ];
}

注意
由于PHP的限制,枚举值不能用作数组键,我们需要利用枚举值进行映射。


在您已经拥有不需要序列化的字符串值的情况下,可以使用 DirectValueSerializer。这允许您绕过通常的序列化过程,简化处理此类预格式化或不可序列化值的过程。

测试

composer test

变更日志

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

鸣谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件