4
votes

I use JMS Serializer Bundle and Symfony2. I am using VirtualProperties. currently, I set the name of a property using the SerializedName annotation.

 /**
 * @JMS\VirtualProperty()
 * @JMS\SerializedName("SOME_NAME")
 */
public function getSomething()
{
    return $this->something
}

Is it possible to set the serialized name dynamically inside the function? Or is it possible to dynamically influence the name using Post/Pre serialization events?

Thanks!

3
Why do you need that? - meze
I have an Entity layer which consists of doctrine objects and an API Layer. Each API Object has a property "entity" which holds a corresponding entity. It has VirtualProperties which are kind of accessors to the entity. Inside of the VirtualProperties I can control how the information from the entity layer is displayed to the user. E.g. an entity of a many to many relationship has properties "source" and "target" - when I access this entity, only source or target is relevant, but I decide this on runtime, and I want to hand it to outside with a relevant property name. - ulilicht
Did you find a solution for this? I something like this myself. - bblue

3 Answers

0
votes

I don't think you can do this directly, but you could accomplish something similar by having several virtual properties, one for each possible name. If the name is not relevant to a particular entity, have the method return null, and disable null serialization in the JMS config.

0
votes

In the moment when you go to serialize the object, do the following:

$this->serializer = SerializerBuilder::create()->setPropertyNamingStrategy(new IdenticalPropertyNamingStrategy())->build();

$json = $this->serializer->serialize($object, 'json');
dump($json);
0
votes

Entity

/**
 * @JMS\VirtualProperty("something", exp="context", options={
 *     @JMS\Expose,
 * })
 */
class SomeEntity
{
}

Event Listener

abstract class AbstractEntitySubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            [
                'event'    => Events::POST_SERIALIZE,
                'method'   => 'onPostSerialize',
                'class'    => static::getClassName(),
                'format'   => JsonEncoder::FORMAT,
                'priority' => 0,
            ],
        ];
    }

    public function onPostSerialize(ObjectEvent $event): void
    {
        foreach ($this->getMethodNames() as $methodName) {
            $visitor  = $event->getVisitor();
            $metadata = new VirtualPropertyMetadata(static::getClassName(), $methodName);

            if ($visitor->hasData($metadata->name)) {
                $value = $this->{$methodName}($event->getObject());
                $visitor->visitProperty(
                    new StaticPropertyMetadata(static::getClassName(), $metadata->name, $value),
                    $value
                );
            }
        }
    }

    abstract protected static function getClassName(): string;

    abstract protected function getMethodNames(): array;
}

...

class SomeEntitySubscriber extends AbstractEntitySubscriber
{
    protected static function getClassName(): string
    {
        return SomeEntity::class;
    }

    protected function getMethodNames(): array
    {
        return ['getSomething'];
    }

    protected function getSomething(SomeEntity $someEntity)
    {
        return 'some text';
    }
}