Explorar o código

Added support serialization the nested form errors.

Deni %!s(int64=13) %!d(string=hai) anos
pai
achega
78e021efda

+ 58 - 10
Serializer/Handler/FormErrorHandler.php

@@ -18,6 +18,7 @@
 
 namespace JMS\SerializerBundle\Serializer\Handler;
 
+use Symfony\Component\Form\Form;
 use Symfony\Component\Form\FormError;
 use Symfony\Component\Translation\TranslatorInterface;
 use JMS\SerializerBundle\Serializer\Handler\SerializationHandlerInterface;
@@ -35,21 +36,68 @@ class FormErrorHandler implements SerializationHandlerInterface
 
     public function serialize(VisitorInterface $visitor, $data, $type, &$handled)
     {
-        if (!$data instanceof FormError) {
-            return;
+        if ($data instanceof Form) {
+            $handled = true;
+
+            if ($visitor instanceof XmlSerializationVisitor) {
+                if (null === $visitor->document) {
+                    $visitor->document = $visitor->createDocument(null, null, false);
+                }
+
+                $formNode = $visitor->document->createElement('form');
+                $formNode->setAttribute('name', $data->getName());
+
+                if (null === $visitor->getCurrentNode()) {
+                    $visitor->document->appendChild($formNode);
+                }
+                else {
+                    $visitor->getCurrentNode()->appendChild($formNode);
+                }
+
+                // append errors node
+                $formNode->appendChild($errorsNode = $visitor->document->createElement('errors'));
+                $visitor->setCurrentNode($errorsNode);
+                $visitor->visitArray($data->getErrors(), $type);
+                $visitor->revertCurrentNode();
+
+                // if has nested form, append children node
+                if ($data->hasChildren()) {
+                    $formNode->appendChild($childrenNode = $visitor->document->createElement('children'));
+                    $visitor->setCurrentNode($childrenNode);
+
+                    foreach ($data->getChildren() as $child) {
+                        $this->serialize($visitor, $child, $type, $visited);
+                    }
+
+                    $visitor->revertCurrentNode();
+                }
+
+                return $formNode;
+            }
+            else {
+                $form = array('errors' => $data->getErrors());
+                if ($data->hasChildren()) {
+                    $form['children'] = $data->getChildren();
+                }
+
+                return $visitor->visitArray($form, $type);
+            }
         }
+        else if ($data instanceof FormError) {
+            $handled = true;
+            $message = $this->translator->trans($data->getMessageTemplate(), $data->getMessageParameters(), 'validators');
 
-        $handled = true;
-        $message = $this->translator->trans($data->getMessageTemplate(), $data->getMessageParameters(), 'validators');
+            if ($visitor instanceof XmlSerializationVisitor) {
+                if (null === $visitor->document) {
+                    $visitor->document = $visitor->createDocument(null, null, true);
+                }
 
-        if ($visitor instanceof XmlSerializationVisitor) {
-            if (null === $visitor->document) {
-                $visitor->document = $visitor->createDocument(null, null, true);
+                return $visitor->document->createCDATASection($message);
             }
 
-            return $visitor->document->createCDATASection($message);
+            return $message;
         }
 
-        return $message;
+        return null;
     }
-}
+}

+ 15 - 0
Tests/Serializer/BaseSerializationTest.php

@@ -19,6 +19,7 @@
 namespace JMS\SerializerBundle\Tests\Serializer;
 
 use Doctrine\Common\Collections\ArrayCollection;
+use Symfony\Component\Form\Form;
 use Symfony\Component\Form\FormError;
 use JMS\SerializerBundle\Serializer\Handler\DeserializationHandlerInterface;
 use JMS\SerializerBundle\Tests\Fixtures\AuthorList;
@@ -199,6 +200,20 @@ abstract class BaseSerializationTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->getContent('form_errors'), $this->serialize($errors));
     }
 
+    public function testNestedFormErrors()
+    {
+        $dispather = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
+
+        $form = new Form('foo', $dispather);
+        $form->addError(new FormError('This is the form error'));
+
+        $child = new Form('bar', $dispather);
+        $child->addError(new FormError('Error of the child form'));
+        $form->add($child);
+
+        $this->assertEquals($this->getContent('nested_form_errors'), $this->serialize($form));
+    }
+
     abstract protected function getContent($key);
     abstract protected function getFormat();
 

+ 1 - 0
Tests/Serializer/JsonSerializationTest.php

@@ -46,6 +46,7 @@ class JsonSerializationTest extends BaseSerializationTest
             $outputs['log'] = '{"author_list":[{"full_name":"Johannes Schmitt"},{"full_name":"John Doe"}],"comments":[{"author":{"full_name":"Foo Bar"},"text":"foo"},{"author":{"full_name":"Foo Bar"},"text":"bar"},{"author":{"full_name":"Foo Bar"},"text":"baz"}]}';
             $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"]}}}';
         }
 
         if (!isset($outputs[$key])) {

+ 13 - 0
Tests/Serializer/xml/nested_form_errors.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form name="foo">
+  <errors>
+    <entry><![CDATA[This is the form error]]></entry>
+  </errors>
+  <children>
+    <form name="bar">
+      <errors>
+        <entry><![CDATA[Error of the child form]]></entry>
+      </errors>
+    </form>
+  </children>
+</form>