Friday, March 3, 2017

Find out if doctrine entity attribute is an array collection

Im trying to create a very dry and reusable resource controller for an api to cut down on re-coding implementations for a-lot of entities.

creating resource methods for show() and delete() is easy as long as you know the $id of the resource. store and update methods get a bit tricky.

Im using lumen 5.3 and laraveldoctrine for my database orm.

I have a middleware that validates requests using doctrine before they hit the controller. So only valid payloads will only ever hit the controller so in theory i should just be able to create a reusable function to store/update entities from requests regardless of what entity/controller is

so far i have something like this

public function setEntityFromPayload(array $payload, DoctrineEntity $entity)
{
    $cols = $this->_em->getClassMetadata(get_class($entity))->getFieldNames();

    foreach ($payload as $key => $value) {
        if(array_key_exists($key,$cols)) {
            $setter = 'set'.ucfirst($col);
            $entity->$setter($value);
        }
    }

    return $entity;
}

Which works for simple entities. But it get's a bit more complex when you talk about entities with associations to other entities.

It's not to hard to figure out one-to-many associations by getting the association mappings like

$this->_em->getClassMetadata(get_class($entity))->getAssociationMappings();

Looking for 'target_entity' in the array and instantiating the target entity with the value in the payload, what i can't work out is how to check if an attribute is a many-to-many or if it's an array collection, as this part of the function

       if(array_key_exists($key,$cols)) {
            $setter = 'set'.ucfirst($col);
            $entity->$setter($value);
        }

will need some logic to use an adder function on the entity like

public function addTag(Tag $tag) {
    if (!$this->tag->contains($tag)) {
        $this->tag->add($tag);
    }
    return $this;
}

I've looked through ClassMetadataInfo and cant find anything that does this.

Any one with deeper Doctrine knowledge might know if this is possible



via user618509

Advertisement