serializer->serialize($school, 'json'); self::assertEquals('{"type":"school"}', $json); $deserialized = $this->serializer->deserialize($json, Organization::class, 'json'); self::assertEquals($school, $deserialized); } public function testDiscriminatorIsInferredForGenericBaseClass() { $student = new Student(); $json = $this->serializer->serialize($student, 'json'); self::assertEquals('{"type":"student"}', $json); $deserialized = $this->serializer->deserialize($json, Person::class, 'json'); self::assertEquals($student, $deserialized); } public function testDiscriminatorIsInferredFromDoctrine() { /** @var EntityManager $em */ $em = $this->registry->getManager(); $student1 = new Student(); $student2 = new Student(); $teacher = new Teacher(); $class = new Clazz($teacher, [$student1, $student2]); $em->persist($student1); $em->persist($student2); $em->persist($teacher); $em->persist($class); $em->flush(); $em->clear(); $reloadedClass = $em->find(get_class($class), $class->getId()); self::assertNotSame($class, $reloadedClass); $json = $this->serializer->serialize($reloadedClass, 'json'); self::assertEquals('{"id":1,"teacher":{"id":1,"type":"teacher"},"students":[{"id":2,"type":"student"},{"id":3,"type":"student"}]}', $json); } protected function setUp() { $connection = $this->createConnection(); $entityManager = $this->createEntityManager($connection); $this->registry = $registry = new SimpleManagerRegistry( static function ($id) use ($connection, $entityManager) { switch ($id) { case 'default_connection': return $connection; case 'default_manager': return $entityManager; default: throw new \RuntimeException(sprintf('Unknown service id "%s".', $id)); } } ); $this->serializer = SerializerBuilder::create() ->setMetadataDriverFactory(new CallbackDriverFactory( static function (array $metadataDirs, Reader $annotationReader) use ($registry) { $defaultFactory = new DefaultDriverFactory(new IdenticalPropertyNamingStrategy()); return new DoctrineTypeDriver($defaultFactory->createDriver($metadataDirs, $annotationReader), $registry); } )) ->build(); $this->prepareDatabase(); } private function prepareDatabase() { /** @var EntityManager $em */ $em = $this->registry->getManager(); $tool = new SchemaTool($em); $tool->createSchema($em->getMetadataFactory()->getAllMetadata()); } private function createConnection() { return DriverManager::getConnection([ 'driver' => 'pdo_sqlite', 'memory' => true, ]); } private function createEntityManager(Connection $con) { $cfg = new Configuration(); $cfg->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader(), [ __DIR__ . '/../../Fixtures/Doctrine/SingleTableInheritance', ])); $cfg->setAutoGenerateProxyClasses(true); $cfg->setProxyNamespace('JMS\Serializer\DoctrineProxy'); $cfg->setProxyDir(sys_get_temp_dir() . '/serializer-test-proxies'); return EntityManager::create($con, $cfg); } } class SimpleManagerRegistry extends AbstractManagerRegistry { private $services = []; private $serviceCreator; public function __construct($serviceCreator, $name = 'anonymous', array $connections = ['default' => 'default_connection'], array $managers = ['default' => 'default_manager'], $defaultConnection = null, $defaultManager = null, $proxyInterface = 'Doctrine\Common\Persistence\Proxy') { if (null === $defaultConnection) { $defaultConnection = key($connections); } if (null === $defaultManager) { $defaultManager = key($managers); } parent::__construct($name, $connections, $managers, $defaultConnection, $defaultManager, $proxyInterface); if (!is_callable($serviceCreator)) { throw new \InvalidArgumentException('$serviceCreator must be a valid callable.'); } $this->serviceCreator = $serviceCreator; } public function getService($name) { if (isset($this->services[$name])) { return $this->services[$name]; } return $this->services[$name] = call_user_func($this->serviceCreator, $name); } public function resetService($name) { unset($this->services[$name]); } public function getAliasNamespace($alias) { foreach (array_keys($this->getManagers()) as $name) { $manager = $this->getManager($name); if ($manager instanceof EntityManager) { try { return $manager->getConfiguration()->getEntityNamespace($alias); } catch (ORMException $ex) { // Probably mapped by another entity manager, or invalid, just ignore this here. } } else { throw new \LogicException(sprintf('Unsupported manager type "%s".', get_class($manager))); } } throw new \RuntimeException(sprintf('The namespace alias "%s" is not known to any manager.', $alias)); } }