2017-01-09 79 views
0

例如,我有兩個實體:主(父)實體(例如User)和從屬實體(Post)。我想使用JMS序列化器序列化User實體,並提供其第一個發佈日期的其他信息。存儲在數據庫中的發佈日期是timestamp int,但我想用我的幫助器(只是一個服務)將其轉換爲int,並將其轉換爲一些格式化的sting。複雜序列化

嘗試在實體類中使用方法創建virtual_property,但未能將我的幫助器注入到實體類中。解決這個問題對我來說,唯一的辦法是自己序列化爲控制器:

public function someAction() 
{ 
    $serializedUser = $this->serializeEntity($user); 
} 

public function serializeEntity(User $user) 
{ 
    // JMS serialization 
    $user = $this->get('jms_serializer')->serialize($user, 'array'); 

    if ($user->getPosts()->count()) { 
     $post = $user->getPosts()->first(); 
     $user['first_post_date'] = $this->get('my_helper_service')->dateFormat($post->getDate()); 
    } 

    return $user; 
} 

注意:這個例子是合成的,在現實世界中我有更復雜的方法,而不僅僅是日期格式。但主要想法是一樣的。

我覺得應該有更好的方法來做到這一點。

回答

3

Dmtry的解決方案應該適合您的情況。

在這種情況下,事件監聽器/訂戶是最佳解決方案。

有點更普遍的解決方案,即使用對象均勻,將觸發JMS串行的整個事件系統部分(Dmtry的解決方案僅適用於原語只爲JSON/YAML,而不是XML)是:

class MyFormatter implements EventSubscriberInterface 
{ 

    public static function getSubscribedEvents() 
    { 
     return array(
      array(
       'event' => 'serializer.post_serialize', 
       'method' => 'onPostSerialize', 
       'class' => 'YourEntity' 
      ), 
     ); 
    } 

    public function __construct(MyFormatter $foermatter) 
    { 
     $this->formatter = $formatter; 
    } 

    public function onPostSerialize(ObjectEvent $event) 
    { 
     $visitor = $event->getVisitor(); 
     $context = $event->getContext(); 

     $timestamp = $event->getObject()->getTimestamp(); 
     $formattedTime = $this->formatter->format($timestamp); 

     $metadata = new StaticPropertyMetadata('stdClass', 'first_post_date', $formattedTime); 

     $visitor->visitProperty($metadata, $formattedTime, $context); 
    } 
} 

stdClass由串行忽略...

1

當然,還有更好的辦法。這就是所謂的序列化事件。

http://jmsyst.com/libs/serializer/master/event_system

創建活動的用戶

my_bundle.serializer_subscriber: 
    class: MyBundle\Serializer\MyEntitySerializerSubscriber 
    arguments: 
     - @bundle.time_formatter 
    tags: 
     - { name: jms_serializer.event_subscriber } 

然後只需添加在您的聽衆

public function myOnPostSerializeMethod(ObjectEvent $event) 
{ 
    if (!($event->getObject() instance of YourEntity)) { 
     return; 
    } 

    $timestamp = $event->getObject()->getTimestamp(); 

    $visitor = $event->getVisitor(); 
    $visitor->addData('date', $this->formatter->format($timestamp)); 
} 

附註:需要的數據我沒有檢查代碼,所以也許我誤解了方法的名稱,但想法很明確,我希望

+0

我認爲有關事件,但將在每一個序列化這一事件火?如果我有幾個實體,我想填充它,代碼中會包含很多'SomeEntity的if($ event-> getObject()實例){$ this-> someEntityFormat($ event); }' – Aliance