Reputation: 17636
I'm using the JMSSerializerBundle to deserialize my JSON object
from a POST request.
One of the vaules in my JSON
is an Id
. I'd like to replace this Id with the correct object before the deserialization occurs.
Unfortunately, JMSSerializerBundle
does not have a @preDeserializer
annotation.
The problem I'm facing (and that I would have faced if there was an @preDeserializer annotation anyway) is that I would like to create a generic function for all my entities.
How do I replace my Id
with the corresponding object
in the most generic way possible ?
Upvotes: 2
Views: 183
Reputation: 1971
You also do your own hydratation as I did (with Doctrine):
The IHydratingEntity
is an interface which all my entities implement.
The hydrate
function is used in my BaseService generically. Parameters are the entity and the json object.
At each iteration, the function will test if the method exists then it will call the reflection
function to check if the parameter's method (setter) also implements IHydratingEntity
.
If it's the case, I use the id
to get the entity from the database with Doctrine ORM.
I think it's possible to optimize this process, so please be sure to share your thoughts !
protected function hydrate(IHydratingEntity $entity, array $infos)
{
#->Verification
if (!$entity) exit;
#->Processing
foreach ($infos as $clef => $donnee)
{
$methode = 'set'.ucfirst($clef);
if (method_exists($entity, $methode))
{
$donnee = $this->reflection($entity, $methode, $donnee);
$entity->$methode($donnee);
}
}
}
public function reflection(IHydratingEntity $entity, $method, $donnee)
{
#->Variable declaration
$reflectionClass = new \ReflectionClass($entity);
#->Verification
$idData = intval($donnee);
#->Processing
foreach($reflectionClass->getMethod($method)->getParameters() as $param)
{
if ($param->getClass() != null)
{
if ($param->getClass()->implementsInterface(IEntity::class))
#->Return
return $this->getDoctrine()->getRepository($param->getClass()->name)->find($idData);
}
}
#->Return
return $donnee;
}
Upvotes: 2