2016-07-22 3 views
2

Насколько я понял, с помощью методов исключения, таких как группы и/или версии, можно сериализовать или не использовать поле сущности, но мне нужно установить другое «serialized_name», ,JMSSerializerBundle: обрабатывать другое имя для того же свойства объекта

У меня есть старый ApiBundle, который сериализует сущности в третьем пакете, и теперь мне нужно сериализовать эти же сущности из NewAPiBundle, но мне нужны новые имена для полей без изменения имен свойств Entity (старый api должен продолжать работать)

Возможно ли что-то подобное с помощью JSMSerializer? :

Entity\User: 
    properties: 
     name: 
      groups: ['user_odlapi'] 
     name: 
      groups: ['user_newapi'] 
      serialized_name: 'username' 

Или, может быть, можно закодировать два различных YML сериализации файлов в зависимости от URL запроса/Bundle?

ответ

2

Вы можете внедрить EventSubscriberInterface, как описано here in the doc.

Как пример:

use JMS\Serializer\EventDispatcher\EventSubscriberInterface; 
use JMS\Serializer\EventDispatcher\ObjectEvent; 
... 

class UserSerializerSubscriber implements EventSubscriberInterface 
{ 

public static function getSubscribedEvents() 
{ 
    return [ 
     [ 
      'event' => 'serializer.post_serialize', 
      'class' => 'Entity\User', 
      'method' => 'onPostSerialize', 
     ], 
    ]; 
} 

public function onPostSerialize(ObjectEvent $event) 
{ 
    $visitor = $event->getVisitor(); 
    $user = $event->getObject(); 

    $attributeName = 'name'; // default 

    if ($this->isInGroups(['user_newapi'], $event)) 
    { 
     $attributeName = 'username'; 
    } 

    $visitor->addData($attributeName, $user->getName()); 

} 

private function isInGroups(array $validGroup, ObjectEvent $event) 
{ 
    $option = $event->getContext() 
      ->attributes->get('groups') 
      ->filter(function ($groups) use ($validGroup) { 
       return sizeof(array_intersect($groups, $validGroup))>0; 
      }); 

    return !$option->isEmpty(); 

} 

И регистр, в YML Например:

acme.user_serializer_subscriber: 
    class: Acme\DemoBundle\Subscriber\UserSerializerSubscriber 
    tags: 
     - { name: "jms_serializer.event_subscriber" } 

Надежда эта помощь

+0

Thans для вашего ответа @Matteo. Кажется, что ваши решения устанавливают 'attributeName' на «username», если «user_newapi» присутствует в списке групп. Я прав? Но то, что я хочу сделать, - установить атрибутName на «имя пользователя», если пользователь запрашивает новый api url, и присваивает атрибуту имя «пользователю», если пользователь запрашивает старый api url (не всегда задает атрибут name для имени пользователя, если старое свойство теперь также поддерживается новым api). – aabilio

+0

Привет, @aabilio, конечно, я думаю, вы можете архивировать то, что вы ищете с помощью этого метода, или я неправильно понимаю, что кто-то думает? – Matteo

+1

ах ок! поэтому '$ event-> getContext() -> attributes-> get ('groups')' получать группы, которые установлены с помощью команды SerializationContext :: create() -> setGroups (array ('learnPills')) '... Понимаю. Я думал, что это предложение принимает группы, перечисленные в конфигурации сущности. Таким образом, кажется, что я могу использовать этот метод для выполнения того, что хочу, но я должен написать событие Подписаться на каждое свойство каждого объекта, я хочу обновить его имя. – aabilio

Смежные вопросы