JMS Serializer: Сериализация пользовательских свойств сущностей

Я хочу добавить пользовательское свойство в представление сериализованного объекта, которое берет существующее свойство объекта и форматирует его удобным для пользователя способом с помощью существующей службы.

Я определил класс подписчика и внедрил службу, используемую для форматирования существующего свойства сущности, и подписался на serializer.pre_serialize следующим образом:

class UserSerializationSubscriber implements EventSubscriberInterface
{
    private $coreTwigExtension;

    private $user;

    public function setCoreTwigExtension(TwigExtension $coreTwigExtension)
    {
        $this->coreTwigExtension = $coreTwigExtension;
    }

    public function setUserService(UserService $user)
    {
        $this->user = $user;
    }

    public static function getSubscribedEvents()
    {
        return array(
            array(
                'event' => 'serializer.pre_serialize', 
                'method' => 'onObjPreSerialize', 
                'class' => 'Some\Bundle\Entity\EntityClass',
                'format' => 'json'
            )
        );
    }

    public function onObjPreSerialize(PreSerializeEvent $event)
    {
        $context = $event->getContext();
        $context->attributes->get('groups')->map(
            function(array $groups) use ($event) {
                if (in_array('somegroup', $groups)) {
                    $obj= $event->getObject();

                    if ($obj->getConfirmedOn()) {
                         $contextualDate = $this->coreTwigExtension->getContextualDate($obj->getConfirmedOn());
                         $event->getVisitor()->addData('displayConfirmedOn', $contextualDate);
                    }
                }
            }
        );
    }

}

Регистрация подписчиков:

some_bundle.handler.serialization:
    class: Some\Bundle\Handler\ObjectSerializationSubscriber
    calls:
        - [setCoreTwigExtension, ['@bundle_core.twig.extension']]
        - [setUserService, ['@some_bundle.service.user']]
    tags:
        - { name: jms_serializer.event_subscriber }

Когда я сериализую массив/коллекцию сущностей Some\Bundle\Entity\EntityClass, я получаю следующую ошибку:

There is already data for "displayConfirmedOn".

Как решить эту проблему? Единственное, что останавливает меня от использования @VirtualProperty в сущности, это то, что вывод виртуального свойства зависит от службы, и никакие зависимости не должны вводиться в сущность.


person Genti Saliu    schedule 15.04.2014    source источник
comment
После добавления данных посетителю на этапе pre_serialize добавленное поле не отображается в выходных данных JSON. Из отладки я вижу, что данные перемещаются в свойство dataStack, а данные очищаются перед помещением свойств объекта в свойство данных. Я не могу найти никакой документации по этому поводу. Есть идеи?   -  person andho    schedule 29.04.2016


Ответы (1)


Ошибка связана с тем, что сама сущность уже предоставляет атрибут displayConfirmedOn для сериализации. Когда ваш прослушиватель событий работает, ему не разрешено добавлять атрибут с тем же именем к выходным данным, и вы получаете эту ошибку.

Просто перестаньте показывать атрибут в вашей сущности, и тогда слушатель сможет добавить свойство с тем же именем.

person advancingu    schedule 19.05.2015