0

I am facing a problem for quite some times and I did not manage to solve it. I use the JMSSerializerBundle to serialize my entities in my web services. So I have to serialize an object A that has a relationship with an object B. In this object B I have to add two new fields whose data are obtained through a call to a repository => so no virtual property because it would mean injecting services in the entity which is bad. Also I don't have to add these fields in all the serialization of object B but only when it is included in object A.

So I thought about listeners, I made a listener who listen the event post serialization for the serialization of my object A, and I wanted to add the fields to the object B included in object A. I thought it would be fairly common but I do not understand how the Visitor (which is given via the ObjectEvent in postSerialize() function) works.

We can quite easily make a

// (here the object A is recovered) 
$event->getObject()->getVisitor()->AddData('someKey', 'someValue');

Just like the following example: Add extra fields using JMS Serializer bundle

But my problem is that I would like to add fields in object B contained in the object A, I have not found any examples or even information in the documentation about this :( anyone can help ?

Thank you in advance.

Community
  • 1
  • 1
Nayro
  • 1
  • 2

1 Answers1

0

There is no way to use serializer inside serialization event subscriber.

Instead, object B can be contained into object A before serialization (just don't map it if you use ORM):

    namespace App\Entity;

use JMS\Serializer\Annotation as JMS;

class ObjectA
{
    /**
     * @JMS\Expose
     */
    private $objectB;

    public function getObjectB(): ObjectB
    {
        return $this->objectB;
    }

    public function setObjectB(ObjectB $objectB): self
    {
        $this->objectB = $objectB;

        return $this;
    }
}

Now use pre-serialization:

namespace App\Subscriber;

use App\Entity\ObjectA;
use JMS\Serializer\EventDispatcher\Events;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\ObjectEvent;

class ObjectASubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return [
            [
                'event' => Events::PRE_SERIALIZE,
                'method' => 'onPreSerialize',
                'class' => ObjectA::class,
            ],
        ];
    }

    public function onPreSerialize(ObjectEvent $event)
    {
        $objectA = $event->getObject();
        $objectB = /** Retrieving here */

        $objectA->setObjectB($objectB);
    }
}