hxm/extrafield

额外字段包,为Laravel提供简单、可扩展且强大的额外字段实现。

v1.0.20 2023-05-19 09:43 UTC

This package is auto-updated.

Last update: 2024-09-28 05:28:28 UTC


README

Laravel 6.x/7.x/8.x Donate

HoanXuanMai — hxm/extrafield

这是一个用于在Laravel项目模型中添加额外字段的仓库。hxm/extrafield包提供了一种简单灵活的方式,将自定义字段添加到您的Laravel Eloquent模型中。使用此包,您可以轻松定义额外的字段来存储任何类型的数据,例如元数据、设置或首选项。额外字段与模型属性无缝集成,允许您使用与常规属性相同的语法访问和修改它们。此外,该包还提供了一些便捷的功能,如默认值、验证规则和自动转换为各种数据类型。无论是构建小型应用程序还是大型系统,hxm/extrafield都可以帮助您轻松高效地扩展模型。

您无需在现有数据库结构上创建额外的列,只需使用此仓库即可。

安装

使用[Composer]安装包

$ composer require hxm/extrafield

使用[迁移]创建所有表

$ php artisan migrate

您也可以通过在您的AppServiceProvider中添加以下代码来跳过迁移。

function boot()
{
    \HXM\ExtraField\ExtraField::$ignoreMigration = true;
}

基本用法

为了能够向模型添加额外字段,我们只需将接口实现到模型类中。它包含一个内置的特质,因此您可以轻松使用它。

HXM\ExtraField\Contracts\CanMakeExtraFieldInterface 模型类将在实例间共享相同的附加字段

为此,您将有一个专门的特质:HXM\ExtraField\Traits\HasExtraFieldByInstance

use HXM\ExtraField\Contracts\CanMakeExtraFieldInterface;
use HXM\ExtraField\Traits\HasExtraField;

class AnyModel extends Model implements CanMakeExtraFieldInterface
{
    use HasExtraField;
}

HXM\ExtraField\Contracts\CanMakeExtraFieldByInstanceInterface:模型类将在每个实例上拥有其自己的额外字段,用作中间模型类

为此,您将有一个专门的特质:HXM\ExtraField\Traits\HasExtraFieldByInstance

use HXM\ExtraField\Contracts\CanMakeExtraFieldByInstanceInterface;
use HXM\ExtraField\Traits\HasExtraFieldByInstance;

class AnyModel extends Model implements CanMakeExtraFieldByInstanceInterface
{
    use HasExtraFieldByInstance;
}

HXM\ExtraField\Contracts\CanMakeExtraFieldByInstanceInterface:当存在父模型类时使用,联系当前类,以便能够根据子模型类获取额外字段选项

use HXM\ExtraField\Contracts\CanMakeExtraFieldInterface;
use HXM\ExtraField\Traits\HasExtraField;

class ParentModel extends Model implements CanMakeExtraFieldInterface
{   
    use HasExtraField;
    
    public function type()
    {
        return $this->belongsTo(AnyModel::class);
    }
    
    public function getExtraFieldTargetTypeInstance(): CanMakeExtraFieldInterface
    {
        return $this->type;
    }
}

别忘了添加函数 public function getExtraFieldTargetTypeInstance(): CanMakeExtraFieldInterface,这将帮助系统知道您使用哪个关系来访问额外字段

保存额外字段

现在,要向数据库添加额外字段,您只需在您的管理员的控制器上直接使用操作即可

...
use HXM\ExtraField\Actions\UpdateOrCreateFieldAction;
use Illuminate\Http\Request;
use AnyModel;

class Controller ... 
{
    function createOrUpdateExtraField(AnyModel $modelHasExtraField, Request $request, UpdateOrCreateFieldAction $action)
    {
        $action->handle($modelHasExtraField, $request, $allowMissingFields);
    }
}

不用担心,因为数据保存到数据库之前有一个内置的验证系统。

保存额外字段值

HXM\ExtraField\Contracts\CanAccessExtraFieldValueInterface 此合约规定了在模型类上可以添加值的地方,以添加之前添加的额外字段列表中的值

附带的还有一些预构建的特质来确保结构:HXM\ExtraField\Traits\HasExtraFieldValueHXM\ExtraField\Traits\AutoValidationAndSaveExtraFieldValue

use HXM\ExtraField\Contracts\CanMakeExtraFieldByInstanceInterface;
use HXM\ExtraField\Traits\HasExtraFieldByInstance;
use HXM\ExtraField\Contracts\CanAccessExtraFieldValueInterface;
use HXM\ExtraField\Traits\HasExtraFieldValue;
use HXM\ExtraField\Traits\AutoValidationAndSaveExtraFieldValue;

class AnyModel extends Model implements CanMakeExtraFieldByInstanceInterface, CanAccessExtraFieldValueInterface
{
    use HasExtraFieldByInstance;
    use HasExtraFieldValue;
    // use AutoValidationAndSaveExtraFieldValue; 
    // Automatically save Extra Values when model saved
}
use HXM\ExtraField\Contracts\CanMakeExtraFieldInterface;
use HXM\ExtraField\Contracts\CanAccessExtraFieldValueInterface;
use HXM\ExtraField\Traits\HasExtraFieldValue;
use HXM\ExtraField\Traits\AutoValidationAndSaveExtraFieldValue;

