<?php
namespace App\EventSubscriber\App;
use App\Entity\AutomatedEmailNotificationDefinition\AutomatedEmailNotificationDefinitionTextContent;
use App\Entity\Notification;
use App\Entity\UsageEvent;
use App\Entity\User;
use App\Event\NewUserEmailAddressConfirmedEvent;
use App\Event\UserAccountConfirmedEvent;
use App\Event\UserEmailAddressEditedEvent;
use App\Event\UserRegisteredEvent;
use App\Event\UserTermsAndConditionsAcceptedEvent;
use App\Event\UserWillBeRemovedEvent;
use App\Service\AutomatedEmailNotificationDefinitionService;
use App\Service\ConversionEventService;
use App\Service\CustomerHelpDeskService;
use App\Service\ExternalFeedsService;
use App\Service\MailService;
use App\Service\OnetimeLoginTokenService;
use App\Service\RouterHelperService;
use App\Service\UsageEventService;
use App\Service\UserService;
use App\SymfonyMessage\SendJoboffererMissingMembershipAfterRegistrationMailSymfonyMessage;
use App\Utility\DateTimeUtility;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use JanusHercules\DatawarehouseIntegration\Domain\Entity\BusinessEvent;
use JanusHercules\DatawarehouseIntegration\Domain\Entity\ExternalPartnerEvent;
use JanusHercules\DatawarehouseIntegration\Domain\Service\BusinessEventDomainService;
use JanusHercules\DatawarehouseIntegration\Domain\Service\ExternalPartnerEventDomainService;
use Psr\Log\LoggerInterface;
use Swift_Message;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Stamp\DelayStamp;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Throwable;
use Twig\Environment;
use Twig\Error\LoaderError;
use Twig\Error\RuntimeError;
use Twig\Error\SyntaxError;
class UserEventSubscriber implements EventSubscriberInterface
{
public function __construct(
private BusinessEventDomainService $businessEventDomainService,
private ConversionEventService $conversionEventService,
private ExternalPartnerEventDomainService $externalPartnerEventDomainService,
private UsageEventService $usageEventService,
private RouterHelperService $routerHelperService,
private OnetimeLoginTokenService $onetimeLoginTokenService,
private EntityManagerInterface $entityManager,
private TranslatorInterface $translator,
private MailService $mailService,
private AutomatedEmailNotificationDefinitionService $automatedEmailNotificationDefinitionService,
private Environment $twigEnvironment,
private LoggerInterface $logger,
private UserService $userService,
private CustomerHelpDeskService $customerHelpDeskService,
private readonly MessageBusInterface $messageBus
) {
}
public static function getSubscribedEvents(): array
{
return [
UserRegisteredEvent::class => 'onUserRegistered',
UserWillBeRemovedEvent::class => 'onUserWillBeRemoved',
UserAccountConfirmedEvent::class => 'onUserAccountConfirmed',
UserEmailAddressEditedEvent::class => 'onUserEmailAddressEdited',
NewUserEmailAddressConfirmedEvent::class => 'onNewUserEmailAddressConfirmed',
UserTermsAndConditionsAcceptedEvent::class => 'onUserTermsAndConditionsAccepted'
];
}
public function onUserTermsAndConditionsAccepted(
UserTermsAndConditionsAcceptedEvent $event
): void {
$user = $event->getUser();
$user->setAcceptedTermsAndConditions(true);
$this->entityManager->persist($user);
$this->entityManager->flush();
$this->businessEventDomainService->writeNewEvent(
BusinessEvent::EVENT_TYPE_TERMS_AND_CONDITIONS_HAS_BEEN_ACCEPTED,
$event->getUser(),
$event->getRecurrentJob()
);
}
public function onNewUserEmailAddressConfirmed(
NewUserEmailAddressConfirmedEvent $event): void
{
$user = $event->getUser();
$this->customerHelpDeskService->userEmailAddressHasChanged($user, $event->getConfirmedUserEmailAddress());
$this->logger->info(
"About to handle NewUserEmailAddressConfirmed for user {$user->getId()}"
);
$this->businessEventDomainService->writeNewEvent(BusinessEvent::EVENT_TYPE_NEW_USER_EMAIL_ADDRESS_CONFIRMED, $user);
}
public function onUserEmailAddressEdited(
UserEmailAddressEditedEvent $event
): void {
$user = $event->getUser();
$this->userService->sendConfirmationEmailToUser($user, $event->getEditedUserEmailAddress());
$this->logger->info(
"About to handle UserEmailAddressEditedEvent for user {$user->getId()}"
);
}
/** @throws Exception */
public function onUserRegistered(
UserRegisteredEvent $event
): void {
$this->logger->info(
"About to handle UserRegisteredEvent for user {$event->getUser()->getId()}"
);
try {
$user = $event->getUser();
$extendedApplication = $event->getExtendedApplication();
$this->businessEventDomainService->writeNewEvent(
BusinessEvent::EVENT_TYPE_NEW_USER_ACCOUNT_REGISTERED,
$user,
null,
null,
json_encode(['userCreatedVia' => $user->getCreatedVia()])
);
$additionalData = json_encode(['createdVia' => 'normal_reg']);
if ($event->getUser()->getCreatedVia() === User::CREATED_VIA_GOOGLE_IDENTITY_OAUTH2) {
$this->businessEventDomainService->writeNewEvent(
BusinessEvent::EVENT_TYPE_NEW_USER_ACCOUNT_REGISTERED_VIA_GOOGLE_IDENTITY_OAUTH2,
$user,
$extendedApplication?->getRecurrentJob()
);
$additionalData = json_encode(['createdVia' => 'google_identity_oauth2']);
} elseif ($event->getUser()->getCreatedVia() === User::CREATED_VIA_GOOGLE_IDENTITY_GSI) {
$this->businessEventDomainService->writeNewEvent(
BusinessEvent::EVENT_TYPE_NEW_USER_ACCOUNT_REGISTERED_VIA_GOOGLE_IDENTITY_GSI,
$user,
$extendedApplication?->getRecurrentJob()
);
$additionalData = json_encode(['createdVia' => 'google_identity_gsi']);
} elseif ($event->getUser()->getCreatedVia() === User::CREATED_VIA_WANTED_JOBS_SEARCH_ANONYMOUS_USER_FORM) {
$additionalData = json_encode(['createdVia' => 'wanted_jobs_search_anonymous_form']);
}
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_REGISTRATION_REFERER,
$user->isJobseeker() ? 1 : 0,
null,
$user,
$extendedApplication?->getRecurrentJob(),
null,
$additionalData
);
foreach ([
ConversionEventService::CAMPAIGN_ID_SHARED_RECURRENT_JOBS,
ConversionEventService::CAMPAIGN_ID_RECURRENT_JOBS_TO_PRINT_QR_CODE,
ConversionEventService::CAMPAIGN_ID_INSTAGRAM,
ConversionEventService::CAMPAIGN_ID_EASY_LEBENSLAUF,
ConversionEventService::CAMPAIGN_ID_JOBWARE,
ConversionEventService::CAMPAIGN_ID_AGENTUR_FUER_ARBEIT,
ConversionEventService::CAMPAIGN_ID_SIMILAR_JOBS,
ConversionEventService::CAMPAIGN_ID_GOOGLE_FOR_JOBS,
ConversionEventService::CAMPAIGN_ID_EXTENDED_APPLICATION_INFO_MAIL_NONSUBSCRIBED_JOBOFFERERS,
ConversionEventService::CAMPAIGN_ID_EMAIL_MARKETING_AKTION,
ConversionEventService::CAMPAIGN_ID_EMAIL_MARKETING_SONDERAKTION,
ConversionEventService::CAMPAIGN_ID_LINKED_IN,
ConversionEventService::CAMPAIGN_ID_PERSPECTIVE,
ConversionEventService::CAMPAIGN_ID_XING_FEED
] as $campaignId
) {
$this->conversionEventService->handleConversionGoalReached(
$campaignId,
0,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
foreach ([
ConversionEventService::CAMPAIGN_ID_EMAIL_MARKETING_ANGEBOT,
ConversionEventService::CAMPAIGN_ID_EMAIL_MARKETING_SONDERANGEBOT,
ConversionEventService::CAMPAIGN_ID_EMAIL_MARKETING_JETZT,
ConversionEventService::CAMPAIGN_ID_YOUTUBE
] as $campaignId
) {
$this->conversionEventService->handleConversionGoalReached(
$campaignId,
0,
null,
$user
);
}
foreach ([
ConversionEventService::CAMPAIGN_ID_JOBLIFT,
ConversionEventService::CAMPAIGN_ID_TALENTCOM,
ConversionEventService::CAMPAIGN_ID_STELLENONLINE,
ConversionEventService::CAMPAIGN_ID_CRITEO,
ConversionEventService::CAMPAIGN_ID_JOOBLE,
ConversionEventService::CAMPAIGN_ID_STEPSTONE_FEED
] as $campaignId
) {
foreach ([0, 1, 2] as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
$campaignId,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
}
foreach ([
ConversionEventService::CAMPAIGN_ID_BING_LANDINGPAGES,
ConversionEventService::CAMPAIGN_ID_JOYN
] as $campaignId
) {
foreach ([0, 1, 2, 3] as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
$campaignId,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
}
foreach ([
ConversionEventService::CAMPAIGN_ID_JOBIJOBA,
ConversionEventService::CAMPAIGN_ID_WHATJOBS
] as $campaignId
) {
foreach ([0, 1, 2, 3, 4, 5] as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
$campaignId,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
}
foreach ([0, 1, 2, 3, 4, 5, 7] as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_RECURRENT_JOBS_SEARCH_FOR_ONE_SPECIFIC_CUSTOMER,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob(),
null,
null,
!is_null($user)
? $user->getIntegratedExternalPartnerCustomer()
: null
);
}
foreach ([4, 5, 6] as $subcampaignId) {
if ($subcampaignId !== 5) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_TALENTCOM,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_STELLENONLINE,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_JOBLIFT,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
foreach (ExternalFeedsService::EBAY_SUBCAMPAIGN_VARIANTS as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_EBAY,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
foreach (range(0, 500) as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_FACEBOOK,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
foreach ([501, 503] as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_FACEBOOK,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_EASY_LEBENSLAUF,
1,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
foreach (range(0, 31) as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_LANDINGPAGES,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
foreach ([0, 1] as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_GMX,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
foreach ([0, 1, 2, 7, 8, 9, 10, 11, 12, 13] as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_MEINESTADT,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
if ($event->getUser()->isJobofferer()) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_EBAY,
8,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
// Marketing-Landingpages AG-Registrierung (pages.joboo.de)
// Loop über alle möglichen Subcampaign-IDs (0-1000)
for ($subcampaignId = 0; $subcampaignId <= 1000; ++$subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_DIGITAL_ESTATE_MARKETING_LANDINGPAGES_AG_REGISTRATION,
$subcampaignId,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
}
}
if ($event->getUser()->isJobseeker()) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_UGC_FUNNEL,
0,
null,
$user,
$extendedApplication?->getRecurrentJob()
);
if ($extendedApplication) {
foreach ([0, 1] as $subcampaignId) {
$this->conversionEventService->handleConversionGoalReached(
ConversionEventService::CAMPAIGN_ID_PERSOMATCH_FEED,
$subcampaignId,
null,
$user,
$extendedApplication->getRecurrentJob()
);
}
}
}
} catch (Throwable $t) {
$this->logger->error("Error handling UserRegisteredEvent for user {$event->getUser()->getId()}: {$t->getMessage()}");
}
}
public function onUserWillBeRemoved(UserWillBeRemovedEvent $event)
{
$user = $event->getUser();
if ($user->isLinkedToExternalPartner()) {
$this->externalPartnerEventDomainService->writeEvent(
ExternalPartnerEvent::EVENT_TYPE_USER_REMOVED,
$user->getExternalPartner(),
null,
null,
null,
null,
null,
null,
$user
);
}
}
/**
* @throws RuntimeError
* @throws SyntaxError
* @throws LoaderError
* @throws Exception|\Doctrine\DBAL\Driver\Exception
*/
public function onUserAccountConfirmed(UserAccountConfirmedEvent $event): void
{
$user = $event->getUser();
$this->businessEventDomainService->writeNewEvent(BusinessEvent::EVENT_TYPE_NEW_USER_ACCOUNT_CONFIRMED, $user);
$this->usageEventService->eventHasOccurredForUser($user, UsageEvent::EVENT_TYPE_NEW_USER_HAS_CONFIRMED_ACCOUNT);
$replacements = [
'contactUrl' => $this->routerHelperService->generate('contact', [], UrlGeneratorInterface::ABSOLUTE_URL),
'resetUrl' => $this->routerHelperService->generate(
'fos_user_resetting_request',
[],
UrlGeneratorInterface::ABSOLUTE_URL
)
];
$bodyId = 0;
if ($user->isJobofferer()) {
$bodyId = AutomatedEmailNotificationDefinitionService::BODY_ID_WELCOME_AFTER_CONFIRMED_BODY_JOBOFFERER;
}
if ($user->isJobseeker()) {
$bodyId = AutomatedEmailNotificationDefinitionService::BODY_ID_WELCOME_AFTER_CONFIRMED_BODY_JOBSEEKER;
}
/** @var AutomatedEmailNotificationDefinitionTextContent $textContent */
$textContent = $this
->entityManager
->getRepository(AutomatedEmailNotificationDefinitionTextContent::class)
->findOneBy([
'automatedEmailNotificationDefinition' => MailService::MAIL_ID_WELCOME_AFTER_CONFIRMED,
'subjectId' => AutomatedEmailNotificationDefinitionService::SUBJECT_ID_WELCOME_AFTER_CONFIRMED,
'bodyId' => $bodyId
]);
$replacements['confirmationUrl'] = $this->onetimeLoginTokenService->generateOneTimeLoginUrl(
OnetimeLoginTokenService::REDIRECT_KEY_SETOWNPASSWORD_FORM,
$user,
[],
ConversionEventService::CAMPAIGN_ID_WELCOME_MAIL,
$user->isJobseeker() ? 0 : 1,
null,
$event->getRequest(),
null,
UrlGeneratorInterface::ABSOLUTE_URL,
false,
$textContent->getAutomatedEmailNotificationDefinition()->getId(),
$textContent->getBodyId()
);
$message = (new Swift_Message($textContent->getSubject()))
->setFrom(MailService::DEFAULT_SENDER_NOREPLY_MAILADDRESS, $this->translator->trans('direct_email_communication.outgoing_message.noreply_sender_name'))
->setTo($user->getEmail())
->setBody(
$this->twigEnvironment->render(
$textContent->getTwigTemplateName(),
$replacements
),
'text/html'
);
$message->setFrom('team@joboo.de', $this->translator->trans('mailfromname.team'));
if ($user->isJobofferer()) {
$message->setBcc('vertragsdoku@joboo.de');
}
$this->mailService->queueForSending(MailService::MAIL_ID_WELCOME_AFTER_CONFIRMED, $message, $user);
if ($user->isJobofferer()) {
$this->messageBus->dispatch(
new SendJoboffererMissingMembershipAfterRegistrationMailSymfonyMessage($user->getId()),
[DelayStamp::delayUntil(
DateTimeUtility::createDateTimeUtc('+ 120 minutes')
)]
);
}
$this
->automatedEmailNotificationDefinitionService
->dispatchEmailNotificationTrigger(
Notification::EMAIL_NOTIFICATION_TRIGGER_POINT_ACCOUNT_CONFIRMATION,
$user
);
}
}