瀏覽代碼

Added the constraint violation handler

Deni 13 年之前
父節點
當前提交
79edce0f94

+ 1 - 0
DependencyInjection/Configuration.php

@@ -59,6 +59,7 @@ class Configuration implements ConfigurationInterface
                             ->end()
                             ->booleanNode('array_collection')->defaultTrue()->end()
                             ->booleanNode('form_error')->defaultTrue()->end()
+                            ->booleanNode('constraint_violation')->defaultTrue()->end()
                         ->end()
                     ->end()
                     ->arrayNode('metadata')

+ 5 - 0
DependencyInjection/JMSSerializerExtension.php

@@ -72,6 +72,11 @@ class JMSSerializerExtension extends Extension
             $container->removeDefinition('jms_serializer.form_error_handler');
         }
 
+        // constraint violation handler
+        if (!$config['handlers']['constraint_violation']) {
+            $container->removeDefinition('jms_serializer.constraint_violation_handler');
+        }
+
         // metadata
         if ('none' === $config['metadata']['cache']) {
             $container->removeAlias('jms_serializer.metadata.cache');

+ 4 - 0
Resources/config/services.xml

@@ -34,6 +34,7 @@
         <parameter key="jms_serializer.datetime_handler.class">JMS\SerializerBundle\Serializer\Handler\DateTimeHandler</parameter>
         <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>
     </parameters>
 
     <services>
@@ -147,5 +148,8 @@
             <argument type="service" id="translator" />
             <tag name="jms_serializer.serialization_handler" />
         </service>
+        <service id="jms_serializer.constraint_violation_handler" class="%jms_serializer.constraint_violation_handler.class%" public="false">
+            <tag name="jms_serializer.serialization_handler" />
+        </service>
     </services>
 </container>

+ 83 - 0
Serializer/Handler/ConstraintViolationHandler.php

@@ -0,0 +1,83 @@
+<?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 Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use JMS\SerializerBundle\Serializer\Handler\SerializationHandlerInterface;
+use JMS\SerializerBundle\Serializer\VisitorInterface;
+use JMS\SerializerBundle\Serializer\GenericSerializationVisitor;
+use JMS\SerializerBundle\Serializer\XmlSerializationVisitor;
+
+class ConstraintViolationHandler implements SerializationHandlerInterface
+{
+    function serialize(VisitorInterface $visitor, $data, $type, &$handled)
+    {
+        if ($data instanceof ConstraintViolationList) {
+            if ($visitor instanceof XmlSerializationVisitor) {
+                $handled = true;
+
+                if (null === $visitor->document) {
+                    $visitor->document = $visitor->createDocument();
+                }
+
+                foreach ($data as $violation) {
+                    $this->serialize($visitor, $violation, null, $visited);
+                }
+            }
+        } else if ($data instanceof ConstraintViolation) {
+            if ($visitor instanceof XmlSerializationVisitor) {
+                $handled = true;
+
+                if (null === $visitor->document) {
+                    $visitor->document = $visitor->createDocument(null, null, false);
+                    $visitor->document->appendChild($violationNode = $visitor->document->createElement('violation'));
+                    $visitor->setCurrentNode($violationNode);
+                }
+                else {
+                    $visitor->getCurrentNode()->appendChild(
+                        $violationNode = $visitor->document->createElement('violation')
+                    );
+                }
+
+                $violationNode->setAttribute('property_path', $data->getPropertyPath());
+                $violationNode->appendChild($messageNode = $visitor->document->createElement('message'));
+
+                $messageNode->appendChild($visitor->document->createCDATASection($data->getMessage()));
+
+                return;
+            } else if ($visitor instanceof GenericSerializationVisitor) {
+                $handled = true;
+
+                $violation = array(
+                    'property_path' => $data->getPropertyPath(),
+                    'message' =>$data->getMessage()
+                );
+
+                if (null === $visitor->getRoot()) {
+                    $visitor->setRoot($violation);
+                }
+
+                return $violation;
+            }
+        }
+
+        return;
+    }
+}

+ 21 - 1
Tests/Serializer/BaseSerializationTest.php

@@ -21,16 +21,19 @@ namespace JMS\SerializerBundle\Tests\Serializer;
 use Doctrine\Common\Collections\ArrayCollection;
 use Symfony\Component\Form\Form;
 use Symfony\Component\Form\FormError;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
 use JMS\SerializerBundle\Serializer\Handler\DeserializationHandlerInterface;
 use JMS\SerializerBundle\Tests\Fixtures\AuthorList;
 use JMS\SerializerBundle\Serializer\VisitorInterface;
-use JMS\SerializerBundle\Serializer\Handler\ArrayCollectionHandler;
 use JMS\SerializerBundle\Serializer\XmlDeserializationVisitor;
 use JMS\SerializerBundle\Serializer\Construction\UnserializeObjectConstructor;
 use JMS\SerializerBundle\Serializer\JsonDeserializationVisitor;
 use JMS\SerializerBundle\Tests\Fixtures\Log;
+use JMS\SerializerBundle\Serializer\Handler\ArrayCollectionHandler;
 use JMS\SerializerBundle\Serializer\Handler\DateTimeHandler;
 use JMS\SerializerBundle\Serializer\Handler\FormErrorHandler;
+use JMS\SerializerBundle\Serializer\Handler\ConstraintViolationHandler;
 use JMS\SerializerBundle\Tests\Fixtures\Comment;
 use JMS\SerializerBundle\Tests\Fixtures\Author;
 use JMS\SerializerBundle\Tests\Fixtures\BlogPost;
@@ -214,6 +217,22 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->getContent('nested_form_errors'), $this->serialize($form));
     }
 
+    public function testConstraintViolation()
+    {
+        $violation = new ConstraintViolation('Message of violation', array(), null, 'foo', null);
+
+        $this->assertEquals($this->getContent('constraint_violation'), $this->serialize($violation));
+    }
+
+    public function testConstraintViolationList()
+    {
+        $violations = new ConstraintViolationList();
+        $violations->add(new ConstraintViolation('Message of violation', array(), null, 'foo', null));
+        $violations->add(new ConstraintViolation('Message of another violation', array(), null, 'bar', null));
+
+        $this->assertEquals($this->getContent('constraint_violation_list'), $this->serialize($violations));
+    }
+
     abstract protected function getContent($key);
     abstract protected function getFormat();
 
@@ -259,6 +278,7 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
         $handlers = array(
             new DateTimeHandler(),
             new FormErrorHandler($translatorMock),
+            new ConstraintViolationHandler(),
         );
 
         return $handlers;

+ 2 - 0
Tests/Serializer/JsonSerializationTest.php

@@ -47,6 +47,8 @@ class JsonSerializationTest extends BaseSerializationTest
             $outputs['lifecycle_callbacks'] = '{"name":"Foo Bar"}';
             $outputs['form_errors'] = '["This is the form error","Another error"]';
             $outputs['nested_form_errors'] = '{"errors":["This is the form error"],"children":{"bar":{"errors":["Error of the child form"]}}}';
+            $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"}]';
         }
 
         if (!isset($outputs[$key])) {

+ 4 - 0
Tests/Serializer/xml/constraint_violation.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<violation property_path="foo">
+  <message><![CDATA[Message of violation]]></message>
+</violation>

+ 9 - 0
Tests/Serializer/xml/constraint_violation_list.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<result>
+  <violation property_path="foo">
+    <message><![CDATA[Message of violation]]></message>
+  </violation>
+  <violation property_path="bar">
+    <message><![CDATA[Message of another violation]]></message>
+  </violation>
+</result>