<?php
namespace App\EventSubscriber\Profile;
use App\Entity\Logs\EventLog;
use App\Entity\Logs\ProfileHierarchyHistoryLog;
use App\Entity\Package\PackageSongWriter;
use App\Entity\Package\PackageTransaction;
use App\Entity\Profile\Invitation;
use App\Entity\Profile\PlatformIpiNumber;
use App\Entity\Profile\Profile;
use App\Entity\Profile\ProfileAccessLog;
use App\Entity\Profile\ProfileRBAC;
use App\Entity\Profile\ProfileSocialMedia;
use App\Entity\Profile\Splits\DeliverySplits;
use App\Entity\User\User;
use App\Entity\User\UserProfile;
use App\Enums\Constants;
use App\Event\LogEvent;
use App\Event\Profile\ProfileCreatedEvent;
use App\Event\Profile\ProfileCreatedForUserEvent;
use App\Event\Profile\ProfileDeletedEvent;
use App\Event\Profile\ProfileEraisedEvent;
use App\Event\Profile\ProfileRoyaltyTemplateEditEvent;
use App\Event\Profile\UserInvitedToProfileEvent;
use App\Repository\Logs\ProfileHierarchyHistoryLogRepository;
use App\Repository\Package\InvoiceRepository;
use App\Repository\Package\PackageSongwriterRepository;
use App\Repository\Package\PackageTransactionRepository;
use App\Repository\Profile\InvitationRepository;
use App\Repository\Profile\PlatformIpiNumberRepository;
use App\Repository\Profile\ProfileAccessLogRepository;
use App\Repository\Profile\ProfileInformationRepository;
use App\Repository\Profile\ProfileRBACRepository;
use App\Repository\Profile\ProfileRepository;
use App\Repository\Profile\ProfileSocialMediaRepository;
use App\Repository\Profile\Splits\DeliverySplitsRepository;
use App\Repository\Publishing\PlatformRepository;
use App\Repository\User\RoleRepository;
use App\Repository\User\UserProfileRepository;
use App\Repository\User\UserRepository;
use App\Service\AuthenticationService;
use App\Service\Mailer\ProfileMailer;
use App\Service\ProfileService;
use Ramsey\Uuid\Uuid;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
class ProfileSubscriber implements EventSubscriberInterface
{
/**
* @var RoleRepository
*/
private $roleRepository;
/**
* @var ProfileSocialMediaRepository
*/
private $profileSocialMediaRepository;
/**
* @var ProfileHierarchyHistoryLogRepository
*/
private $profileHierarchyHistoryLogRepository;
/**
* @var UserRepository
*/
private $userRepository;
/**
* @var ProfileMailer
*/
private $profileMailer;
/**
* @var InvitationRepository
*/
private $invitationRepository;
/**
* @var PlatformRepository
*/
private $platformRepository;
/**
* @var PlatformIpiNumberRepository
*/
private $platformIpiNumberRepository;
/**
* @var DeliverySplitsRepository
*/
private $deliverySplitsRepository;
/**
* @var ProfileService
*/
private $profileService;
/**
* @var ProfileRepository
*/
private $profileRepository;
/** @var ProfileInformationRepository */
private $profileInformationRepository;
/** @var ProfileRBACRepository */
private $profileRBACRepository;
/** @var UserProfileRepository */
private $userProfileRepository;
/** @var ProfileAccessLogRepository */
private $profileAccessLogRepository;
/** @var PackageTransactionRepository */
private $packageTransactionRepository;
/** @var PackageSongwriterRepository */
private $packageSongwriterRepository;
/** @var InvoiceRepository */
private $invoiceRepository;
/**
* @var EventDispatcherInterface
*/
private $eventDispatcher;
/**
* @var AuthenticationService
*/
private $authenticationService;
public function __construct(
ProfileSocialMediaRepository $profileSocialMediaRepository,
ProfileHierarchyHistoryLogRepository $profileHierarchyHistoryLogRepository,
UserRepository $userRepository,
ProfileMailer $profileMailer,
InvitationRepository $invitationRepository,
RoleRepository $roleRepository,
PlatformRepository $platformRepository,
PlatformIpiNumberRepository $platformIpiNumberRepository,
DeliverySplitsRepository $deliverySplitsRepository,
ProfileService $profileService,
ProfileRepository $profileRepository,
ProfileInformationRepository $profileInformationRepository,
ProfileRBACRepository $profileRBACRepository,
UserProfileRepository $userProfileRepository,
ProfileAccessLogRepository $profileAccessLogRepository,
PackageTransactionRepository $packageTransactionRepository,
PackageSongwriterRepository $packageSongwriterRepository,
InvoiceRepository $invoiceRepository,
EventDispatcherInterface $eventDispatcher,
AuthenticationService $authenticationService
)
{
$this->profileSocialMediaRepository = $profileSocialMediaRepository;
$this->profileHierarchyHistoryLogRepository = $profileHierarchyHistoryLogRepository;
$this->userRepository = $userRepository;
$this->profileMailer = $profileMailer;
$this->invitationRepository = $invitationRepository;
$this->roleRepository = $roleRepository;
$this->platformRepository = $platformRepository;
$this->platformIpiNumberRepository = $platformIpiNumberRepository;
$this->deliverySplitsRepository = $deliverySplitsRepository;
$this->profileService = $profileService;
$this->profileRepository = $profileRepository;
$this->profileInformationRepository = $profileInformationRepository;
$this->profileRBACRepository = $profileRBACRepository;
$this->userProfileRepository = $userProfileRepository;
$this->profileAccessLogRepository = $profileAccessLogRepository;
$this->packageTransactionRepository = $packageTransactionRepository;
$this->packageSongwriterRepository = $packageSongwriterRepository;
$this->invoiceRepository = $invoiceRepository;
$this->eventDispatcher = $eventDispatcher;
$this->authenticationService = $authenticationService;
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents(): array
{
return [
ProfileCreatedEvent::class => 'onProfileCreatedEvent',
ProfileCreatedForUserEvent::class => 'onProfileCreatedForUserEvent',
ProfileDeletedEvent::class => 'onProfileDeletedEvent',
UserInvitedToProfileEvent::class => 'onUserInvitedToProfileEvent',
ProfileEraisedEvent::class => 'onProfileEraisedEvent',
ProfileRoyaltyTemplateEditEvent::class => 'onProfileRoyaltyTemplateEditEvent',
];
}
/**
* @param ProfileCreatedEvent $event
* @throws TransportExceptionInterface
*/
public function onProfileCreatedEvent(ProfileCreatedEvent $event): void
{
// Generate and send profile invitation
/** @var Profile $parent */
$parent = $event->getProfile()->getParent();
/** @var Profile $profile */
$profile = $event->getProfile();
/** @var User $owner */
$owner = $this->getOrCreateUser($profile);
// Generate Works Prefix
$confirmationToken = Uuid::uuid4()->toString();
$prefix = $this->profileService->generateWorksPrefix($event->getProfile());
$profile->setWorksPrefix($prefix);
$profile->setConfirmationToken($confirmationToken);
$this->profileRepository->save($profile);
// Generate Platform IPI Numbers
/**if (
$event->getProfile()->getProfileType()->getName() === Constants::PROFILE_TYPE_PUBLISHER_ADMINISTRATOR ||
$event->getProfile()->getProfileType()->getName() === Constants::PROFILE_TYPE_PUBLISHER
) {
$platforms = $this->platformRepository->findAll();
foreach ($platforms as $platform) {
$platformIpiNumber = (new PlatformIpiNumber())
->setProfile($event->getProfile())
->setPlatform($platform);
$this->platformIpiNumberRepository->save($platformIpiNumber);
}
}**/
// Generate profile social media
$profileSocialMedia = (new ProfileSocialMedia())
->setProfile($event->getProfile());
$this->profileSocialMediaRepository->save($profileSocialMedia);
// Generate profile hierarchy history log
$profileHierarchyHistoryLog = (new ProfileHierarchyHistoryLog())
->setProfile($event->getProfile())
->setParent($event->getProfile()->getParent());
$this->profileHierarchyHistoryLogRepository->save($profileHierarchyHistoryLog);
// Generate delivery splits for profile
$deliverySplits = (new DeliverySplits())
->setProfile($event->getProfile());
$this->profileService->processToCreateRoyaltySplits($profile);
$this->deliverySplitsRepository->save($deliverySplits);
// Set Minimum Payment of the profile
$this->profileService->processToSetMinimumPayment($profile);
if($parent->getProfileType()->getName() === Constants::PROFILE_TYPE_PUBLISHER){
$profileRBAC = (new ProfileRBAC())
->setProfile($event->getProfile())
->setRole($this->roleRepository->findOneBy(['name' => Constants::PROFILE_ROLE_NAME_OWNER]))
->setUser($parent->getOwner());
$this->profileRBACRepository->save($profileRBAC);
$invitation = (new Invitation())
->setProfile($event->getProfile())
->setEmail($event->getProfile()->getProfileInformation()->getEmail())
->setLastName("user")
->setFirstName("user")
->setRole($this->roleRepository->findOneByName(Constants::PROFILE_ROLE_NAME_ADMIN))
->setToken($confirmationToken)
->setUser($owner);
$this->invitationRepository->save($invitation);
}else{
$invitation = (new Invitation())
->setProfile($event->getProfile())
->setEmail($event->getProfile()->getProfileInformation()->getEmail())
->setLastName("user")
->setFirstName("user")
->setRole($this->roleRepository->findOneByName(Constants::PROFILE_ROLE_NAME_OWNER))
->setToken($confirmationToken)
->setUser($owner);
$this->invitationRepository->save($invitation);
}
if($event->getFrom() === Constants::MMPZ_REFERER){
$this->profileMailer->sendProfileCreatedEmail($invitation);
}
if($parent->getProfileType()->getName() === Constants::PROFILE_TYPE_PUBLISHER){
$this->profileService->updateProfilePackageSongwriterAfterCreateSubProfile($parent);
}
}
/**
* @param ProfileCreatedForUserEvent $event
* @throws TransportExceptionInterface
*/
public function onProfileCreatedForUserEvent(ProfileCreatedForUserEvent $event): void
{
$this->profileMailer->sendProfileNotificationEmail($event->getUser(), $event->getMessage());
}
/**
* @param ProfileCreatedForUserEvent $event
* @throws TransportExceptionInterface
*/
public function onProfileDeletedEvent(ProfileDeletedEvent $event): void
{
$this->profileMailer->sendProfileNotificationEmail($event->getUser(), $event->getMessage());
}
/**
* @param ProfileEraisedEvent $event
* @throws TransportExceptionInterface
*/
public function onProfileEraisedEvent(ProfileEraisedEvent $event): void
{
/** @var Profile $profile */
$profile = $event->getProfile();
$this->eventDispatcher->dispatch(new LogEvent(
$profile,
$this->authenticationService->getUser(),
EventLog::TYPE_PROFILE_ERASED
));
if(!is_null($profile->getProfileInformation())){
$this->profileInformationRepository->remove($profile->getProfileInformation());
$this->profileInformationRepository->flush();
}
$invitations = $this->invitationRepository->findBy(['profile' => $profile]);
if(count($invitations)){
foreach ($invitations as $invitation){
$this->invitationRepository->remove($invitation);
}
$this->invitationRepository->flush();
}
if($profile->getPlatformIpiNumbers()->count() > 0){
/** @var PlatformIpiNumber $platformIpiNumber */
foreach ($profile->getPlatformIpiNumbers() as $platformIpiNumber){
$this->platformIpiNumberRepository->remove($platformIpiNumber);
}
$this->platformIpiNumberRepository->flush();
}
/** @var ProfileRBAC $profileRBAC */
foreach($profile->getProfileRBAC() as $profileRBAC){
$user = $profileRBAC->getUser();
$this->profileRBACRepository->remove($profileRBAC);;
$this->profileRBACRepository->flush();
if($event->getFlag() === 'user'){
$this->eventDispatcher->dispatch(new LogEvent(
$user,
$this->authenticationService->getUser(),
EventLog::TYPE_USER_ERASED
));
$this->eventDispatcher->dispatch(new LogEvent(
$profile,
$this->authenticationService->getUser(),
EventLog::TYPE_PROFILE_AND_USERS_ERASED
));
$this->userProfileRepository->remove($user->getUserProfile());
$this->userProfileRepository->flush();
$this->userRepository->remove($user);
$this->userRepository->flush();
}
}
if($event->getFlag() === 'user'){
//this is when the user and the profile don't have an established relation
$this->deleteUserWithoutAssociationforProfile($profile);
}
/** @var ProfileAccessLog $profileAccessLog */
foreach ($this->profileAccessLogRepository->findBy(['profile' => $profile]) as $profileAccessLog){
$this->profileAccessLogRepository->remove($profileAccessLog);
$this->profileAccessLogRepository->flush();
}
if($profile->getPackageSongWriters()->count() > 0){
/** @var PackageSongWriter $packageSongWriter */
foreach ($profile->getPackageSongWriters() as $packageSongWriter){
foreach ($packageSongWriter->getInvoices() as $invoice){
$this->invoiceRepository->remove($invoice);
$this->invoiceRepository->flush();
}
$this->packageSongwriterRepository->remove($packageSongWriter);
$this->packageSongwriterRepository->flush();
}
}
$this->profileMailer->sendProfileNotificationEmail($event->getUser(), $event->getMessage());
}
/**
* @param UserInvitedToProfileEvent $event
* @throws TransportExceptionInterface
*/
public function onUserInvitedToProfileEvent(UserInvitedToProfileEvent $event): void
{
$invitation = $event->getInvitation();
$this->profileMailer->sendUserInvitedToProfileMail($invitation);
}
/**
* @param ProfileRoyaltyTemplateEditEvent $event
* @return void
*/
public function onProfileRoyaltyTemplateEditEvent(ProfileRoyaltyTemplateEditEvent $event)
{
$this->profileService->processToEditARoyaltyTemplate($event->getRoyaltySplitsTemplate());
}
/** PRIVATE FUNCTIONS */
/**
* This function is used in the creation Profile process to get the owner user for the new profile or to create once
*
* @param Profile $profile
*
* @return User
*/
private function getOrCreateUser($profile)
{
/** @var User $user */
$user = $this->userRepository->findOneBy(['email' => $profile->getProfileInformation()->getEmail()]);
/*if(is_null($user)){
$user = (new User())
->setEmail($profile->getProfileInformation()->getEmail())
->setEnabled(true);
$this->userRepository->save($user);
$userProfile = (new UserProfile())
->setUser($user)
->setFirstName($profile->getProfileInformation()->getFirstName())
->setLastName($profile->getProfileInformation()->getLastName());
$this->userProfileRepository->save($userProfile);
$user = $this->userRepository->findOneBy(['email' => $profile->getProfileInformation()->getEmail()]);
}*/
return $user;
}
/**
* this function is used in de erased profile process to delete a profile created with this user without association
*
* @param Profile $profile
* @return bool
*/
private function deleteUserWithoutAssociationforProfile(Profile $profile): bool
{
/** @var User $user */
$user = $this->userRepository->findOneBy(['email' => $profile->getProfileInformation()->getEmail()]);
if(is_null($user)){
return false;
}else{
$profiles = $this->profileService->findMainProfilesForUser($user);
if(count($profiles) > 0){
return false;
}else{
$this->eventDispatcher->dispatch(new LogEvent(
$user,
$this->authenticationService->getUser(),
EventLog::TYPE_USER_ERASED
));
$this->eventDispatcher->dispatch(new LogEvent(
$profile,
$this->authenticationService->getUser(),
EventLog::TYPE_PROFILE_AND_USERS_ERASED
));
$this->userProfileRepository->remove($user->getUserProfile());
$this->userProfileRepository->flush();
$this->userRepository->remove($user);
$this->userRepository->flush();
return true;
}
}
}
}