<?php
namespace App\Security\Voter\Content;
use App\Entity\Content;
use App\Security\ApiUser;
use App\Service\Content\MemberContentService;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
class ContentVoter extends Voter
{
public const PERMISSION_EDIT = 'edit';
public const PERMISSION_DELETE = 'delete';
public const PERMISSION_COMMENT = 'comment';
public const PERMISSION_WATCH = 'watch';
protected MemberContentService $memberContentService;
public function __construct(MemberContentService $memberContentService)
{
$this->memberContentService = $memberContentService;
}
protected function supports(string $attribute, $subject): bool
{
if (!$subject instanceof Content) {
return false;
}
return in_array($attribute, [
self::PERMISSION_EDIT,
self::PERMISSION_DELETE,
self::PERMISSION_COMMENT,
self::PERMISSION_WATCH,
], true);
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
if (!$user instanceof ApiUser || !$subject instanceof Content) {
return false;
}
// Allow watch only when video was bought - even for admins!
if (self::PERMISSION_WATCH === $attribute) {
return $this->memberContentService->hasMemberPurchasedContent($subject, $user->getMember());
}
if ($user->getIsAdmin()) {
return true;
}
switch ($attribute) {
case self::PERMISSION_COMMENT:
return $this->memberContentService->hasMemberPurchasedContent($subject, $user->getMember());
default:
return $this->canEdit($subject, $user);
}
}
protected function canEdit(Content $subject, ApiUser $user): bool
{
return $user->getMember()->getId() == $subject->getMember()->getId();
}
}