我有一个 Doctrine 实体,我使用 JMS 序列化程序在我的 API 中呈现它。
我想添加一个这样的 bool 字段:
/**
* @var bool
*
* @ORM\Column(name = "is_serialized", type = "boolean")
*/
protected $isSerialized = true;
我还使用 EventSubscriber 在序列化之前向我的实体添加一些数据。
我想根据
$isSerialized
动态包含或不包含每个实体值(我无法修改 Doctrine 查询)。class SerializationEventSubscriber extends EventSubscriberInterface
{
/**
* @param ObjectEvent $event
*/
public function onPostSerialize(ObjectEvent $event)
{
if (!$this->isGroup('api', $event)) {
return;
}
$entity = $event->getObject();
$visitor = $event->getVisitor();
if (!$object->isSerialized()) {
// Skip the current object and remove it from serialization
}
}
}
我在 JMS 注释文档中都找不到关于此的任何信息。
最佳答案
这是我的 EventListener
,但我没有删除对象,而是跳过了空字段。
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\EntityManagerInterface;
use JMS\Serializer\JsonSerializationVisitor;
use JMS\Serializer\EventDispatcher\ObjectEvent;
use JMS\Serializer\Metadata\ClassMetadata as JMSClassMetadata;
use JMS\Serializer\Metadata\StaticPropertyMetadata;
class EntitySerializerListener
{
/**
* @var EntityManagerInterface
*/
protected $em;
public function __construct(EntityManagerInterface $entityManager)
{
$this->em = $entityManager;
}
public function onPostSerialize(ObjectEvent $event)
{
/** @var JsonSerializationVisitor $visitor */
$object = $event->getObject();
$visitor = $event->getVisitor();
$context = $event->getContext();
$type = $event->getType();
/** @var JMSClassMetadata $metadata */
$metadata = $context->getMetadataFactory()->getMetadataForClass($type['name']);
$data = $visitor->endVisitingObject($metadata, $object, $type);
$visitor->startVisitingObject($metadata, $object, $type);
// Here I remove unnecessary fields
$this->prune($type['name'], $data);
// Reset fresh serialized data
foreach ($data as $field => $value) {
$visitor->visitProperty(new StaticPropertyMetadata($type['name'], $field, $value), $value);
}
}
/**
* Prune the empty field which was set to NULL by MaxDepth annotation but left in the data graph by JWT serializer.
*
* @param string $fqcn
* @param array $data
*/
protected function prune(string $fqcn, array & $data)
{
/** @var ClassMetadata $metadata */
$metadata = $this->em->getMetadataFactory()->getMetadataFor($fqcn);
// Handle association
$associations = $metadata->getAssociationMappings();
foreach ($associations as $field => $association) {
if (!array_key_exists($field, $data)) {
continue;
}
// Here remove entity or any other field which you want
if (empty($data[$field])) {
unset($data[$field]);
} else {
$this->prune($association['targetEntity'], $data[$field]);
}
}
}
}
关于symfony - 动态删除 JMS 序列化程序事件订阅者内的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42621810/