Browse Source

add VirtualPropertyMetadata for virtual method annotation

Aleksandr Klimenkov 13 years ago
parent
commit
f72bc8ed49

+ 0 - 8
Metadata/ClassMetadata.php

@@ -38,7 +38,6 @@ class ClassMetadata extends MergeableClassMetadata
     public $preSerializeMethods = array();
     public $postSerializeMethods = array();
     public $postDeserializeMethods = array();
-    public $virtualPropertyMethods = array();
     public $xmlRootName;
     public $accessorOrder;
     public $customOrder;
@@ -87,11 +86,6 @@ class ClassMetadata extends MergeableClassMetadata
         $this->postDeserializeMethods[] = $method;
     }
 
-    public function addVirtualPropertyMethod(MethodMetadata $method, $field)
-    {
-        $this->virtualPropertyMethods[$field] = $method;
-    }
-	
     public function merge(MergeableInterface $object)
     {
         if (!$object instanceof ClassMetadata) {
@@ -120,7 +114,6 @@ class ClassMetadata extends MergeableClassMetadata
             $this->preSerializeMethods,
             $this->postSerializeMethods,
             $this->postDeserializeMethods,
-            $this->virtualPropertyMethods,
             $this->xmlRootName,
             $this->accessorOrder,
             $this->customOrder,
@@ -134,7 +127,6 @@ class ClassMetadata extends MergeableClassMetadata
             $this->preSerializeMethods,
             $this->postSerializeMethods,
             $this->postDeserializeMethods,
-            $this->virtualPropertyMethods,
             $this->xmlRootName,
             $this->accessorOrder,
             $this->customOrder,

+ 4 - 1
Metadata/Driver/AnnotationDriver.php

@@ -47,6 +47,7 @@ use JMS\SerializerBundle\Annotation\Inline;
 use JMS\SerializerBundle\Annotation\ReadOnly;
 use JMS\SerializerBundle\Metadata\ClassMetadata;
 use JMS\SerializerBundle\Metadata\PropertyMetadata;
+use JMS\SerializerBundle\Metadata\VirtualPropertyMetadata;
 use Metadata\Driver\DriverInterface;
 
 class AnnotationDriver implements DriverInterface
@@ -154,7 +155,9 @@ class AnnotationDriver implements DriverInterface
                     $classMetadata->addPostSerializeMethod(new MethodMetadata($name, $method->getName()));
                     continue 2;
                 } else if ($annot instanceof Virtual) {
-                    $classMetadata->addVirtualPropertyMethod( new MethodMetadata($name, $method->getName()), $annot->field);
+                    $virtualPropertyMetadata = new VirtualPropertyMetadata($name, $annot->field);
+                    $virtualPropertyMetadata->getter = $method->getName();
+                    $classMetadata->addPropertyMetadata( $virtualPropertyMetadata );
                     continue 2;
                 }
             }

+ 56 - 0
Metadata/VirtualPropertyMetadata.php

@@ -0,0 +1,56 @@
+<?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\Metadata;
+
+
+class VirtualPropertyMetadata extends PropertyMetadata
+{
+
+	public function __construct($class, $name)
+    {
+        $this->class = $class;
+        $this->name = $name;
+		$this->readOnly = true;
+    }
+
+    public function getValue($obj)
+    {
+        return $obj->{$this->getter}();
+    }
+	
+    public function setValue($obj, $value)
+    {
+        return false;
+    }
+
+    public function serialize()
+    {
+        return serialize(array(
+            $this->class,
+            $this->name,
+			$this->getter
+        ));
+    }
+
+    public function unserialize($str)
+    {
+        list($this->class, $this->name, $this->getter) = unserialize($str);
+		$this->readOnly = true;
+    }	
+}

+ 0 - 4
Serializer/GenericSerializationVisitor.php

@@ -113,10 +113,6 @@ abstract class GenericSerializationVisitor extends AbstractSerializationVisitor
 
         $this->dataStack->push($this->data);
         $this->data = array();
-		
-        foreach( $metadata->virtualPropertyMethods as $field => $method ) {
-            $this->data[$field] = $method->invoke($data);
-        }
     }
 
     public function endVisitingObject(ClassMetadata $metadata, $data, $type)

+ 0 - 6
Serializer/XmlSerializationVisitor.php

@@ -143,12 +143,6 @@ class XmlSerializationVisitor extends AbstractSerializationVisitor
         }
 
         $this->hasValue = false;
-
-        foreach( $metadata->virtualPropertyMethods as $field => $method ) {
-            $element = $this->getDocument()->createElement($field);
-            $element->appendChild($this->getDocument()->createCDATASection( (string) $method->invoke($data)));
-            $this->getCurrentNode()->appendChild($element);
-        }
     }
 
     public function visitProperty(PropertyMetadata $metadata, $object)

+ 0 - 4
Serializer/YamlSerializationVisitor.php

@@ -143,10 +143,6 @@ class YamlSerializationVisitor extends AbstractSerializationVisitor
 
     public function startVisitingObject(ClassMetadata $metadata, $data, $type)
     {
-        foreach( $metadata->virtualPropertyMethods as $field => $method ) {
-            $this->writer
-                ->writeln(Inline::dump($field).': ' . $method->invoke($data));
-        }
     }
 
     public function visitProperty(PropertyMetadata $metadata, $data)

+ 4 - 1
Tests/Fixtures/ObjectWithVirtualProperty.php

@@ -18,12 +18,15 @@
 
 namespace JMS\SerializerBundle\Tests\Fixtures;
 
-use JMS\SerializerBundle\Annotation\SerializedName;
+use JMS\SerializerBundle\Annotation\Type;
 use JMS\SerializerBundle\Annotation\Virtual;
 
 class ObjectWithVirtualProperty
 {
 
+	/**
+	 * @Type("string")
+	 */
 	protected $existField = 'value';
     
 	/**

+ 1 - 1
Tests/Serializer/JsonSerializationTest.php

@@ -64,7 +64,7 @@ class JsonSerializationTest extends BaseSerializationTest
             $outputs['groups_all'] = '{"foo":"foo","foobar":"foobar","bar":"bar","none":"none"}';
             $outputs['groups_foo'] = '{"foo":"foo","foobar":"foobar"}';
             $outputs['groups_foobar'] = '{"foo":"foo","foobar":"foobar","bar":"bar"}';
-            $outputs['virtual_property'] = '{"foo":"bar","exist_field":"value"}';
+            $outputs['virtual_property'] = '{"exist_field":"value","foo":"bar"}';
         }
 
         if (!isset($outputs[$key])) {

+ 1 - 1
Tests/Serializer/xml/virtual_property.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <result>
-  <foo><![CDATA[bar]]></foo>
   <exist_field><![CDATA[value]]></exist_field>
+  <foo><![CDATA[bar]]></foo>
 </result>

+ 1 - 1
Tests/Serializer/yml/virtual_property.yml

@@ -1,2 +1,2 @@
-foo: bar
 exist_field: value
+foo: bar