diossystem/multicasting

此包已被废弃,不再维护。未建议替代包。

Laravel模型属性的组播。一个模型属性可以有多个类型。

v1.1.4 2020-12-13 14:08 UTC

This package is auto-updated.

Last update: 2022-09-13 17:59:18 UTC


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

每个接口都有自己的功能。

初始化的基接口:

填充的基接口:

/** @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
/** @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
/** @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