<?php
namespace App\Subscriber\UserGroups;
use App\Dictionary\UserGroupJoinMode;
use App\Event\UserGroups\GroupJoinedEvent;
use App\Event\UserGroups\GroupScoreUpdateEvent;
use App\Event\UserGroups\JoinGroupEvent;
use App\Event\UserGroups\LeaveGroupEvent;
use App\Service\UserGroups\GroupMemberService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class UserGroupMembershipSubscriber implements EventSubscriberInterface
{
/**
* @var GroupMemberService
*/
protected $service;
/**
* @var EventDispatcherInterface
*/
protected $dispatcher;
/**
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* UserGroupMembershipSubscriber constructor.
*/
public function __construct(GroupMemberService $service, EventDispatcherInterface $dispatcher, EntityManagerInterface $entityManager)
{
$this->dispatcher = $dispatcher;
$this->service = $service;
$this->entityManager = $entityManager;
}
protected function getDispatcher(): EventDispatcherInterface
{
return $this->dispatcher;
}
public static function getSubscribedEvents(): array
{
return [
JoinGroupEvent::class => [
['onGroupJoin', 0],
],
GroupJoinedEvent::class => [
['onGroupJoinedUpdateMemberCount', 90],
],
LeaveGroupEvent::class => [
['onGroupLeaveBanAlso', 0],
['onGroupLeaveUpdateMemberCount', 0],
['onGroupLeaveUpdateScore', 0],
],
];
}
/**
* @throws \App\Exception\UserGroup\BannedFromGroupException
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onGroupJoin(JoinGroupEvent $event): bool
{
$group = $event->getGroup();
$member = $event->getMember();
if (!$event->isModerator()) {
// Moderator-Joins skippen den InviteCheck
$invite = $this->service->loadInvite($member, $group);
if (!$invite && UserGroupJoinMode::INVITE == $group->getJoinMode()) {
return false;
} elseif ($invite) {
$this->service->deleteEntity($invite->getId());
}
}
$result = $this->service->joinGroup($member, $group, $event->isModerator());
if ($result) {
$event = new GroupScoreUpdateEvent($group, $event->getScore());
$this->getDispatcher()->dispatch($event);
}
return true;
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onGroupLeaveBanAlso(LeaveGroupEvent $event)
{
if (!$event->banAlso()) {
return;
}
$group = $event->getGroup();
$member = $event->getGroupMember()->getMember();
$operator = $event->getOperator();
$this->service->banMemberFromUserGroup($group, $member, $operator);
}
public function onGroupLeaveUpdateScore(LeaveGroupEvent $event)
{
$group = $event->getGroup();
$event = new GroupScoreUpdateEvent($group, $event->getScore());
$this->getDispatcher()->dispatch($event);
}
public function onGroupLeaveUpdateMemberCount(LeaveGroupEvent $event)
{
$group = $event->getGroup();
$stat = $group->getUserGroupStat();
$stat->setMemberCount($stat->getMemberCount() - 1);
$this->entityManager->persist($stat);
$this->entityManager->flush();
}
public function onGroupJoinedUpdateMemberCount(GroupJoinedEvent $event)
{
$group = $event->getGroup();
$stat = $group->getUserGroupStat();
$stat->setMemberCount($stat->getMemberCount() + 1);
$this->entityManager->persist($stat);
$this->entityManager->flush();
}
}