Doctrine ORM Transformations

This library allows you to transform Doctrine ORM Entities into nested arrays of scalar data types and vise versa. It can be used together with JSON, XML, YAML or any serializer/deserializer that supports php nested assoc arrays and scalar types.

View the Project on GitHub Indaxia/doctrine-orm-transformations

JSON-ready Doctrine ORM Entity-Array Transformations

Features

Step 1: Installation

in composer.json add:

"require": {

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

then

> cd <your doc root>
> composer update

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
]));

Policy options

$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
    ])
]);

Policy options

How to redeclare Transformable methods

    class A implements ITransformable {
        use Transformable {
            toArray as traitToArray;
            fromArray as traitFromArray;
        }

        public function toArray ...
        public function fromArray ...
    }

Indaxia / 2016