diossystem / multicasting
Laravel模型属性的组播。一个模型属性可以有多个类型。
Requires
- php: 7 - 8
- illuminate/database: 5 - 8
Requires (Dev)
- illuminate/support: 5 - 8
- orchestra/database: ~3.5
- orchestra/testbench: 3.5.x-dev
- phpunit/phpunit: ^6
README
这就是某个属性可以有多个类型的情况。具有不同数据类型的数据值存储在一个列中。
这使得模型更加灵活,它们的实例可以使用适当的实体,并且这些实体可以具有处理数据的不同方法和算法。数据处理可以完全不同。这为模型提供了极大的可能性,并简化了代码的实现和阅读。
在哪里可以使用它?
在您的Eloquent模型中使用它。
如何实现:
- 将特性添加到您的模型;
- 配置变量(设置变量值);
- 使用基接口或您自己的接口实现您的处理器。
示例 #1.1. 配置模型
namespace App\Models; use Dios\System\Multicasting\AttributeMulticasting; use Dios\System\Multicasting\ReadwriteInstance; // to have the access from attributes: $model->instance use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; class Sheet extends Model { use AttributeMulticasting, ReadwriteInstance; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'properties' => 'array', ]; /** * The instance type of entities. * * @var string */ protected $interfaceType = \Dios\System\Multicasting\Interfaces\RelatedEntity::class; /** * The source that contains an entity type. * * @var string */ protected $sourceWithEntityType = 'type'; /** * Type mapping of entity types and their handlers. * * @var array */ protected $entityTypeMapping = [ 'single_type' => App\Models\RelatedSheetTypes\SingleType::class, 'roll_paper_type' => App\Models\RelatedSheetTypes\RollPaperType::class, ]; /** * The property to read values for entities. * * @var string */ protected $propertyForEntity = 'properties'; // the table has a column namesd 'properties' /** * The state of configuring instances of entities. * * @var bool */ // protected $configureInstanceOfEntity = true; // by default /** * The state of filling instances of entities. * * @var bool */ // protected $fillInstance = true; // by default
示例 #1.2. 使用实例
$model = Sheet::where('type', 'single_type')->find($id); /** @var SingleType $singleType */ $singleType = $model->instance; $height = $singleType->getHeight(); $topMargin = $singleType->getTopMargin(); $availableHeight = $singleType->getAvailableHeight(); if ($singleType->canContain($customHeight, $customWeight)) { // actions } $singleType->setHeight($newHeight); $singleType->save(); // The second type $model = Sheet::where('type', 'roll_paper_type')->find($id); /** @var RollPaperType $rollPaperType */ $rollPaperType = $model->instance; $indent = $rollPaperType->getIndent(); // this method does not exist in SingleType // others methods if ($rollPaperType->canContain($customHeight, $customWeight)) { // other actions }
安装
使用 Composer 安装此包
composer require "diossystem/multicasting:1.*"
设置模型
使用特性
要使用这些功能,您需要将特性添加到您的模型。
示例 #1
use Dios\System\Multicasting\AttributeMulticasting; class Sheet extends Model { use AttributeMulticasting; // your code }
接口类型
下一步,您必须选择一个接口来实现模型属性的数据处理器并配置变量。
初始化的默认接口是 \Dios\System\Multicasting\Interfaces\IndependentEntity
。
每个接口都有自己的功能。
初始化的基接口:
- \Dios\System\Multicasting\Interfaces\IndependentEntity - 它没有参数。
- \Dios\System\Multicasting\Interfaces\SimpleSingleValueEntity - 它有一个参数 - 模型的单个值;
- \Dios\System\Multicasting\Interfaces\SimpleArrayEntity - 它有一个参数 - 包含模型值的数组;
- \Dios\System\Multicasting\Interfaces\RelatedEntity - 它有一个参数 - 模型的实例;
- \Dios\System\Multicasting\Interfaces\EntityWithModel 它有一个参数 - 模型的实例。
填充的基接口:
- \Dios\System\Multicasting\Interfaces\ArrayEntity- 用于填充和获取值数组;
/** @var MulticastingEntity|ArrayEntity **/ $instance = $model->getInstance(); $instance->fillFromArray($values); /** @var array $values **/ $values = $instance->toArray();
/** @var MulticastingEntity|SingleValueEntity **/ $instance = $model->getInstance(); $instance->setValue($value); /** @var mixed $value **/ $value = $instance->getValue(); // returns any value
- \Dios\System\Multicasting\Interfaces\KeepsEntityType - 用于分配和获取实体类型。
/** @var MulticastingEntity|KeepsEntityType **/ $instance = $model->getInstance(); /** @var string $type **/ $type = $instance->getEntityType(); // A type is assigned during initialization, if it is configured $instance->setEntityType($this->getEntityType()); // it is called from the model
- \Dios\System\Multicasting\Interfaces\KeepsAttributeName - 用于分配和获取属性名称。
/** @var MulticastingEntity|KeepsAttributeName **/ $instance = $model->getInstance(); /** @var string $name **/ $name = $instance->getAttributeName(); // A name is assigned during initialization, if it is configured $instance->setAttributeName($this->{$this->propertyForEntity}); // it is called from the model
所有这些接口都扩展自 \Dios\System\Multicasting\Interfaces\MulticastingEntity。
当你需要使用自己的接口或另一个接口时,它必须实现 \Dios\System\Multicasting\Interfaces\MulticastingEntity
。
在你的模型中将所选接口类型分配给 $interfaceType
。
示例 #2
use Dios\System\Multicasting\Interfaces\SimpleArrayEntity; /** * The instance type of entities. * * @var string */ protected $interfaceType = SimpleArrayEntity::class; }
如果你使用的是非供应商接口,你必须扩展或替换 newInstanceByClassNameOfEntity()
函数的基本实现。此函数实现选择一个合适的模式来初始化类的实例。
示例 #3. 自定义接口
use App\Models\EntitiesOfSheets\TypeOfSheet; // your own interface use Illuminate\Database\Eloquent\Model; class Sheet extends Model { use AttributeMulticasting { // Set another name to the function of the trait newInstanceByClassNameOfEntity as newInstanceFromTrait; } /** * The instance type of entities. * * @var string */ protected $interfaceType = TypeOfSheet::class; /** * Makes a new instance of a class using the interface type * and a class name of the entity. * * @param string $className * @return MulticastingEntity|null */ public function newInstanceByClassNameOfEntity(string $className) { /** @var string $interfaceType **/ $interfaceType = $this->getInterfaceTypeOfEntities(); if ($interfaceType === TypeOfSheet::class) { // The custom interface and atypical arguments are used here $instance = new $className($this->height, $this->height); } else { // In another case there will be call a function from the trait $instance = $this->newInstanceFromTrait($className); } } }
为了在初始化期间向你的实例添加非典型值,你必须扩展或替换模型中的 fillInstanceOfEntity()
。
示例 #4. 自定义接口设置值
use App\Models\EntitiesOfSheets\KeepsSize; // your own interface use Illuminate\Database\Eloquent\Model; class Sheet extends Model { use AttributeMulticasting { // Set another name to the function of the trait fillInstanceOfEntity as fillInstanceInTrait; } /** * Fills an instance of the entity with data from the property. * * @param MulticastingEntity $instance * @return MulticastingEntity */ public function fillInstanceOfEntity(MulticastingEntity $instance): MulticastingEntity { // Sets values from the model if ($instance instanceof KeepsSize) { $instance->setSize($this->height, $this->width); // or $instance->setHeight($this->height); $instance->setWidth($this->width); } // Uses the function of the trait $this->fillInstanceInTrait(); } }
类型的来源
下一步,你必须为获取当前实体类型的来源分配一个来源。类型来自你的数据库。
使用 $sourceWithEntityType
来分配你的来源。
示例 #5. 双值
/** * The source that contains an entity type. * When set second value, then may to use caching of a result of the search * entity key. * * Format that uses the cache: '<first_value>|<second_value>' * The first_value is a path to get an entity key. * The second_value is a key for the cache. * Example: 'af.type|additional_field_id' * * Format that do not use the cache: '<value>'. * The value is a path to get an entity key or it is a property of the current model. * Example: 'code_name' * * @var string */ protected $sourceWithEntityType = 'af.type|additional_field_id'; }
该包实现了类型来源的两种格式
- 单个值。它是指向类型来源的值。类型可能位于其他表和当前表中。如果你将使用它从另一个表获取类型,则类型键将不会缓存。
- 双值。它是指向类型来源的值。类型必须位于另一个表中。结果将被缓存。
使用 单个值
来设置当前模型中类型的来源。使用 双值
来设置位于另一个表中的类型的来源。
在示例 #4 中使用了 双值
:'af.type|additional_field_id'
。第一个值是类型的来源。 af
是关系名称,type
是允许的实体类型的存储。
实体处理程序
下一步,你必须为允许的类型定义实体处理程序。
示例 #6
/** * Type mapping of entity types and their handlers. * * @var array */ protected $entityTypeMapping = [ 'map' => \Dios\System\Page\Models\HandlersOfAdditionalFields\Map::class, ]; /** * A default entity handler class. * * @var string|null */ protected $defaultEntityHandler = \Dios\System\Page\Models\HandlersOfAdditionalFields\DefaultHandler::class; }
变量 $entityTypeMapping
和 $defaultEntityHandler
必须包含实体处理程序。你可以为不同类型使用一个处理程序。
默认处理程序是可选的。
这些处理程序必须实现 MulticastingEntity 接口。
包含值的属性
你必须定义变量 $propertyForEntity
。它包含用于获取实体(处理程序)实例值的模型属性。它在初始化实例时使用。
/** * The property that contains values for entities. * * @var string */ protected $propertyForEntity = 'values';
通常你的属性将属于 '数组' 类型。
/** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'values' => 'array', ];
你可以使用任何类型的属性,其值将传递给实体的新实例。
许可协议: MIT