У меня есть сущность Category
, которая содержит кучу Assets
. У категории есть метод getCount
, который возвращает количество активов в ней.
Я использую FosRestBundle и, следовательно, JMSSerializerBundle для сериализации ресурса категории в json. Теперь произошло изменение функции, которое представило различные виды активов, например. external
и internal
.
Я все еще хочу использовать сериализацию сущностей, и я подумал, что, создав PreSerializeEvent
, я действительно смогу это сделать.
Тем не менее, документы для компонента сериализатора неясны, так как соответствующая часть упоминается как do something
Как я вообще должен что-то здесь делать?
Чего я хочу добиться, так это изменить метод, который вызывается, если установлен флаг. Обычным случаем для сериализатора должно быть использование метода getCount
, с другой стороны, метода getExternalCountOnly
для объекта категории, если сериализуется 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;
}
}
internal
дляgetCount()
иexternal
дляgetExternalAssetCount()
, а затем добавите соответствующую группу сериализации на основе уровня доступа пользователя? - person Jason Roman   schedule 23.12.2014