112 lines
4.2 KiB
PHP
112 lines
4.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controller\Voucher;
|
|
|
|
use App\Exception\VoucherShopUnavailableException;
|
|
use App\Form\Model\VoucherPurchaseDto;
|
|
use App\Htmx\HxTrait;
|
|
use App\Model\PurchaseFlow;
|
|
use App\Service\PurchaseFlowResolver;
|
|
use App\Service\VoucherPurchaseSessionManager;
|
|
use App\Service\VoucherTemplateProvider;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
|
|
/**
|
|
* Entry, cancellation and error pages of the voucher purchase flow, which replaces the voucher
|
|
* shop hosted by BusProNet (maske_gutschein.php).
|
|
*/
|
|
class IndexController extends AbstractController
|
|
{
|
|
use HxTrait;
|
|
|
|
public function __construct(
|
|
private readonly VoucherPurchaseSessionManager $sessionManager,
|
|
private readonly VoucherTemplateProvider $templateProvider,
|
|
private readonly PurchaseFlowResolver $purchaseFlowResolver,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* Renders a loading page that posts to init, as the booking flow does.
|
|
*/
|
|
#[Route('/gutschein', name: 'app_voucher', methods: ['GET'])]
|
|
public function index(#[MapQueryParameter('r')] ?string $returnUrl = null): Response
|
|
{
|
|
return $this->render('voucher/index.html.twig', [
|
|
'returnUrl' => $returnUrl,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Starts a fresh purchase and sends the visitor to the login page (sign in or continue as guest).
|
|
*
|
|
* POST-only for the same reason as app_booking_create_init: it resets session state and calls
|
|
* BusPro, so nothing that speculatively fetches URLs may trigger it.
|
|
*/
|
|
#[Route('/gutschein/init', name: 'app_voucher_init', methods: ['POST'])]
|
|
public function init(Request $request, #[MapQueryParameter('r')] ?string $returnUrl = null): Response
|
|
{
|
|
$this->sessionManager->clear($request);
|
|
$this->sessionManager->storeReturnUrl($request, $returnUrl);
|
|
|
|
try {
|
|
$templates = $this->templateProvider->getTemplates();
|
|
$paymentMethod = $this->templateProvider->getPaymentMethod();
|
|
} catch (VoucherShopUnavailableException) {
|
|
$this->addFlash('error', 'Gutscheine können gerade nicht gekauft werden. Bitte versuche es später noch einmal.');
|
|
|
|
return $this->htmxRedirect($request, $this->generateUrl('app_voucher_error'));
|
|
}
|
|
|
|
$dto = new VoucherPurchaseDto();
|
|
$dto->minAmount = $templates->minAmount;
|
|
$dto->maxAmount = $templates->maxAmount;
|
|
$dto->paymentMethod = $paymentMethod;
|
|
if (1 === \count($templates->templates)) {
|
|
$dto->template = $templates->templates[0];
|
|
}
|
|
|
|
$this->sessionManager->save($request, $dto);
|
|
$this->purchaseFlowResolver->markStarted($request, PurchaseFlow::Voucher);
|
|
|
|
return $this->htmxRedirect($request, $this->generateUrl('app_login'));
|
|
}
|
|
|
|
#[Route('/gutschein/abbrechen', name: 'app_voucher_cancel', methods: ['GET', 'POST'])]
|
|
public function cancel(Request $request): Response
|
|
{
|
|
if (Request::METHOD_POST !== $request->getMethod()) {
|
|
return $this->render('voucher/modal_cancel.html.twig');
|
|
}
|
|
|
|
$returnUrl = $this->sessionManager->getReturnUrl($request);
|
|
$this->sessionManager->clear($request);
|
|
|
|
// Without this, a later login would send the user back into the cancelled purchase
|
|
$request->getSession()->remove('_security.main.target_path');
|
|
|
|
if (null !== $this->getUser()) {
|
|
$this->addFlash('info', 'Gutscheinkauf abgebrochen.');
|
|
|
|
return $this->htmxRedirect($request, $this->generateUrl('app_account'));
|
|
}
|
|
|
|
return $this->htmxRedirect($request, $returnUrl);
|
|
}
|
|
|
|
#[Route('/gutschein/fehler', name: 'app_voucher_error', methods: ['GET'])]
|
|
public function error(Request $request): Response
|
|
{
|
|
return $this->render('booking/create/error.html.twig', [
|
|
'returnUrl' => $this->sessionManager->getReturnUrl($request),
|
|
'defaultErrorMessage' => 'Es ist ein Fehler beim Gutscheinkauf aufgetreten.',
|
|
]);
|
|
}
|
|
}
|