class ParentModel extends Model implements CanAccessExtraFieldValueInterface
{
    use HasExtraFieldValue;
    // use AutoValidationAndSaveExtraFieldValue; 
    // Automatically save Extra Values when model saved
    
    public function type()
    {
        return $this->belongsTo(AnyModel::class);
    }
    
    public function getExtraFieldTargetTypeInstance(): CanMakeExtraFieldInterface
    {
        return $this->type;
    }
}

HasExtraFieldValue 将在模型中添加一个 1-n 的关系函数,称为 extraValues()

AutoValidationAndSaveExtraFieldValue 您可以使用它,以便在创建或更新模型类时自动保存值。请注意,在保存当前模型之前,将有一个验证集。您可能不需要使用它,保存值时需要在控制器中手动插入另一段代码

如果您想自己保存它,请从模型类中移除特质。以下代码将帮助您手动保存

...
use HXM\ExtraField\ExtraFieldValueValidation;
use HXM\ExtraField\Actions\SaveExtraFieldValueForTargetAction;
use Illuminate\Http\Request;
use AnyModel;

class Controller ... 
{
    function store(Request $request, SaveExtraFieldValueForTargetAction $action)
    {
        $model = AnyModel::create([
                ...
            ]);
        $validation = new ExtraFieldValueValidation($model, $request->all());
        $action->handle($model, $validation);
    }
}

高级

此仓库与hxm/enum包一起使用。因此,您可以在系统中的许多结构上创建自己的EnumInstances。

首先,不要忘记通过以下命令发布包的配置文件:

$ php artisan vendor:publish --tag=extra_field:config
//extra_field.php
...
return [
    ...
    
    'enums' => [
        AnyModel::class => new \App\Enums\DemoExtraFieldTypeEnums(),
    ]
]

此Enum类必须实现以下接口:HXM\ExtraField\Contracts\ExtraFieldTypeEnumInterface,否则在将其集成到系统中时会出错。

<?php
/**
 * Created by HoanXuanMai
 * @author hoanxuanmai@gmail.com
 */
namespace App\Enums;

use HXM\Enum\Abstracts\EnumBase;
use HXM\ExtraField\Contracts\ExtraFieldTypeEnumInterface;
use HXM\ExtraField\Models\ExtraField;


class DemoExtraFieldTypeEnums extends EnumBase implements ExtraFieldTypeEnumInterface
{
    const SECTION = 'SECTION';
    const TEXT = 'TEXT';
    const NUMBER = 'NUMBER';
    const SELECT = 'SELECT';
    const MULTIPLE = 'MULTIPLE';
    ...

    protected static $descriptions = [
        'SECTION' => 'Section',
        'TEXT' => 'Text',
        'NUMBER' => 'Number',
        'SELECT' => 'Select',
        'MULTIPLE' => 'Multiple choice',
        ...
    ];

    static function buildSelectOptions(): \Illuminate\Support\Collection
    {
        return static::getCollection(function($des, $value) {
            return [
                'component' => self::getComponentByType($value),
                'requireHasOptions'=> self::requireHasOptions($value),
                'requireHasFields'=> self::requireHasFields($value),
                'masterSelect'=> $value != self::SECTION,
                'childSelect'=> ! in_array($value, [self::SECTION, self::CLAIMS, self::REPEATER]),
            ];
        });
    }

    static function getComponentByType($type): string
    {
        switch ($type) {
            case self::SELECT:
            case self::MULTIPLE: return 'Select';
            case self::FILE: return 'File';
            case self::DATE:  return 'Datepicker';
            case self::DATETIME: return 'DateTime';
            case self::TIME: return 'Time';
            default: return 'Text';

        }
    }

    static function requireHasOptions($value) : bool
    {
        return in_array($value, [self::SELECT, self::MULTIPLE]);
    }


    static function requireHasFields($value) : bool
    {
        return ...
    }

    static function inputRequestHasFile($value) : bool
    {
        return $value == self::FILE;
    }

    static function inputRequestIsMultiple($value) : bool
    {
        return ...
    }

    static function appendToArray(ExtraField $extraField): array
    {
        return [
            'component' => static::getComponentByType($extraField->type),
        ];
    }
}

此外,您还可以在从数据库保存和检索时自定义值处理器。此Enum类必须实现以下接口:HXM\ExtraField\Contracts\ExtraValueProcessValueInterface,否则在将其集成到系统中时会出错。

//extra_field.php
...
return [
    ...
    
    'valueProcessions' => [
        \App\Models\Demo::class => new \App\Casts\DemoExtraValueProcessValue(),
    ]
]
<?php
/**
 * Created by HoanXuanMai
 * @author hoanxuanmai@gmail.com
 */

namespace App\Casts;

use HXM\ExtraField\Contracts\ExtraValueProcessValueInterface;
use HXM\ExtraField\Models\ExtraField;
use HXM\ExtraField\Models\ExtraFieldValue;

class DemoExtraValueProcessValue implements ExtraValueProcessValueInterface
{

    function getValue($value, $valueType = null, ExtraFieldValue $model)
    {
        return $value;
    }

    function setValue($value, $valueType = null, ExtraField $model)
    {
     
        return $value;
    }
}

许可证

Laravel User Agent遵循MIT许可证(MIT)

捐赠

Paypal

联系方式