2013-11-28 35 views
5

Chcę desirialize JSON ręcznie z JMSSerializerBundle. Mam problemy z HandlerCallback. Oto kod:Serializator JMS, jak obsługiwać serializację ręcznie?

namespace Company\Bundle\Model; 

use JMS\Serializer\Annotation\Type; 
use JMS\Serializer\Annotation\SerializedName; 
use JMS\Serializer\Annotation\HandlerCallback; 
use JMS\Serializer\JsonDeserializationVisitor; 
use JMS\Serializer\DeserializationContext; 
use JMS\Serializer\TypeParser; 
use JMS\Serializer\Serializer; 

class Blog 
{ 
    protected $blogName; 

    protected $blogUrl; 

    protected $blogCategory; 
    /** 
    * @Type("array<Company\Bundle\Model\Post>") 
    * @SerializedName("data") 
    */ 
    protected $posts; 

    /** 
    * @param mixed $posts 
    */ 
    public function setPosts($posts) 
    { 
     $this->posts = $posts; 
    } 

    /** 
    * @return mixed 
    */ 
    public function getPosts() 
    { 
     return $this->posts; 
    } 

    /** 
    * @HandlerCallback("json", direction = "deserialization") 
    */ 
    public function deserializeFromJson(JsonDeserializationVisitor $visitor, array $data, DeserializationContext $context) 
    { 
     $this->blogName = $data['data'][0]['blogName']; 
     $this->blogUrl = $data['data'][0]['blogUrl']; 
     $this->blogCategory = $data['data'][0]['blogCategory']; 

     $this->posts = ????; 
    } 
} 

Co powinienem dodać zamiast ???? aby uzyskać tablicę obiektów Company \ Bundle \ model \ Napisz

+0

jedynym oficjalnym przykłady/dokumentacja są tutaj: https://github.com/schmittjoh/serializer/blob/master/tests/JMS/Serializer/Tests/Fixtures/Article.php – Damien

Odpowiedz

2

Może Somthing tak:

/** 
* @HandlerCallback("json", direction = "deserialization") 
*/ 
public function deserializeFromJson(JsonDeserializationVisitor $visitor, array $data, DeserializationContext $context) 
{ 
    $this->blogName = $data['data'][0]['blogName']; 
    $this->blogUrl = $data['data'][0]['blogUrl']; 
    $this->blogCategory = $data['data'][0]['blogCategory']; 

    $this->posts = new ArrayCollection(); 
    for ($data['data'][0]['posts'] as $post_data){ 
     $this->posts->add(new Post($post_data)); 
     // OR 
     $this->posts->add(Post::deserializeFromJson($post_data)); 
    } 
} 
+0

Próbowałem, ale to będzie utwórz nowy pusty obiekt $ this-> addPost (nowy post ($ post_data)); To $ this-> addPost (Post :: deserializeFromJson ($ post_data)); nie jest w porządku, ponieważ nie ma takiej statycznej metody. – klipach

+0

Rzeczywiście, musisz napisać własną metodę 'Post :: deserializeFromJson' :) –

+0

W tym przypadku, co jest zaletą korzystania z JMS/serializera, jeśli powinienem napisać własną metodę deserializeFromJson :) – klipach

2

rzeczywiście można ponownie użyć innych przedmiotów oraz lokalne adnotacje.

/** 
* @HandlerCallback("json", direction = "deserialization") 
*/ 
public function deserializeFromJson(JsonDeserializationVisitor $visitor, array $data, DeserializationContext $context) 
{ 
    $typeParser = new TypeParser(); 

    /** @var ClassMetadata $metadata */ 
    $metadata = $context->getMetadataFactory()->getMetadataForClass(self::class); 
    $visitor->startVisitingObject($metadata, $this, $typeParser->parse(self::class), $context); 

    $visitor->visitProperty($metadata->propertyMetadata['blogName'], $data['data'][0], $context); 
    $visitor->visitProperty($metadata->propertyMetadata['blogUrl'], $data['data'][0], $context); 
    $visitor->visitProperty($metadata->propertyMetadata['blogCategory'], $data['data'][0], $context); 
    $visitor->visitProperty($metadata->propertyMetadata['posts'], $data['data'][0], $context); 
}