瀏覽代碼

Implement the handler of serialization to process the proxy of Doctrine ORM.

Deni 13 年之前
父節點
當前提交
44fea2c2de

+ 33 - 0
DependencyInjection/Factory/DoctrineOrmProxyFactory.php

@@ -0,0 +1,33 @@
+<?php
+
+namespace JMS\SerializerBundle\DependencyInjection\Factory;
+
+use JMS\SerializerBundle\DependencyInjection\HandlerFactoryInterface;
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
+
+class DoctrineOrmProxyFactory implements HandlerFactoryInterface
+{
+    public function getConfigKey()
+    {
+        return 'doctrine_orm';
+    }
+
+    public function getType(array $config)
+    {
+        return self::TYPE_SERIALIZATION;
+    }
+
+    public function addConfiguration(ArrayNodeDefinition $builder)
+    {
+        $builder
+            ->addDefaultsIfNotSet()
+            ->defaultValue(array())
+        ;
+    }
+
+    public function getHandlerId(ContainerBuilder $container, array $config)
+    {
+        return 'jms_serializer.doctrine_orm_handler';
+    }
+}

+ 2 - 0
JMSSerializerBundle.php

@@ -23,6 +23,7 @@ use JMS\SerializerBundle\DependencyInjection\Factory\DateTimeFactory;
 use JMS\SerializerBundle\DependencyInjection\Factory\ConstraintViolationFactory;
 use JMS\SerializerBundle\DependencyInjection\Factory\ArrayCollectionFactory;
 use JMS\SerializerBundle\DependencyInjection\Factory\ObjectBasedFactory;
+use JMS\SerializerBundle\DependencyInjection\Factory\DoctrineOrmProxyFactory;
 use JMS\SerializerBundle\DependencyInjection\JMSSerializerExtension;
 use Symfony\Component\HttpKernel\KernelInterface;
 use JMS\SerializerBundle\DependencyInjection\Compiler\SetVisitorsPass;
