hxm / extrafield
额外字段包,为Laravel提供简单、可扩展且强大的额外字段实现。
Requires
- php: >=7
- hxm/enum: ^1.0
- laravel/framework: >=5
README
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\HasExtraFieldValue
,HXM\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)。