Przeglądaj źródła

fixes a bug involving proxies and custom type handlers

Johannes M. Schmitt 12 lat temu
rodzic
commit
71388cc58d

+ 13 - 2
src/JMS/Serializer/EventDispatcher/Subscriber/DoctrineProxySubscriber.php

@@ -13,9 +13,17 @@ class DoctrineProxySubscriber implements EventSubscriberInterface
     public function onPreSerialize(PreSerializeEvent $event)
     public function onPreSerialize(PreSerializeEvent $event)
     {
     {
         $object = $event->getObject();
         $object = $event->getObject();
+        $type = $event->getType();
+
+        // If the set type name is not an actual class, but a faked type for which a custom handler exists, we do not
+        // modify it with this subscriber. Also, we forgo autoloading here as an instance of this type is already created,
+        // so it must be loaded if its a real class.
+        $virtualType = ! class_exists($type['name'], false);
 
 
         if ($object instanceof PersistentCollection) {
         if ($object instanceof PersistentCollection) {
-            $event->setType('ArrayCollection');
+            if ( ! $virtualType) {
+                $event->setType('ArrayCollection');
+            }
 
 
             return;
             return;
         }
         }
@@ -25,7 +33,10 @@ class DoctrineProxySubscriber implements EventSubscriberInterface
         }
         }
 
 
         $object->__load();
         $object->__load();
-        $event->setType(get_parent_class($object));
+
+        if ( ! $virtualType) {
+            $event->setType(get_parent_class($object));
+        }
     }
     }
 
 
     public static function getSubscribedEvents()
     public static function getSubscribedEvents()

+ 46 - 0
tests/JMS/Serializer/Tests/Serializer/EventDispatcher/Subscriber/DoctrineProxySubscriberTest.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace JMS\Serializer\Tests\Serializer\EventDispatcher\Subscriber;
+
+use JMS\Serializer\EventDispatcher\PreSerializeEvent;
+use JMS\Serializer\EventDispatcher\Subscriber\DoctrineProxySubscriber;
+use JMS\Serializer\Tests\Fixtures\SimpleObjectProxy;
+use JMS\Serializer\VisitorInterface;
+
+class DoctrineProxySubscriberTest extends \PHPUnit_Framework_TestCase
+{
+    /** @var VisitorInterface */
+    private $visitor;
+
+    /** @var DoctrineProxySubscriber */
+    private $subscriber;
+
+    public function testRewritesProxyClassName()
+    {
+        $event = $this->createEvent($obj = new SimpleObjectProxy('a', 'b'), array('name' => get_class($obj), 'params' => array()));
+        $this->subscriber->onPreSerialize($event);
+
+        $this->assertEquals(array('name' => get_parent_class($obj), 'params' => array()), $event->getType());
+        $this->assertTrue($obj->__isInitialized());
+    }
+
+    public function testDoesNotRewriteCustomType()
+    {
+        $event = $this->createEvent($obj = new SimpleObjectProxy('a', 'b'), array('name' => 'FakedName', 'params' => array()));
+        $this->subscriber->onPreSerialize($event);
+
+        $this->assertEquals(array('name' => 'FakedName', 'params' => array()), $event->getType());
+        $this->assertTrue($obj->__isInitialized());
+    }
+
+    protected function setUp()
+    {
+        $this->subscriber = new DoctrineProxySubscriber();
+        $this->visitor = $this->getMock('JMS\Serializer\VisitorInterface');
+    }
+
+    private function createEvent($object, array $type)
+    {
+        return new PreSerializeEvent($this->visitor, $object, $type);
+    }
+}