浏览代码

added some more lifecycle callbacks

Johannes Schmitt 14 年之前
父节点
当前提交
93dc77ddad

+ 8 - 0
Annotation/PostSerialize.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace JMS\SerializerBundle\Annotation;
+
+/** @Annotation */
+final class PostSerialize
+{
+}

+ 8 - 0
Annotation/PreDeserialize.php

@@ -0,0 +1,8 @@
+<?php
+
+namespace JMS\SerializerBundle\Annotation;
+
+/** @Annotation */
+final class PreDeserialize
+{
+}

+ 16 - 0
Metadata/ClassMetadata.php

@@ -25,6 +25,8 @@ class ClassMetadata extends BaseClassMetadata
 {
     public $exclusionPolicy = 'NONE';
     public $preSerializeMethods = array();
+    public $postSerializeMethods = array();
+    public $preDeserializeMethods = array();
     public $postDeserializeMethods = array();
 
     public function addPreSerializeMethod(MethodMetadata $method)
@@ -32,6 +34,16 @@ class ClassMetadata extends BaseClassMetadata
         $this->preSerializeMethods[] = $method;
     }
 
+    public function addPostSerializeMethod(MethodMetadata $method)
+    {
+        $this->postSerializeMethods[] = $method;
+    }
+
+    public function addPreDeserializeMethod(MethodMetadata $method)
+    {
+        $this->preDeserializeMethods[] = $method;
+    }
+
     public function addPostDeserializeMethod(MethodMetadata $method)
     {
         $this->postDeserializeMethods[] = $method;
@@ -42,6 +54,8 @@ class ClassMetadata extends BaseClassMetadata
         return serialize(array(
             $this->exclusionPolicy,
             $this->preSerializeMethods,
+            $this->postSerializeMethods,
+            $this->preDeserializeMethods,
             $this->postDeserializeMethods,
             parent::serialize(),
         ));
@@ -52,6 +66,8 @@ class ClassMetadata extends BaseClassMetadata
         list(
             $this->exclusionPolicy,
             $this->preSerializeMethods,
+            $this->postSerializeMethods,
+            $this->preDeserializeMethods,
             $this->postDeserializeMethods,
             $parentStr
         ) = unserialize($str);

+ 8 - 3
Metadata/Driver/AnnotationDriver.php

@@ -18,12 +18,11 @@
 
 namespace JMS\SerializerBundle\Metadata\Driver;
 
+use JMS\SerializerBundle\Annotation\PostSerialize;
 use JMS\SerializerBundle\Annotation\PostDeserialize;
-
 use JMS\SerializerBundle\Annotation\PreSerialize;
-
+use JMS\SerializerBundle\Annotation\PreDeserialize;
 use Metadata\MethodMetadata;
-
 use Doctrine\Common\Annotations\Reader;
 use JMS\SerializerBundle\Annotation\Type;
 use JMS\SerializerBundle\Annotation\Exclude;
@@ -92,6 +91,12 @@ class AnnotationDriver implements DriverInterface
                 } else if ($annot instanceof PostDeserialize) {
                     $classMetadata->addPostDeserializeMethod(new MethodMetadata($name, $method->getName()));
                     continue 2;
+                } else if ($annot instanceof PostSerialize) {
+                    $classMetadata->addPostSerializeMethod(new MethodMetadata($name, $method->getName()));
+                    continue 2;
+                } else if ($annot instanceof PreDeserialize) {
+                    $classMetadata->addPreDeserializeMethod(new MethodMetadata($name, $method->getName()));
+                    continue 2;
                 }
             }
         }

+ 8 - 0
Serializer/Normalizer/PropertyBasedNormalizer.php

@@ -85,6 +85,10 @@ class PropertyBasedNormalizer extends SerializerAwareNormalizer
 
                 $normalized[$this->propertyNamingStrategy->translateName($propertyMetadata)] = $value;
             }
+
+            foreach ($classMetadata->postSerializeMethods as $method) {
+                $method->invoke($object);
+            }
         }
 
         return $normalized;
@@ -105,6 +109,10 @@ class PropertyBasedNormalizer extends SerializerAwareNormalizer
         foreach ($metadata->classMetadata as $classMetadata) {
             $exclusionStrategy = $this->exclusionStrategyFactory->getStrategy($classMetadata->exclusionPolicy);
 
+            foreach ($classMetadata->preDeserializeMethods as $method) {
+                $method->invoke($object);
+            }
+
             foreach ($classMetadata->propertyMetadata as $propertyMetadata) {
                 if ($exclusionStrategy->shouldSkipProperty($propertyMetadata)) {
                     continue;

+ 23 - 0
Tests/Fixtures/ObjectWithLifecycleCallbacks.php

@@ -4,6 +4,8 @@ namespace JMS\SerializerBundle\Tests\Fixtures;
 
 use JMS\SerializerBundle\Annotation\Exclude;
 use JMS\SerializerBundle\Annotation\PreSerialize;
+use JMS\SerializerBundle\Annotation\PostSerialize;
+use JMS\SerializerBundle\Annotation\PreDeserialize;
 use JMS\SerializerBundle\Annotation\PostDeserialize;
 use JMS\SerializerBundle\Annotation\Type;
 
@@ -24,6 +26,11 @@ class ObjectWithLifecycleCallbacks
      */
     private $name;
 
+    /**
+     * @Exclude
+     */
+    public $preDeserializeCalled = false;
+
     public function __construct($firstname = 'Foo', $lastname = 'Bar')
     {
         $this->firstname = $firstname;
@@ -38,6 +45,14 @@ class ObjectWithLifecycleCallbacks
         $this->name = $this->firstname.' '.$this->lastname;
     }
 
+    /**
+     * @PostSerialize
+     */
+    private function cleanUpAfterSerialization()
+    {
+        $this->name = null;
+    }
+
     /**
      * @PostDeserialize
      */
@@ -45,4 +60,12 @@ class ObjectWithLifecycleCallbacks
     {
         list($this->firstname, $this->lastname) = explode(' ', $this->name);
     }
+
+    /**
+     * @PreDeserialize
+     */
+    private function beforeDeserialization()
+    {
+        $this->preDeserializeCalled = true;
+    }
 }

+ 5 - 1
Tests/Serializer/SerializerTest.php

@@ -98,8 +98,12 @@ class SerializerTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(json_encode(array(
             'name' => 'Foo Bar',
         )), $serialized = $serializer->serialize($object, 'json'));
+        $this->assertAttributeEquals(null, 'name', $object);
 
-        $this->assertEquals($object, $serializer->deserialize($serialized, 'JMS\SerializerBundle\Tests\Fixtures\ObjectWithLifecycleCallbacks', 'json'));
+        $deserializedObject = $serializer->deserialize($serialized, 'JMS\SerializerBundle\Tests\Fixtures\ObjectWithLifecycleCallbacks', 'json');
+        $this->assertAttributeEquals('Foo', 'firstname', $deserializedObject);
+        $this->assertAttributeEquals('Bar', 'lastname', $deserializedObject);
+        $this->assertTrue($deserializedObject->preDeserializeCalled);
     }
 
     private function getSerializer($propertyNamingStrategy = null, $encoders = null, $customNormalizers = null)