I\'m trying to serialize a entity relation with JMS Serializer.
Here is the Entity:
class Ad
{
/**
* @Type(\"string\")
* @Groups({\"manag
Just to follow answered question:
If you don't like writing one method for each relation you have - just write your own handler. It's easy like
final class RelationsHandler
{
/**
* @var EntityManagerInterface
*/
private $manager;
/**
* RelationsHandler constructor.
*
* @param EntityManagerInterface $manager
*/
public function __construct(EntityManagerInterface $manager) { $this->manager = $manager; }
public function serializeRelation(JsonSerializationVisitor $visitor, $relation, array $type, Context $context)
{
if ($relation instanceof \Traversable) {
$relation = iterator_to_array($relation);
}
if (is_array($relation)) {
return array_map([$this, 'getSingleEntityRelation'], $relation);
}
return $this->getSingleEntityRelation($relation);
}
/**
* @param $relation
*
* @return array|mixed
*/
protected function getSingleEntityRelation($relation)
{
$metadata = $this->manager->getClassMetadata(get_class($relation));
$ids = $metadata->getIdentifierValues($relation);
if (!$metadata->isIdentifierComposite) {
$ids = array_shift($ids);
}
return $ids;
}
}
Register the Handler
jms_serializer.handler.relation:
class: MyBundle\RelationsHandler
arguments:
- "@doctrine.orm.entity_manager"
tags:
- { name: jms_serializer.handler, type: Relation, direction: serialization, format: json, method: serializeRelation}
- { name: jms_serializer.handler, type: Relation, direction: deserialization, format: json, method: deserializeRelation}
- { name: jms_serializer.handler, type: Relation>, direction: serialization, format: json, method: serializeRelation}
- { name: jms_serializer.handler, type: Relation>, direction: deserialization, format: json, method: deserializeRelation}
This allows you to replace virtual getter methods with `Type("Relation").
If you also want't to deserialize relation - you should tell each @Type("Relation")
the classname (@Type("Relation
) which it should deserialize to or wrap the metadata driver with one which do it for you.
public function deserializeRelation(JsonDeserializationVisitor $visitor, $relation, array $type, Context $context)
{
$className = isset($type['params'][0]['name']) ? $type['params'][0]['name'] : null;
if (!class_exists($className, false)) {
throw new \InvalidArgumentException('Class name should be explicitly set for deserialization');
}
$metadata = $this->manager->getClassMetadata($className);
if (!is_array($relation)) {
return $this->manager->getReference($className, $relation);
}
$single = false;
if ($metadata->isIdentifierComposite) {
$single = true;
foreach ($metadata->getIdentifierFieldNames() as $idName) {
$single = $single && array_key_exists($idName, $relation);
}
}
if ($single) {
return $this->manager->getReference($className, $relation);
}
$objects = [];
foreach ($relation as $idSet) {
$objects[] = $this->manager->getReference($className, $idSet);
}
return $objects;
}