gpt4 book ai didi

symfony - 在要序列化的实体上添加动态属性

转载 作者:行者123 更新时间:2023-12-05 07:52:24 25 4
gpt4 key购买 nike

我有这个 REST API。每当请求通过 id (/resource/{id} ) 获取资源时,我想在该对象上动态添加一个 permissions 数组(实体本身没有该字段)。

我想到的是这个事件监听器。它检查 Controller 返回的结果:

class PermissionFinderListener {
...

public function onKernelView(GetResponseForControllerResultEvent $event) {
$object = $event->getControllerResult();

if (!is_object($object) || !$this->isSupportedClass($object)) {
return;
}

$permissions = $this->permissionFinder->getPermissions($object);
$object->permissions = $permissions;

$event->setControllerResult($object);
}
....
}

问题是 JMS 序列化程序在序列化时选择了这个动态属性。我尝试在 JMS 序列化程序上制作 onPostSerialize 事件订阅者,但是没有明确的方法来检查这是 GET ONE 还是 GET COLLECTION要求。我在 GET COLLECTION 上不需要这种行为,而且它还会对集合序列化造成巨大的性能影响。此外,我不想创建任何具有 permission 属性的基实体类。

也许有其他方法可以处理这种情况?

最佳答案

我能想到的是虚拟属性(property)和序列化组的结合:

向您的实体添加属性,例如:

 /**
* @Serializer\VirtualProperty
* @Serializer\SerializedName("permissions")
* @Serializer\Groups({"includePermissions"}) */
*
* @return string
*/
public function getPermissions()
{
return $permissionFinder->getPermissions($this);
}

您唯一需要做的就是仅在您的特殊情况下序列化“includePermissions”组(参见 http://jmsyst.com/libs/serializer/master/cookbook/exclusion_strategies)

如果您无法从您的实体访问 $permissionFinder,您也可以在序列化之前从 Controller /服务设置实体的权限属性。

编辑:

这是一些更多的代码,通过包装您的实体并将 VirtualProperty 与 SerializationGroups 一起使用来演示我的意思。这段代码根本没有经过测试——它基本上是我们正在使用的手动复制和剥离的版本。所以请仅作为一个想法使用它!

1) 为您的实体创建类似包装类的东西:

 <?php
namespace Acquaim\ArcticBundle\Api;

use JMS\Serializer\Annotation as JMS;

/**
* Class MyEntityApi
*
* @package My\Package\Api
*/
class MyEntityApi
{
/**
* The entity which is wrapped
*
* @var MyEntity
* @JMS\Include()
*/
protected $entity;

protected $permissions;
/**
* @param MyEntity $entity
* @param Permission[] $permissions
*/
public function __construct(
MyEntity $entity,
$permissions = null)
{
$this->entity = $entity;
$this->permissions = $permissions;
}

/**
* @Serializer\VirtualProperty
* @Serializer\SerializedName("permissions")
* @Serializer\Groups({"includePermissions"})
*
* @return string
*/
public function getPermissions()
{
if ($this->permissions !== null && count($this->permissions) > 0) {
return $this->permissions;
} else {
return null;
}
}

/**
* @return object
*/
public function getEntity()
{
return $this->entity;
}

}

2) 在您的 Controller 中,不要返回您的原始实体,而是获取您的权限并使用实体和权限创建您的包装类。设置您的序列化上下文以包含权限并让 ViewHandler 返回您的序列化对象。

如果您没有将序列化上下文设置为 includePermissions,它将被排除在序列化结果之外。

 YourController:

$myEntity = new Entity();

$permissions = $this->get('permission_service')->getPermissions();

$context = SerializationContext::create()->setGroups(array('includePermissions'));

$myEntityApi = new MyEntityApi($myEntity,$permissions);

$view = $this->view($myEntityApi, 200);

$view->setSerializationContext($context);

return $this->handleView($view);

关于symfony - 在要序列化的实体上添加动态属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33692651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com