我能想象的是虚拟属性和序列化组的组合:
向您的实体添加一个属性,例如:
/**
* @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/Service 设置实体的权限属性。
编辑:
通过包装您的实体并将 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)在您的控制器中,不要返回您的原始实体,而是获取您的权限并创建具有实体和权限的包装类。设置您的序列化上下文以包含权限并让 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);