Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add extra fields using JMS Serializer bundle

I've an entity I usually serialize using the JMS Serializer bundle. I have to add to the serialization some fields that doesn't reside in the entity itself but are gathered with some db queries.

My idea was to create a custom object, fill the fields with the entity fields and add the custom one. But this seems a bit tricky and expensive to do for every variation (I use lot of serialization groups) of the class.

Is there a better/standard way to do this? Using a factory? Pre/Post serialization events?

Maybe I can listen for the serialization and checking entity type and serialization groups add the custom fields? But instead of making a query for each entity it would be better to gather all the data of the related entities and then add it to them. Any help is appreciated

like image 262
alex88 Avatar asked Feb 21 '13 16:02

alex88


1 Answers

I've found the solution by myself,

to add a custom field after the serialization has been done we've to create a listener class like this:

<?php  namespace Acme\DemoBundle\Listener;  use JMS\DiExtraBundle\Annotation\Service; use JMS\DiExtraBundle\Annotation\Tag; use JMS\DiExtraBundle\Annotation\Inject; use JMS\DiExtraBundle\Annotation\InjectParams; use Symfony\Component\HttpKernel\Event\PostResponseEvent; use Acme\DemoBundle\Entity\Team; use JMS\Serializer\Handler\SubscribingHandlerInterface; use JMS\Serializer\EventDispatcher\EventSubscriberInterface; use JMS\Serializer\EventDispatcher\PreSerializeEvent; use JMS\Serializer\EventDispatcher\ObjectEvent; use JMS\Serializer\GraphNavigator; use JMS\Serializer\JsonSerializationVisitor;  /**  * Add data after serialization  *  * @Service("acme.listener.serializationlistener")  * @Tag("jms_serializer.event_subscriber")  */ class SerializationListener implements EventSubscriberInterface {      /**      * @inheritdoc      */     static public function getSubscribedEvents()     {         return array(             array('event' => 'serializer.post_serialize', 'class' => 'Acme\DemoBundle\Entity\Team', 'method' => 'onPostSerialize'),         );     }      public function onPostSerialize(ObjectEvent $event)     {         $event->getVisitor()->addData('someKey','someValue');     } } 

That way you can add data to the serialized element.

Instead, if you want to edit an object just before serialization use the pre_serialize event, be aware that you need to already have a variable (and the correct serialization groups) if you want to use pre_serialize for adding a value.

like image 195
alex88 Avatar answered Nov 10 '22 00:11

alex88