add success email (#14)
Co-authored-by: Jan-Marlon Leibl <jleibl@proton.me> Reviewed-on: #14 Reviewed-by: jank1619 <jan@kjan.email>
This commit is contained in:
20
src/Controller/SuccessController.php
Normal file
20
src/Controller/SuccessController.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Service\TicketService;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
class SuccessController extends AbstractController
|
||||
{
|
||||
#[Route(path: '/success', name: 'app_success_page', methods: Request::METHOD_GET)]
|
||||
public function __invoke(TicketService $service, Request $request): Response
|
||||
{
|
||||
$service->completePayment((string)$request->query->get('session_id'));
|
||||
|
||||
return $this->render('ticket/success.html.twig');
|
||||
}
|
||||
}
|
24
src/Controller/TestController.php
Normal file
24
src/Controller/TestController.php
Normal file
@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use Nucleos\DompdfBundle\Factory\DompdfFactory;
|
||||
use Nucleos\DompdfBundle\Wrapper\DompdfWrapper;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\Filesystem\Filesystem;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
class TestController extends AbstractController
|
||||
{
|
||||
#[Route('/test')]
|
||||
public function index(Filesystem $filesystem): Response
|
||||
{
|
||||
$filesystem->dumpFile('test.pdf', $content);
|
||||
|
||||
return $this->render('test.html.twig', ['qr' => (new QRCode())->render('https://www.google.com')]);
|
||||
}
|
||||
}
|
@ -33,7 +33,7 @@ final class TicketController extends AbstractController
|
||||
return $this->json(['id' => $this->service->handleTicketData($ticketData)->id]);
|
||||
}
|
||||
|
||||
#[Route(path: '/success', name: 'app_success', methods: Request::METHOD_GET)]
|
||||
#[Route(path: '/success', name: 'app_order_success', methods: Request::METHOD_GET)]
|
||||
public function success(Request $request): Response
|
||||
{
|
||||
$sessionId = $request->query->get('session_id');
|
||||
@ -50,7 +50,7 @@ final class TicketController extends AbstractController
|
||||
return $this->redirectToRoute('app_ticket');
|
||||
}
|
||||
|
||||
return $this->render('ticket/success.html.twig');
|
||||
return $this->redirectToRoute('app_success_page');
|
||||
}
|
||||
|
||||
#[Route(path: '/cancelled', name: 'app_cancelled', methods: Request::METHOD_GET)]
|
||||
|
64
src/Service/TicketEmailService.php
Normal file
64
src/Service/TicketEmailService.php
Normal file
@ -0,0 +1,64 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Controller\Admin\TicketCrudController;
|
||||
use App\Entity\Payment;
|
||||
use App\Entity\Ticket;
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use Nucleos\DompdfBundle\Factory\DompdfFactory;
|
||||
use Nucleos\DompdfBundle\Wrapper\DompdfWrapper;
|
||||
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use Symfony\Component\Mailer\MailerInterface;
|
||||
use Symfony\Component\Mime\Address;
|
||||
use Symfony\Component\Mime\Part\DataPart;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Twig\Environment;
|
||||
|
||||
class TicketEmailService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly MailerInterface $mailer,
|
||||
#[Autowire(env: 'SENDER_MAIL')]
|
||||
private readonly string $senderMail,
|
||||
private readonly UrlGeneratorInterface $urlGenerator,
|
||||
private readonly Environment $twig,
|
||||
) {
|
||||
}
|
||||
|
||||
public function sendSuccessEmail(Payment $payment): void
|
||||
{
|
||||
$mail = (new TemplatedEmail())
|
||||
->htmlTemplate('email/order.html.twig')
|
||||
->subject('Abiball Ticket')
|
||||
->from(new Address($this->senderMail, 'Noreply'))
|
||||
->to(new Address($payment->getCustomer()?->getEmail(), $payment->getCustomer()?->getFirstname() . ' ' . $payment->getCustomer()?->getLastname()))
|
||||
->context([
|
||||
'payment' => $payment,
|
||||
]);
|
||||
|
||||
$i = 0;
|
||||
foreach ($payment->getCustomer()?->getTickets() as $ticket) {
|
||||
++$i;
|
||||
$mail->addPart(new DataPart($this->generateTicket($ticket), "ticket-$i.pdf", 'application/pdf'));
|
||||
}
|
||||
|
||||
$this->mailer->send($mail);
|
||||
}
|
||||
|
||||
private function generateTicket(Ticket $ticket): string
|
||||
{
|
||||
return (new DompdfWrapper(new DompdfFactory()))->getPdf($this->twig->render('test.html.twig', ['qr' => (new QRCode())->render($this->generateUrl($ticket))]));
|
||||
}
|
||||
|
||||
private function generateUrl(Ticket $ticket): string
|
||||
{
|
||||
return $this->urlGenerator->generate('admin', [
|
||||
'crudAction' => 'detail',
|
||||
'crudControllerFqcn' => TicketCrudController::class,
|
||||
'entityId' => $ticket->getCustomer()?->getId()
|
||||
], UrlGeneratorInterface::ABSOLUTE_URL);
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ class TicketService
|
||||
private readonly UrlGeneratorInterface $generator,
|
||||
private readonly EntityManagerInterface $em,
|
||||
private readonly PaymentRepository $paymentRepository,
|
||||
private readonly TicketEmailService $emailService,
|
||||
#[Autowire(env: 'STRIPE_SECRET_KEY')]
|
||||
string $stripeKey
|
||||
) {
|
||||
@ -36,18 +37,6 @@ class TicketService
|
||||
return $session;
|
||||
}
|
||||
|
||||
public function saveTicketData(TicketFormData $data, string $sessionId): void
|
||||
{
|
||||
$payment = (new Payment())
|
||||
->setSessionId($sessionId)
|
||||
->setCompleted(false)
|
||||
->setCustomer($this->createEntityFromData($data));
|
||||
|
||||
$this->em->persist($payment);
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
|
||||
public function completePayment(string $sessionId): bool
|
||||
{
|
||||
if (!$payment = $this->paymentRepository->findOneBy(['sessionId' => $sessionId])) {
|
||||
@ -57,9 +46,23 @@ class TicketService
|
||||
$payment->setCompleted(true);
|
||||
$this->em->flush();
|
||||
|
||||
$this->emailService->sendSuccessEmail($payment);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private function saveTicketData(TicketFormData $data, string $sessionId): void
|
||||
{
|
||||
$payment = (new Payment())
|
||||
->setSessionId($sessionId)
|
||||
->setCompleted(false)
|
||||
->setCustomer($this->createEntityFromData($data));
|
||||
|
||||
$this->em->persist($payment);
|
||||
$this->em->flush();
|
||||
}
|
||||
|
||||
private function getLineItems(array $tickets): array
|
||||
{
|
||||
$lineItems = [];
|
||||
@ -87,7 +90,7 @@ class TicketService
|
||||
'line_items' => $lineItems,
|
||||
'mode' => 'payment',
|
||||
'customer_email' => $email,
|
||||
'success_url' => $this->generator->generate('app_success', [], 0) . '?session_id={CHECKOUT_SESSION_ID}',
|
||||
'success_url' => $this->generator->generate('app_order_success', [], 0) . '?session_id={CHECKOUT_SESSION_ID}',
|
||||
'cancel_url' => $this->generator->generate('app_cancelled', [], 0),
|
||||
]);
|
||||
}
|
||||
|
Reference in New Issue
Block a user