<?php
namespace App\Security\Voter;
use App\Entity\Forum;
use App\Entity\ForumAccess;
use App\Entity\ForumMessage;
use App\Entity\User;
use App\EntityManager\ForumAccessManager;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
class ForumVoter extends Voter
{
const VIEW = 'view';
const CREATE_TOPIC = 'create_topic';
const MODERATE = 'moderate';
protected $security;
protected $forumAccessManager;
protected $userForumAccess = null;
protected $forumAccess = null;
public function __construct(Security $security, ForumAccessManager $forumAccessManager)
{
$this->security = $security;
$this->forumAccessManager = $forumAccessManager;
}
protected function supports($attribute, $subject)
{
if (!in_array($attribute, [self::VIEW, self::CREATE_TOPIC, self::MODERATE])) {
return false;
}
if (!$subject instanceof Forum && !$subject instanceof ForumMessage) {
return false;
}
return true;
}
protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
{
$user = $token->getUser();
if (!$user instanceof User) {
$user = null;
}
/** @var Forum $forum */
$forum = $subject instanceof ForumMessage ? $subject->getForum() : $subject;
if (is_null($this->forumAccess)) {
$this->userForumAccess = $this->forumAccessManager->getForumAccessForCurrentUser($forum);
$this->forumAccess = $this->forumAccessManager->getForumAccess($forum);
}
switch ($attribute) {
case self::VIEW:
return $this->canView($forum, $user, $token);
case self::CREATE_TOPIC:
return $this->canCreateTopic($forum, $user, $token);
case self::MODERATE:
return $this->canModerate($forum, $user, $token);
}
throw new \LogicException('This code should not be reached!');
}
private function canView(Forum $forum, User $user = null, TokenInterface $token = null)
{
return (
($this->forumAccess instanceof ForumAccess && $this->forumAccess->getListMessage()) ||
($this->userForumAccess instanceof ForumAccess && $this->userForumAccess->getListMessage())
);
}
private function canCreateTopic(Forum $forum, User $user = null, TokenInterface $token = null)
{
return (
$user instanceof User &&
($this->forumAccess instanceof ForumAccess && $this->forumAccess->getAddMessage()) ||
($this->userForumAccess instanceof ForumAccess && $this->userForumAccess->getAddMessage())
);
}
private function canModerate(Forum $forum, User $user = null, TokenInterface $token = null)
{
return $user instanceof User &&
$this->userForumAccess instanceof ForumAccess &&
$this->userForumAccess->getModMessage();
}
}