I have question about Symfony Voters. I have entity UserPermissionList which looks like that:
class UserPermissionList {
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
*/
private $name;
/**
* @ORM\Column(type="string", length=50)
*/
private $path;
/**
* @ORM\Column(type="smallint")
*/
private $view;
public function getId(): ?int {
return $this->id;
}
public function getName(): ?string {
return $this->name;
}
public function setName(string $name): self {
$this->name = $name;
return $this;
}
/**
* @return mixed
*/
public function getPath() {
return $this->path;
}
/**
* @param mixed $path
*/
public function setPath($path): void {
$this->path = $path;
}
/**
* @return mixed
*/
public function getView() {
return $this->view;
}
/**
* @param mixed $view
*/
public function setView($view): void {
$this->view = $view;
}
}
Path property is actual path to a specific route e.g: /desktop or /mobile
My User entity looks like that:
class User implements UserInterface
{
public const ROLE_USER = 'ROLE_USER';
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\ManyToMany(targetEntity="App\Entity\UserPermissionList")
* @ORM\JoinTable(name="user_permisions")
*/
private $permissions;
public function __construct()
{
$this->permissions = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
/**
* @return Collection|UserPermissionList[]
*/
public function getPermissions(): Collection
{
return $this->permissions;
}
public function addPermission(UserPermissionList $permission): self
{
if (!$this->permissions->contains($permission)) {
$this->permissions[] = $permission;
}
return $this;
}
public function removePermission(UserPermissionList $permission): self
{
if ($this->permissions->contains($permission)) {
$this->permissions->removeElement($permission);
}
return $this;
}}
And now, when User is related to specific permission in UserPermissionList I need to make logic allowing him access to route specified in this Entity.
Eg. I have permission with name: Desktop, path: /dekstop and view: 2 (means that permission can be displayed only on desktop devices).
Only User who has relation to this permission in UserPermissionList can visit page /desktop.
How my Voter should looks like?
EDIT. Ok, i made Voter like this:
class ViewVoter extends Voter
{
/**
* @var UserPermissionListRepository
*/
private $permissionListRepository;
public function __construct(UserPermissionListRepository $permissionListRepository)
{
$this->permissionListRepository = $permissionListRepository;
}
protected function supports($attribute, $subject)
{
$permissions = $this->permissionListRepository->findAll();
$permissionList = [];
foreach ($permissions as $permission) {
$permissionList[] = $permission->getPath();
}
return in_array($attribute, $permissionList)
&& $subject instanceof User;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$permissions = $subject->getPermissions();
$permissionList = [];
foreach ($permissions as $permission) {
$permissionList[] = $permission->getPath();
}
return in_array($attribute, $permissionList);
}
}
And than in my Controllers, e.g. in DesktopController i add annotation:
@Security("is_granted('/desktop', user)")