Coder Social home page Coder Social logo

dto-annotation-mapper's Introduction

Annotation entity mapper based on Doctrine

Latest Stable Version Total Downloads License

This library intended for auto fill entity object from input dataset based on annotations.

Purpose

This library could be useful if you have several cases, when you fill entity from an array data.

For example, you retrieve data from client and create new entity and another way you get this entity from import file.

Instead of create separate services to filling entity from array data set you could just specify entity fields for filling and pass only those properties which you need.

Requirements

  • PHP 7.4+
  • Doctrine ORM 2+

Installation

You can install the package via composer:

composer require ok/dto-annotation-mapper

For Symfony project: Register AnnotationMapper as service in services.yml:

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

For other just init new mapper object

use Doctrine\Common\Annotations\AnnotationReader;

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

Usage

At first you need to mark your setters in doctrine entity with DTO annotation

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

Then just pass input data with object to fillObject method in controller like this (Example for Symfony project, but you can use it with any framework or without it):

    /**
     * @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);
    }

That's it! Your entity will updated with new data.

Available simple types: string, float, bool, boolean, int, integer, datetime, array. Trying to use other types without relation will throw the OK\Dto\Exception\MapperInvalidTypeException.

You can use any entity class as type, you just need to specify relation for it: ManyToOne, OneToMany, ManyToMany

Testing

composer install
vendor/bin/phpunit tests

Information

Basic usage

All useful information will be retrieved from Doctrine annotations if property set or type is not set in DTO annotation.

@DTO(name="material")

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

Using only simple types

If you don't use Doctrine\orm you could use this mapper anyway.

Just create mapper without the second parameter and with you own Reader implementation if need.

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

And then you can use only the simple types.

Case sensitivity

You can use both snake_case and camelCase in name field and mapper will check both of variants in dataset if doesn't find the strict key. For example: If you have annotation:

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

and dataset:

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

It's fine. At first mapper check the strict name customerNumber, then (if name doesn't exist) transforms name to customer_number and check it again. It works other way too (from snake_case to camelCase).

Several naming

If you need to have several names for one Dto annotation just list them via | delimiter and then you can use different name in data for different cases:

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

If in dataset existed more then one from this set of names, then mapper will return first found.

Using ManyToMany relation

For using ManyToMany relation you need to implement OK\Dto\Repository\SearchCollectionInterface for you entity repository or you can just extends from OK\Dto\Repository\EntityRepository

Using OneToMany relation

Here are two ways to use this relation:

The first one when related entity existed then you need to pass array of id to dataset:

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

Another way when you need to create new Entity, then you need to pass data to create:

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

You can combine both this way in one dataset:

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

License

The MIT License (MIT). Please see License File for more information.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.