I'm using JMSSerializerBundle in my entities definition, and RestBundle's annotations in controllers.
I have an entity with public and admin-protected attributes, let's say
use JMS\Serializer\Annotation as Serializer;
class UserAddress {
/**
* @Serializer\Expose
* @Serializer\Groups(groups={"address:read"})
*/
private $nonSecretAttribute;
/**
* @Serializer\Expose
* @Serializer\Groups(groups={"address:admin-read"})
*/
private $secretAttribute;
}
and a User like :
class User {
// ...
/**
* @ORM\OneToMany(targetEntity="UserAddress", mappedBy="user")
*/
private $addresses;
and my controller looks like
use FOS\RestBundle\Controller\Annotations as Rest;
class UsersController {
/**
* @Rest\Get("/users/{user}/addresses", requirements={"user"="\d+"})
* @Rest\View(serializerGroups={"address:read"})
* @IsGranted("user_read", subject="user")
*/
public function getUsersAddresses(User $user)
{
return $user->getAddresses();
}
}
but how could I add the address:admin-read
to the serializer groups here if the logged in user happens to have the ADMIN_ROLE
role ?
Is that possible in the @Rest\View
annotation ?
Do I have a way to modify the groups in the controller's method, inside a conditional loop verifying my logged in user's roles ?
You should instantiate the fos-rest View
manually and add a Context
. On that Context
you can set the serialization groups at runtime by evaluating the users roles.
Something like this should work:
use FOS\RestBundle\View\View;
use FOS\RestBundle\Context\Context;
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());
}
}