Как изменить метод для вызова объекта в PreSerializeEvent?

у меня есть Category сущность, которая содержит кучу Assets, Категория имеет getCount метод, который возвращает количество активов в нем.

Я использую FosRestBundle и, следовательно, JMSSerializerBundle, чтобы сериализовать актив Category в json. Теперь произошла смена функций, которая привела к появлению различных видов активов, например, external а также internal из них.

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

Все же документы для компонента сериализатора неясны, ссылаясь на соответствующую часть как do something

Как я на самом деле должен что-то здесь делать?

Чего я хочу добиться — это изменить метод, который вызывается, если установлен флаг. Обычным случаем для сериализатора должно быть использование getCount метод, с другой стороны, getExternalCountOnly метод объекта Category, если getCount сериализуется.

Это действительно возможно сделать здесь, или я на неправильном пути?

См мой CategorySerializationSubscriber:

<?php
namespace Hn\AssetDbBundle\Listener;

use Hn\AssetDbBundle\Entity\Category;
use Hn\UserBundle\Entity\User;
use JMS\Serializer\Annotation\PostSerialize;
use JMS\Serializer\EventDispatcher\EventSubscriberInterface;
use JMS\Serializer\EventDispatcher\ObjectEvent;
use JMS\Serializer\EventDispatcher\PreSerializeEvent;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;

/**
* Class CategorySerializationSubscriber
* @package Hn\AssetDbBundle\Listener
*/

class CategorySerializationSubscriber implements EventSubscriberInterface
{
/**
* @var LoggerInterface
*/
private $logger;

/**
* @var User $user
*/

private $user;

/**
* @param LoggerInterface $logger
*/

public function __construct(LoggerInterface $logger, SecurityContextInterface $context)
{
$this->user = $context->getToken()->getUser();
$this->logger = $logger;
$logger->critical($this->user->getFullNameOrEmail());
}

/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
[
'event' => 'serializer.pre_serialize',
'method' => 'onPreSerialize'
],
];
}

/**
* @param PreSerializeEvent $event
*/

public function onPreSerialize(PreSerializeEvent $event)
{
$category = $this->getCategoryFromEvent($event);

if (!$category) {
$this->logger->info('is not a category, aborting');
return;
}

$userCanViewInternalAsset = $this->user->isAllowedToViewInternalAssets();

/**
* How to actually do something?
*
* Pseudocode follows:
*/

if ($userCanViewInternalAsset) {
$seriaization->replaceMethod($category, 'getCount', 'getExternalAssetCount');
} else {
/**
* $category->getCount(); remains intact
*/
}
}

/**
* @param PreSerializeEvent $event
* @return Category|null
*/

protected function getCategoryFromEvent(PreSerializeEvent $event) {

/**
* @var Category $category
*/

$category = $event->getObject();

if (!$category instanceof Category) {
return null;

}

return $category;

}
}

1

Решение

Как насчет исключения по умолчанию и последующего использования подписчика postSerialize (), чтобы добавить его с нужной вам функцией? Например:

Определить в services.yml (или под services в config.yml):

category_serialization_subscriber:
class: Hn\AssetDbBundle\Listener\CategorySerializationSubscriber
tags:
- { name: jms_serializer.event_subscriber }

Затем следующее, которое модифицируется из вашего класса выше:

public static function getSubscribedEvents()
{
return array(array(
'event'  => 'serializer.post_serialize',
'class'  => 'Hn\AssetDbBundle\Entity\Category',
'method' => 'onPostSerialize'
));
}

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

if ($this->user->isAllowedToViewInternalAssets()) {
$visitor->addData('count', $category->getExternalAssetCount());
} else {
$visitor->addData('count', $category->getCount());
}
}
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]