Skip to content

Instantly share code, notes, and snippets.

@Glifery
Last active June 18, 2018 06:46
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Glifery/f035e698b5e3a99f11b5 to your computer and use it in GitHub Desktop.
Save Glifery/f035e698b5e3a99f11b5 to your computer and use it in GitHub Desktop.
Entity to it's ID serialization handler
<?php
namespace MyVendor\MyBundle\Model;
use MyVendor\MyBundle\Entity\User;
use JMS\Serializer\Annotation as JMS;
class Assessment
{
...
/**
* @JMS\Type("EntityId<'MyVendorMyBundle:User'>")
* @var User
*/
private $user;
...
}
<?php
namespace MyVendor\MyBundle\Handler;
use Doctrine\ORM\EntityManager;
use JMS\Serializer\Context;
use JMS\Serializer\GraphNavigator;
use JMS\Serializer\Handler\SubscribingHandlerInterface;
use JMS\Serializer\JsonSerializationVisitor;
use JMS\Serializer\JsonDeserializationVisitor;
class EntityIdSerializeHandler implements SubscribingHandlerInterface
{
/** @var EntityManager */
private $em;
/**
* @param EntityManager $em
*/
public function __construct(EntityManager $em)
{
$this->em = $em;
}
/**
* Return format:
*
* array(
* array(
* 'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
* 'format' => 'json',
* 'type' => 'DateTime',
* 'method' => 'serializeDateTimeToJson',
* ),
* )
*
* The direction and method keys can be omitted.
*
* @return array
*/
public static function getSubscribingMethods()
{
return array(
array(
'direction' => GraphNavigator::DIRECTION_SERIALIZATION,
'format' => 'json',
'type' => 'EntityId',
'method' => 'serializeEntityToId',
),
array(
'direction' => GraphNavigator::DIRECTION_DESERIALIZATION,
'format' => 'json',
'type' => 'EntityId',
'method' => 'deserializeIdToEntity',
)
);
}
/**
* @param JsonSerializationVisitor $visitor
* @param object|null $entity
* @param array $type
* @param Context $context
* @return mixed
* @throws \Exception
*/
public function serializeEntityToId(JsonSerializationVisitor $visitor, $entity, array $type, Context $context)
{
$entityName = $this->getEntityName($type);
if ($entity === null) {
return null;
}
if (!is_object($entity)) {
throw new \Exception(sprintf('Value of @JMS\Type("EntityId<\'%s\'>") must me object of null, %s given.', $entityName, gettype($entity)));
}
$identifier = $this->getEntityIdentifier($type);
$getter = 'get' . ucfirst($identifier);
$id = $entity->$getter();
return $id;
}
/**
* @param JsonDeserializationVisitor $visitor
* @param int|null $id
* @param array $type
* @param Context $context
* @return bool|\Doctrine\Common\Proxy\Proxy|null|object
* @throws \Doctrine\ORM\ORMException
*/
public function deserializeIdToEntity(JsonDeserializationVisitor $visitor, $id = null, array $type, Context $context)
{
if ($id === null) {
return null;
}
$entityName = $this->getEntityName($type);
if ($entity = $this->em->getReference($entityName, $id)) {
return $entity;
}
return null;
}
/**
* @param array $type
* @return string
* @throws \Exception
*/
private function getEntityName(array $type)
{
if (!(is_array($type['params']) && count($type['params']) && strlen($type['params'][0]))) {
throw new \Exception('You must specify entityName in @JMS\Type("EntityId<\'entity:name\'>") annotation.');
}
$entityName = $type['params'][0];
return $entityName;
}
/**
* @param array $type
* @return string
* @throws \Exception
*/
private function getEntityIdentifier(array $type)
{
$entityName = $this->getEntityName($type);
if (!$classMetadata = $this->em->getClassMetadata($entityName)) {
throw new \Exception(sprintf('Can\'t find metadata for class %s', $entityName));
}
$identifiers = $classMetadata->getIdentifier();
if (count($identifiers) != 1) {
throw new \Exception(sprintf('@JMS\Type("EntityId<>") supports entities with only one identifier, %s contains %s identifier(s).', $entityName, count($identifiers)));
}
$identifier = $identifiers[0];
return $identifier;
}
}
serializer_handler.entity_id:
...
class: MyVendor\MyBundle\Handler\EntityIdSerializeHandler
tags:
- { name: jms_serializer.subscribing_handler }
arguments: [@doctrine.orm.entity_manager]
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment