indaxia/doctrine-orm-transformations

Provides JSON-ready Doctrine ORM Entity-Array transfomtaions

2.0.1-stable 2016-11-18 04:44 UTC

README

Features

  • JSON-ready toArray and fromArray Trait (no need to extend class);
  • Manipulating fields and nested sub-fields using Policy for each one;
  • Supports all Doctrine ORM Column types;
  • Supports JavaScript ISO8601 format for "date", "time" and "datetime" types;
  • Supports nested Entities and Collections for all the Association types (be careful with self-referencing);
  • fromArray asks EntityManager to find by "referencedColumnName" or creates new sub-entities (depends on Identifier emptiness and Policy);
  • Same for Collection members (OneToMany, ManyToMany);
  • Static toArrays method transforms multiple entities at once;
  • Has workarounds for CVE-2015-0231 and Doctrine issue #4673;

Step 1: Installation

in composer.json add:

"require": {

    "Indaxia/doctrine-orm-transformations": "2.*"
}

then

> cd <your doc root>
> composer update

Requirements & Restrictions

Step 2: Reference common classes

use \Indaxia\OTR\ITransformable;
use \Indaxia\OTR\Traits\Transformable;
use \Indaxia\OTR\Annotations\Policy;

Documentation

Full Documentation

How to transform entities to arrays and vice versa

Let's say we have the following entities:

    class Car implements ITransformable {
        use Transformable;
    
        /** @ORM\Id
         * @ORM\Column(type="integer") */
        protected $id;
        
        /** @Policy\To\Skip
         * @ORM\Column(type="string") */
        protected $keys;
        
        /** @ORM\OneToMany(targetEntity="Wheel") ... */
        protected $wheels;
        
        public function getId();
        public function getKeys() ...
        public function setKeys($v) ...
        ...
    }
    
    class Engine implements ITransformable {
        use Transformable;
        
        /** @ORM\Id
         * @ORM\Column(type="integer") */
        protected $id;
        
        /** @Policy\To\Skip
         * @ORM\Column(type="string") */
        protected $serialNumber;
        
        public function getId();
        public function getSerialNumber() ...
        public function setSerialNumber($v) ...
        ...
    }
    
    class Wheel implements ITransformable {
        use Transformable;
        
        /** @ORM\Id
         * @ORM\Column(type="integer") */
        protected $id;
        
        /** @Policy\Skip
         * @ORM\Column(type="string") */
        protected $brakes;
        
        /** @ORM\Column(type="string") */
        protected $model;
        
        public function getId();
        public function getBrakes() ...
        public function setBrakes($v) ...
        public function getModel() ...
        public function setModel($v) ...
        ...
    }

Here we have some $car. Let's transform it to array.

// Using global policy
$result = $car->toArray();
    
// Using local policy
$result = $car->toArray((new Policy\Auto)->inside([
    'wheels' => new Policy\To\FetchPaginate(['offset'=0, 'limit'=4, 'fromTail'=false])
]));

// Local policy overrides global policy
$result = $car->toArray((new Policy\Auto)->inside([
    'keys' => new Policy\Auto
]));

Policies Documentation

$result will be something like:

[
    '__meta' => ['class' => 'Car'],
    'id' => 1,
    'engine' => [
        '__meta' => ['class' => 'Engine', 'association' => 'OneToOne'],
        'id' => 83
    ],
    'wheels' => [
        '__meta' => ['class' => 'Wheel', 'association' => 'OneToMany'],
        'collection' => [
            [
                '_meta' => ['class' => 'Wheel'],
                'id' => 1,
                'model' => 'A'
            ],
            [
                '_meta' => ['class' => 'Wheel'],
                'id' => 2,
                'model' => 'A'
            ],
            [
                '_meta' => ['class' => 'Wheel'],
                'id' => 3,
                'model' => 'B'
            ],
            [
                '_meta' => ['class' => 'Wheel'],
                'id' => 4,
                'model' => 'B'
            ]
        ]
    ]
]

It's ready for JSON transformation!

    echo json_encode($result);

You can also use something like array2XML and more.

And we can transform it to Entity again. It will retrieve sub-entities by id using EntityManager. Don't forget to use try-catch block to avoid uncaught exceptions.

$carB = new Car();
    
// Simple way
$carB->fromArray($result, $entityManager);

// With Policy
$carB->fromArray($result, $entityManager, (new Policy\Auto())->inside([
    'keys' => mew Policy\Skip,
    'engine' => (new Policy\Auto())->inside([
        'serialNumber' => new Policy\From\DenyNewUnset
    ]),
    'wheels' => (new Policy\Auto())->inside([
        'brakes' => new Policy\From\Auto
    ])
]);

Policies Documentation

Documentation

Full Documentation

Indaxia / 2016