<?php
namespace App\EventSubscriber\User;
use App\Entity\Logs\EventLog;
use App\Entity\Notifications\Notification;
use App\Entity\Profile\Profile;
use App\Entity\Profile\ProfileAccessLog;
use App\Entity\Profile\ProfileRBAC;
use App\Entity\User\User;
use App\Enums\Constants;
use App\Event\Composition\SongWriter\SongwriterConnectedToProfileEvent;
use App\Event\LogEvent;
use App\Event\User\UserClosedEvent;
use App\Event\User\UserCreatedEvent;
use App\Event\User\UserDeletedEvent;
use App\Event\User\UserSuspendedEvent;
use App\Event\User\UserTerminatedEvent;
use App\Event\User\UserUpdatedEvent;
use App\Repository\Notifications\NotificationRepository;
use App\Repository\Profile\ProfileAccessLogRepository;
use App\Repository\Profile\ProfileRBACRepository;
use App\Repository\User\UserProfileRepository;
use App\Repository\User\UserRepository;
use App\Service\AuthenticationService;
use App\Service\Mailer\UserMailer;
use App\Service\ProfileService;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class UserSubscriber implements EventSubscriberInterface
{
/**
* @var AuthenticationService
*/
private $authenticationService;
/**
* @var EventDispatcherInterface
*/
private $eventDispatcher;
/** @var UserRepository */
private $userRepository;
/** @var UserMailer */
private $userMailer;
/** @var UserProfileRepository */
private $userProfileRepository;
/** @var ProfileAccessLogRepository */
private $profileAccessLogRepository;
/** @var ProfileRBACRepository */
private $profileRBACRepository;
/** @var NotificationRepository */
private $notificationRepository;
/** @var ProfileService */
private $profileService;
/**
* @param AuthenticationService $authenticationService
* @param EventDispatcherInterface $eventDispatcher
* @param UserRepository $userRepository
* @param UserMailer $userMailer
* @param UserProfileRepository $userProfileRepository
* @param ProfileAccessLogRepository $profileAccessLogRepository
* @param ProfileRBACRepository $profileRBACRepository
* @param NotificationRepository $notificationRepository
* @Param ProfileService $profileService
*/
public function __construct(
AuthenticationService $authenticationService,
EventDispatcherInterface $eventDispatcher,
UserRepository $userRepository,
UserMailer $userMailer,
UserProfileRepository $userProfileRepository,
ProfileAccessLogRepository $profileAccessLogRepository,
ProfileRBACRepository $profileRBACRepository,
NotificationRepository $notificationRepository,
ProfileService $profileService
)
{
$this->authenticationService = $authenticationService;
$this->eventDispatcher = $eventDispatcher;
$this->userRepository = $userRepository;
$this->userMailer = $userMailer;
$this->userProfileRepository = $userProfileRepository;
$this->profileAccessLogRepository = $profileAccessLogRepository;
$this->profileRBACRepository = $profileRBACRepository;
$this->notificationRepository = $notificationRepository;
$this->profileService = $profileService;
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents(): array
{
return [
UserCreatedEvent::class => 'onUserCreatedEvent',
UserUpdatedEvent::class => 'onUserUpdatedEvent',
UserClosedEvent::class => 'onUserClosedEvent',
UserSuspendedEvent::class => 'onUserSuspendedEvent',
UserTerminatedEvent::class => 'onUserTerminatedEvent',
UserDeletedEvent::class => 'onUserDeletedEvent'
];
}
/**
* @param UserCreatedEvent $event
* @return void
*/
public function onUserCreatedEvent(UserCreatedEvent $event)
{
/** @var User $user */
$user = $event->getUser();
$userForLog = ($event->getFrom() === Constants::MMPZ_REFERER) ? $this->authenticationService->getUser() : $user;
$this->eventDispatcher->dispatch(
new LogEvent(
$event->getUser(),
$userForLog,
EventLog::TYPE_USER_CREATED
)
);
}
/**
* @param UserUpdatedEvent $event
* @return void
*/
public function onUserUpdatedEvent(UserUpdatedEvent $event)
{
/** @var User $user */
$user = $event->getUser();
$userForLog = ($event->getFrom() === Constants::MMPZ_REFERER) ? $this->authenticationService->getUser() : $user;
$this->eventDispatcher->dispatch(
new LogEvent(
$event->getUser(),
$userForLog,
EventLog::TYPE_USER_UPDATED
)
);
}
/**
* @param UserUpdatedEvent $event
* @return void
*/
public function onUserRevokeEvent(UserUpdatedEvent $event)
{
/** @var User $user */
$user = $event->getUser();
$userForLog = ($event->getFrom() === Constants::MMPZ_REFERER) ? $this->authenticationService->getUser() : $user;
$this->eventDispatcher->dispatch(
new LogEvent(
$event->getUser(),
$userForLog,
EventLog::TYPE_USER_REVOKED
)
);
}
/**
* @param UserClosedEvent $event
*/
public function onUserClosedEvent(UserClosedEvent $event): void
{
/** @var User $user */
$user = $event->getUser();
$user->setStatus(Constants::USER_CLOSE);
$this->userRepository->flush();
$this->eventDispatcher->dispatch(
new LogEvent(
$event->getUser(),
$this->authenticationService->getUser(),
EventLog::TYPE_USER_CLOSED
)
);
$this->userMailer->sendUserEmails(
$user,
$this->authenticationService->getUser(),
$this->buildMessage($user, $this->authenticationService->getUser(), Constants::USER_CLOSE)
);
}
/**
* @param UserSuspendedEvent $event
*/
public function onUserSuspendedEvent(UserSuspendedEvent $event): void
{
/** @var User $user */
$user = $event->getUser();
$user->setStatus(Constants::USER_SUSPEND);
$this->userRepository->flush();
$this->eventDispatcher->dispatch(
new LogEvent(
$event->getUser(),
$this->authenticationService->getUser(),
EventLog::TYPE_USER_SUSPENDED
)
);
$this->userMailer->sendUserEmails(
$user,
$this->authenticationService->getUser(),
$this->buildMessage($user, $this->authenticationService->getUser(), Constants::USER_SUSPEND)
);
}
/**
* @param UserTerminatedEvent $event
*/
public function onUserTerminatedEvent(UserTerminatedEvent $event): void
{
/** @var User $user */
$user = $event->getUser();
$user->setStatus(Constants::USER_TERMINATE);
$this->userRepository->flush();
$this->eventDispatcher->dispatch(
new LogEvent(
$event->getUser(),
$this->authenticationService->getUser(),
EventLog::TYPE_USER_TERMINATED
)
);
$this->userMailer->sendUserEmails(
$user,
$this->authenticationService->getUser(),
$this->buildMessage($user, $this->authenticationService->getUser(), Constants::USER_TERMINATE)
);
}
/**
* @param UserDeletedEvent $event
*/
public function onUserDeletedEvent(UserDeletedEvent $event): void
{
/** @var User $user */
$user = $event->getUser();
$userForLog = ($event->getFrom() === Constants::MMPZ_REFERER) ? $this->authenticationService->getUser() : $user;
$this->eventDispatcher->dispatch(
new LogEvent(
$event->getUser(),
$userForLog,
EventLog::TYPE_USER_TERMINATED
)
);
$this->userMailer->sendUserEmails(
$user,
$userForLog,
$this->buildMessage($user, $userForLog, Constants::USER_DELETE)
);
$pofileRbacs = $this->profileRBACRepository->findBy(['user' => $user]);
/** @var ProfileRBAC $pofileRbac */
foreach ($pofileRbacs as $pofileRbac) {
$this->profileRBACRepository->remove($pofileRbac);
$this->profileRBACRepository->flush();
}
$profileAccessLogs = $this->profileAccessLogRepository->findBy(['user' => $user]);
/** @var ProfileAccessLog $profileAccessLog */
foreach ($profileAccessLogs as $profileAccessLog){
$this->profileAccessLogRepository->remove($profileAccessLog);
$this->profileAccessLogRepository->flush();
}
$notifications = $this->notificationRepository->findBy(['user' => $user]);
/** @var Notification $notification */
foreach ($notifications as $notification){
$this->notificationRepository->remove($notification);
$this->notificationRepository->flush();
}
}
/**
* @param User $user
* @param User $responsible
* @param string $event
* @return string[]
*/
private function buildMessage(User $user, User $responsible, string $event)
{
if($event !== Constants::USER_DELETE){
$message = [
'title' => 'User " ' . $user->getUserProfile()->getFirstName() ." ".$user->getUserProfile()->getLastName() . '" '. $event,
'message' => "Dear ".$user->getUsername().", this user account now is {$event} status"
];
}else{
$message = [
'title' => 'User " ' . $user->getUserProfile()->getFirstName() ." ".$user->getUserProfile()->getLastName() . '" '. $event,
'message' => "Dear ".$user->getUsername().", this user account now is deleted"
];
}
$profile = $this->profileService->findDefaultProfileForUser($user);
if(is_null($profile)){
$profile = $this->profileService->getProfileByUrlName(Constants::PROFILE_SERVICE_URL_NAME);
}
$message['profile'] = $profile;
return $message;
}
}