@@ -46,6 +47,7 @@ class JMSSerializerBundle extends Bundle
     public function configureSerializerExtension(JMSSerializerExtension $ext)
     {
         $ext->addHandlerFactory(new ObjectBasedFactory());
+        $ext->addHandlerFactory(new DoctrineOrmProxyFactory());
         $ext->addHandlerFactory(new ArrayCollectionFactory());
         $ext->addHandlerFactory(new ConstraintViolationFactory());
         $ext->addHandlerFactory(new DateTimeFactory());

+ 2 - 0
Resources/config/services.xml

@@ -37,6 +37,7 @@
         <parameter key="jms_serializer.array_collection_handler.class">JMS\SerializerBundle\Serializer\Handler\ArrayCollectionHandler</parameter>
         <parameter key="jms_serializer.form_error_handler.class">JMS\SerializerBundle\Serializer\Handler\FormErrorHandler</parameter>
         <parameter key="jms_serializer.constraint_violation_handler.class">JMS\SerializerBundle\Serializer\Handler\ConstraintViolationHandler</parameter>
+        <parameter key="jms_serializer.doctrine_orm_handler.class">JMS\SerializerBundle\Serializer\Handler\DoctrineOrmProxyHandler</parameter>
     </parameters>
 
     <services>
@@ -154,5 +155,6 @@
             <argument type="service" id="translator" />
         </service>
         <service id="jms_serializer.constraint_violation_handler" class="%jms_serializer.constraint_violation_handler.class%" public="false" />
+        <service id="jms_serializer.doctrine_orm_handler" class="%jms_serializer.doctrine_orm_handler.class%" public="false" />
     </services>
 </container>

+ 46 - 0
Serializer/Handler/DoctrineOrmProxyHandler.php

@@ -0,0 +1,46 @@
+<?php
+
+/*
+ * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace JMS\SerializerBundle\Serializer\Handler;
+
+use Doctrine\ORM\Proxy\Proxy;
+use JMS\SerializerBundle\Serializer\VisitorInterface;
+use JMS\SerializerBundle\Serializer\Handler\SerializationHandlerInterface;
+
+class DoctrineOrmProxyHandler implements SerializationHandlerInterface
+{
+    public function serialize(VisitorInterface $visitor, $data, $type, &$handled)
+    {
+        if ($data instanceof Proxy && get_class($data) === $type) {
+            $handled = true;
+            $parents = class_parents($data);
+
+            if (false === $parents || count($parents) == 0) {
+                throw new \LogicException(sprintf('The proxy "%s" must extend any other class.', get_class($data)));
+            }
+
+            if (method_exists($data, '__load')) {
+                $data->__load();
+            }
+
+            return $visitor->getNavigator()->accept($data, array_pop($parents), $visitor);
+        }
+
+        return null;
+    }
+}

+ 29 - 0
Tests/Fixtures/SimpleObjectProxy.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * Copyright 2011 Johannes M. Schmitt <schmittjoh@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace JMS\SerializerBundle\Tests\Fixtures;
+
+use Doctrine\ORM\Proxy\Proxy;
+
+class SimpleObjectProxy extends SimpleObject implements Proxy
+{
+    public function __load()
+    {
+        $this->camelCase = 'proxy-boo';
+    }
+}

+ 14 - 0
Tests/Serializer/BaseSerializationTest.php

@@ -44,6 +44,7 @@ use JMS\SerializerBundle\Serializer\Handler\ObjectBasedCustomHandler;
 use JMS\SerializerBundle\Serializer\Handler\DateTimeHandler;
 use JMS\SerializerBundle\Serializer\Handler\FormErrorHandler;
 use JMS\SerializerBundle\Serializer\Handler\ConstraintViolationHandler;
+use JMS\SerializerBundle\Serializer\Handler\DoctrineOrmProxyHandler;
 use JMS\SerializerBundle\Tests\Fixtures\Comment;
 use JMS\SerializerBundle\Tests\Fixtures\Author;
 use JMS\SerializerBundle\Tests\Fixtures\BlogPost;
@@ -54,6 +55,7 @@ use Doctrine\Common\Annotations\AnnotationReader;
 use JMS\SerializerBundle\Metadata\Driver\AnnotationDriver;
 use Metadata\MetadataFactory;
 use JMS\SerializerBundle\Tests\Fixtures\SimpleObject;
+use JMS\SerializerBundle\Tests\Fixtures\SimpleObjectProxy;
 use JMS\SerializerBundle\Tests\Fixtures\Price;
 use JMS\SerializerBundle\Serializer\Naming\CamelCaseNamingStrategy;
 use JMS\SerializerBundle\Serializer\Naming\SerializedNameAnnotationStrategy;
@@ -334,6 +336,17 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->getContent('constraint_violation_list'), $this->serialize($violations));
     }
 
+    public function testDoctrineOrmProxy()
+    {
+        if (!class_exists('Doctrine\ORM\Version')) {
+            $this->markTestSkipped('Doctrine is not available.');
+        }
+
+        $object = new SimpleObjectProxy('foo', 'bar');
+
+        $this->assertEquals($this->getContent('orm_proxy'), $this->serialize($object));
+    }
+
     abstract protected function getContent($key);
     abstract protected function getFormat();
 
@@ -390,6 +403,7 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
             new DateTimeHandler(),
             new FormErrorHandler($translatorMock),
             new ConstraintViolationHandler(),
+            new DoctrineOrmProxyHandler(),
         );
 
         return $handlers;

+ 1 - 0
Tests/Serializer/JsonSerializationTest.php

@@ -54,6 +54,7 @@ class JsonSerializationTest extends BaseSerializationTest
             $outputs['constraint_violation'] = '{"property_path":"foo","message":"Message of violation"}';
             $outputs['constraint_violation_list'] = '[{"property_path":"foo","message":"Message of violation"},{"property_path":"bar","message":"Message of another violation"}]';
             $outputs['article'] = '{"custom":"serialized"}';
+            $outputs['orm_proxy'] = '{"foo":"foo","moo":"bar","camel_case":"proxy-boo"}';
         }
 
         if (!isset($outputs[$key])) {

+ 6 - 0
Tests/Serializer/xml/orm_proxy.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<result>
+  <foo><![CDATA[foo]]></foo>
+  <moo><![CDATA[bar]]></moo>
+  <camel_case><![CDATA[proxy-boo]]></camel_case>
+</result>

+ 3 - 0
Tests/Serializer/yml/orm_proxy.yml

@@ -0,0 +1,3 @@
+foo: foo
+moo: bar
+camel_case: proxy-boo