ok/dto-annotation-mapper

2.3 2021-07-21 10:23 UTC

This package is auto-updated.

Last update: 2024-09-21 16:39:33 UTC


README

Latest Stable Version Total Downloads License

这个库旨在根据注解自动填充实体对象。

用途

如果您有多种情况需要从数组数据填充实体,则此库可能非常有用。

例如,您从客户端检索数据并创建新实体,另一种方式是从导入文件中获取此实体。

您无需创建单独的服务来从数组数据集中填充实体,只需指定要填充的实体字段,并传递您需要的那些属性即可。

要求

  • PHP 7.4+
  • Doctrine ORM 2+

安装

您可以通过 composer 安装此包

composer require ok/dto-annotation-mapper

对于 Symfony 项目:在 services.yml 中将 AnnotationMapper 注册为服务

OK\Dto\MapperInterface:
   class: OK\Dto\AnnotationMapper
   autowire: true

对于其他项目,只需初始化新的映射器对象

use Doctrine\Common\Annotations\AnnotationReader;

$mapper = new AnnotationMapper(new AnnotationReader(), $entityManager);

用法

首先,您需要使用 DTO 注解标记 doctrine 实体中的设置器

/**
 * @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
 */
class Product
{
    /**
     * @var string
     *
     * @ORM\Column(type="string", nullable=true)
     */
    protected $article;

    /**
     * @var Material
     *
     * @ORM\ManyToOne(targetEntity="App\Entity\Product\Options\Material")
     */
    protected $material;

    /**
     * @DTO(name="article", type="string")
     */
    public function setArticle(?string $article)
    {
        $this->article = $article;
    }

    /**
     * @DTO(name="material", type="App\Entity\Product\Options\Material", relation="ManyToOne")
     */
    public function setMaterial(?Material $material)
    {
        $this->material = $material;
    }

然后,只需将对象和输入数据传递到控制器中的 fillObject 方法,如下所示(以 Symfony 项目为例,但您可以使用任何框架或无需框架)

    /**
     * @Route("/products/{id}", name="api_product_patch", methods={"PATCH"})
     */
    public function updateProductAction(Request $request, Product $product, MapperInterface $mapper): JsonResponse
    {
        $data = $this->getRequestData($request);

        $updatedProduct = $mapper->fillObject($product, $data);

        /* Do validation and other actions if need */

        $this->getDoctrine()->getManager()->flush();

        return $this->json($updatedProduct);
    }

这就完成了!您的实体将更新为新数据。

支持的简单类型:stringfloatboolbooleanintintegerdatetimearray。尝试使用其他类型而无需 relation 将会抛出 OK\Dto\Exception\MapperInvalidTypeException

您可以使用任何实体类作为类型,您只需指定它的 relationManyToOneOneToManyManyToMany

测试

composer install
vendor/bin/phpunit tests

信息

基本用法

如果 property 设置或 type 未在 DTO 注解中设置,则所有有用的信息都将从 Doctrine 注解中检索。

@DTO(name="material")

@DTO(name="material_name", property="material")

仅使用简单类型

即使不使用 Doctrine\orm,您也可以使用此映射器。

只需创建映射器,不使用第二个参数,并根据需要使用您自己的 Reader 实现。

new \OK\Dto\AnnotationMapper(new \Doctrine\Common\Annotations\AnnotationReader());

然后您可以使用简单类型。

大小写敏感

您可以在 name 字段中使用 snake_casecamelCase,映射器将在数据集中检查这两种变体的严格键。例如:如果您有注解

@DTO(name="customerNumber", type="string")

和数据集

$data = ['customer_number' => 123];

这是可以的。首先映射器检查严格的名称 customerNumber,然后(如果名称不存在)将其转换为 customer_number 并再次检查。它也可以以相反的方式工作(从 snake_casecamelCase)。

多个命名

如果您需要为单个 Dto 注解设置多个名称,请通过 | 分隔符列出它们,然后您可以在不同情况下使用不同的名称在数据中。

@DTO(name="customerNumber|userNumber|managerNumber", type="string")

如果在数据集中存在这个集合中的多个名称,则映射器将返回第一个找到的。

使用 ManyToMany 关系

要使用 ManyToMany 关系,您需要为您的事件仓库实现 OK\Dto\Repository\SearchCollectionInterface 或您可以从 OK\Dto\Repository\EntityRepository 继承。

使用 OneToMany 关系

这里有两种使用这种关系的方法

第一种是当相关实体存在时,您需要将 id 数组传递到数据集中

$data = ['customers' => [1,2,3]];

当您需要创建新的实体时,您需要传递数据以创建

$data = ['customers' => [['firstName' => 'John', 'lastName' => 'Smith']]];

您可以将这两种方式结合在一个数据集中

$data = ['customers' => [1, 2, ['firstName' => 'John', 'lastName' => 'Smith']];

许可证

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