<?php
namespace App\Controller;
use App\Entity\EmailConfirmation;
use App\Form\SubscribeForm;
use App\Service\TessituraBundle\ConstituentService;
use App\Service\TessituraSDK\Entity\Remote\WebLogin;
use App\Service\TessituraSDK\Resource\CRM\WebLogins;
use App\Service\TessituraSDK\Resource\Emails;
use App\Service\TessituraSDK\TessituraClient;
use App\Service\TessituraSDK\TessituraClientException;
use App\Service\TessituraSDK\Request as TessituraRequest;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\User\User;
use Symfony\Contracts\Translation\TranslatorInterface;
class SubscribeController extends AbstractController
{
/**
* @var TessituraClient
*/
private $client;
/**
* @var TranslatorInterface
*/
private $translator;
/**
* @var ParameterBagInterface
*/
private $params;
public function __construct(
TessituraClient $client,
TranslatorInterface $translator,
ParameterBagInterface $params
) {
$this->client = $client;
$this->translator = $translator;
$this->params = $params;
}
/**
* @Route(
* "/subscribe/",
* name="subscribe-redirect",
* )
* @param Request $request
*
* @return Response
*/
public function subscribeRedirect(Request $request)
{
return $this->redirect('/en/subscribe');
}
/**
* @Route(
* "/{_locale}/subscribe/",
* name="subscribe",
* defaults={
* "_locale": "fi"
* },
* requirements={
* "_locale": "fi|sv|en"
* }
* )
* @param Request $request
*
* @return Response
*/
public function subscribeAction(Request $request)
{
/** @var User $user */
$user = $this->get('security.token_storage')->getToken()->getUser();
if (in_array('ROLE_TESSITURA_KNOWN', $user->getRoles())) {
return $this->redirectToRoute('account-profile', ['_fragment' => 'subscribe']);
}
$form = $this->createForm(SubscribeForm::class, [
]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$searchResponse = $this->client->request(WebLogins::search([
'emailAddress' => $data['email'],
'loginTypeId' => $this->params->get('tessitura.logintype')
]));
$webLogins = $searchResponse->denormalize(WebLogin::class . '[]');
if (!empty($webLogins)) {
$form->addError(new FormError($this->translator->trans('form_subscribe_email_exists_error')));
} else {
$mail = $this->generateSubscriptionConfirmationMail($data);
$this->client->request($mail);
return $this->render('page/subscribe.html.twig', [
'submitted' => true
]);
}
}
return $this->render('page/subscribe.html.twig', [
'form' => $form->createView(),
'submitted' => false
]);
}
/**
* @Route(
* "/api/v1/subscribe/",
* name="subscribe-api",
* methods={"POST"},
* )
* @param Request $request
*
* @return Response
*/
public function subscribeRequest(Request $request)
{
$data = $request->toArray();
$origin = $request->headers->get('Origin');
if (!$data['email'] || !$data['firstname'] || !$data['lastname'] || !$data['consent']) {
return new JsonResponse(array_merge([
'success' => false,
'message' => 'Bad request'
], $data), 400);
}
$searchResponse = $this->client->request(WebLogins::search([
'emailAddress' => $data['email'],
'loginTypeId' => $this->params->get('tessitura.logintype')
]));
$webLogins = $searchResponse->denormalize(WebLogin::class . '[]');
if (!empty($webLogins)) {
return new JsonResponse(array_merge([
'success' => false,
'message' => 'Change subscription status in profile page'
], $data), 400);
} else {
$mail = $this->generateSubscriptionConfirmationMail($data);
try {
$this->client->request($mail);
} catch (TessituraClientException $exception) {
return new JsonResponse(array_merge([
'success' => false,
'message' => $exception->getMessage()
], $data), 500);
}
return new JsonResponse(array_merge([
'success' => true,
'message' => 'success'
], $data), 200);
}
}
/**
* @param mixed $data
* @return TessituraRequest
*/
private function generateSubscriptionConfirmationMail($data) {
/** @var EntityManagerInterface $em */
$em = $this->getDoctrine()->getManager();
/** @var EmailConfirmation $emailConfirmation */
$emailConfirmation = $em->getRepository(EmailConfirmation::class)->findOneBy([
'email' => $data['email']
]);
if (!$emailConfirmation) {
$emailConfirmation = new EmailConfirmation();
}
$emailConfirmation->setEmail($data['email']);
$emailConfirmation->setFirstname($data['firstname']);
$emailConfirmation->setLastname($data['lastname']);
$emailConfirmation->setToken(strtoupper(md5(uniqid())));
$em->persist($emailConfirmation);
$em->flush();
$template = $this->render('emails/subscribe-confirm.html.twig', [
'confirm_link' => $this->generateUrl('subscribe-confirm', [],
UrlGeneratorInterface::ABSOLUTE_URL) . '?token=' . $emailConfirmation->getToken()
]);
return Emails::send([
'HtmlBody' => $template->getContent(),
'Subject' => $this->translator->trans('subscribe_email_confirm_subject'),
'EmailProfileId' => $this->params->get('tessitura.subscribe.profile_id'),
'RecipientAddress' => $data['email']
]);
}
/**
* @Route(
* "/{_locale}/subscribe/confirm/",
* name="subscribe-confirm",
* defaults={
* "_locale": "fi"
* },
* requirements={
* "_locale": "fi|sv|en"
* }
* )
* @param Request $request
*
* @return Response
*/
public function confirmAction(Request $request, ConstituentService $constituentService)
{
/** @var User $user */
$user = $this->get('security.token_storage')->getToken()->getUser();
$token = $request->get('token');
$hasError = false;
if ($token) {
/** @var EntityManagerInterface $em */
$em = $this->getDoctrine()->getManager();
/** @var EmailConfirmation $emailConfirmation */
$emailConfirmation = $em->getRepository(EmailConfirmation::class)->findOneBy([
'token' => $token,
'savedTessitura' => null
]);
if (!$emailConfirmation) {
$hasError = true;
} else {
$searchResponse = $this->client->request(WebLogins::search([
'emailAddress' => $emailConfirmation->getEmail(),
'loginTypeId' => $this->params->get('tessitura.logintype')
]));
$webLogins = $searchResponse->denormalize(WebLogin::class . '[]');
if (in_array('ROLE_TESSITURA_KNOWN', $user->getRoles())) {
$hasError = true;
} elseif (!$webLogins) {
$registrationData = [
'email' => $emailConfirmation->getEmail(),
'firstname' => $emailConfirmation->getFirstname(),
'lastname' => $emailConfirmation->getLastname(),
'city' => $this->params->get('tessitura.subscribe.default_city'),
'postalcode' => $this->params->get('tessitura.subscribe.default_postalcode'),
'street1' => $this->params->get('tessitura.subscribe.default_street1'),
'mobile' => $this->params->get('tessitura.subscribe.default_phone'),
'mobile_national' => $this->params->get('tessitura.subscribe.default_phone_national'),
'opt_in' => (in_array($request->getLocale(), ['en', 'sv'])) ? [ConstituentService::OPTIN_KV] : [ConstituentService::OPTIN_EMAIL],
'password' => str_shuffle(md5(time()))
];
$constituentService->register($constituentService->getUser(), $registrationData);
$emailConfirmation->setSavedTessitura(1);
$em->persist($emailConfirmation);
$em->flush();
} else {
$hasError = true;
}
}
} else {
$hasError = true;
}
return $this->render('page/subscribe-confirm.html.twig', [
'has_error' => $hasError
]);
}
}