fromArray - Indaxia/doctrine-orm-transformations GitHub Wiki

Converts and fills Entity's fields (including nested Entity and Collection) to the values from the given array.

Scalar Types

OTR checks scalar type and sets the property to it's value using write accessor method (setter).

datetime, datetimez, date, time

Any date and/or time type must be in JavaScript ISO8601 format, a PHP DateTime object or null (if the column has nullable flag); Example: "2099-12-31T23:59:59.000Z"

array

When using 'array' ORM type it throws Exceptions\FromArrayException to avoid CVE-2015-0231 exploit.

To ignore this check use PolicyResolver::IGNORE_CVE_2015_0231 option:

use Indaxia\OTR\Annotations\PolicyResolver;

// ...
$pr = new PolicyResolver(PolicyResolver::IGNORE_CVE_2015_0231);

$result = $e->fromArray($data, $entityManger, null, null, $pr);

simple_array

This type is converted as any array type with one exception: https://github.com/doctrine/doctrine2/issues/4673

OTR has a fix for that - it saves empty array as [null] and loads it as empty array again. To enable this fix instantiate a new PolicyResolver with the option SIMPLE_ARRAY_FIX:

use Indaxia\OTR\Annotations\PolicyResolver;

// ...
$pr = new PolicyResolver(PolicyResolver::SIMPLE_ARRAY_FIX);

$result = $e->fromArray($data, $entityManger, null, null, $pr);

blob

OTR reads BLOB type as stream. It creates a new stream using fopen('php://memory','r+') if the input is a string.

float

OTR uses is_integer($v) || is_double($v) expression to check the value before setting.

Relations

Entity (OneToOne, ManyToOne)

Here are 3 cases:

  • Non-existent: Source array contains identifier (determined from 'referencedColumnName' of the doctrine annotation)
  • Existent: Source array doesn't contain identifier
  • Unsetting: Target value is null

Non-existent

OTR checks if the poilicy is not an instance of Policy\Interfaces\DenyNewFrom, then creates a new entity using it's constructor and calls 'fromArray' method of this entity.

It passes property's policy if it's not an instance of Policy\Interfaces\PolicyFrom, otherwise it creates a new Policy\From\Auto.

Existent

OTR compares old and new Entity identifiers.

If the entity ids are not equal it checks for the policy.

If the poilicy is instance of Policy\Interfaces\DenyUpdateFrom and it's allowExternal property set to true or it's not an instance of DenyUpdateFrom, OTR uses $entityManager->getReference() to find the entity and set the property to it's value.

After all (for any case) it checks if the poilicy is instance of Policy\Interfaces\DenyUpdateFrom and it's allowExistent property set to true or it's not an instance of DenyUpdateFrom OTR calls 'fromArray' method of this entity.

It passes property's policy if it's not an instance of Policy\Interfaces\PolicyFrom, otherwise it creates a new Policy\From\Auto.

Unsetting

If the value is null, OTR checks if the poilicy is not an instance of Policy\Interfaces\DenyUnsetFrom and sets the property to null.

Collection (OneToMany, ManyToMany)

Here are 4 cases:

  • Non-existent: One of sub-arrays contains identifier (determined from 'referencedColumnName' of the doctrine annotation)
  • Internal Existent: One of sub-arrays contains identifier of one of the existing entities in the current collection
  • External Existent: One of sub-arrays contains identifier of one of extenal entities, not containing in current collection
  • Unsetting: Target value is null

Non-existent

OTR checks if the poilicy is not an instance of Policy\Interfaces\DenyNewFrom, then creates a new entity using it's constructor and calls 'fromArray' method of this entity.

It passes property's policy if it's not an instance of Policy\Interfaces\PolicyFrom, otherwise it creates a new Policy\From\Auto.

After that the entity is placed at the new collection instance.

Existent Internal

OTR checks if the poilicy is instance of Policy\Interfaces\DenyUpdateFrom and it's allowExistent property set to true or it's not an instance of DenyUpdateFrom and calls 'fromArray' method of this entity.

It passes property's policy if it's not an instance of Policy\Interfaces\PolicyFrom, otherwise it creates a new Policy\From\Auto.

After all it adds the entity to the new collection instance.

Existent External

If the poilicy is instance of Policy\Interfaces\DenyUpdateFrom and it's allowExternal property set to true or it's not an instance of DenyUpdateFrom, OTR uses $entityManager->getReference() to find the entity.

OTR check if the poilicy is instance of Policy\Interfaces\DenyUpdateFrom and it's allowExistent property set to true or it's not an instance of DenyUpdateFrom and calls 'fromArray' method of this entity.

It passes property's policy if it's not an instance of Policy\Interfaces\PolicyFrom, otherwise it creates a new Policy\From\Auto.

After all it adds the entity to the new collection instance.

Unsetting

If current collection contains some entities not existing in the new collection instance, it checks if the poilicy is an instance of Policy\Interfaces\DenyUnsetFrom. If so, OTR adds the rest to the end of collection.


Read Policies to get more info how to control your transformations.