我在实体定义中使用JMSSerializerBundle,在控制器中使用RestBundle的注释。
我有一个具有公共和管理保护属性的实体,比如
use JMSSerializerAnnotation as Serializer;
class UserAddress {
/**
* @SerializerExpose
* @SerializerGroups(groups={"address:read"})
*/
private $nonSecretAttribute;
/**
* @SerializerExpose
* @SerializerGroups(groups={"address:admin-read"})
*/
private $secretAttribute;
}
和一个用户喜欢:
class User {
// ...
/**
* @ORMOneToMany(targetEntity="UserAddress", mappedBy="user")
*/
private $addresses;
我的控制器看起来像
use FOSRestBundleControllerAnnotations as Rest;
class UsersController {
/**
* @RestGet("/users/{user}/addresses", requirements={"user"="d+"})
* @RestView(serializerGroups={"address:read"})
* @IsGranted("user_read", subject="user")
*/
public function getUsersAddresses(User $user)
{
return $user->getAddresses();
}
}
但是,如果登录的用户恰好具有ADMIN_ROLE
角色,我如何将address:admin-read
添加到此处的序列化程序组中?这在@RestView
注释中可能吗?我有办法修改控制器方法中的组吗?在一个条件循环中验证我登录的用户的角色?
您应该手动实例化fos-restView
并添加一个Context
。在Context
上,您可以在运行时通过评估用户角色来设置序列化组。
像这样的东西应该起作用:
use FOSRestBundleViewView;
use FOSRestBundleContextContext;
class UsersController
{
public function getUsersAddresses(User $user): View
{
$isAdmin = in_array('ROLE_ADMIN', $user->getRoles());
$context = new Context();
$context->setGroups($isAdmin ? ['address:admin-read'] : ['address:read']);
$view = VVV::create()->setContext($context);
return $view
->setContext($context)
->setData($user->getAddresses());
}
}