<?php
namespace Bidcoz\Bundle\FrontendBundle\Controller;
use Bidcoz\Bundle\CoreBundle\Controller\CoreController;
use Bidcoz\Bundle\CoreBundle\Entity\Campaign;
use Bidcoz\Bundle\CoreBundle\Entity\Organization;
use Bidcoz\Bundle\CoreBundle\Entity\Proxy\RegistrationPurchaseProxy;
use Bidcoz\Bundle\CoreBundle\Entity\Registration\RegistrationType;
use Bidcoz\Bundle\CoreBundle\Entity\User;
use Bidcoz\Bundle\FrontendBundle\Form\Type\RegistrationPurchaseType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
# TODO: New authenticator behaves differently for @Security and @IsGranted
# Issue: "Symfony\Component\Security\Core\Exception\AccessDeniedException: No user token or you forgot to put your controller behind a firewall while using a @Security tag
# PR fixes this (still "Open"): https://github.com/sensiolabs/SensioFrameworkExtraBundle/pull/763
# Docs: https://symfony.com/doc/5.2/security/experimental_authenticators.html#enabling-the-system
# Notes: When PR gets merged, switch back to using the @Security tag: @Security("is_granted('VIEW', organization) and is_granted('FRONT_END', campaign)")
/**
* @Route("/{orgSlug}/{campaignSlug}/registrations")
* @IsGranted("VIEW", subject="organization")
* @IsGranted("FRONT_END", subject="campaign")
*/
class RegistrationController extends CoreController
{
/**
* @Route("", name="campaign_registrations")
*/
public function registrationsAction(Organization $organization, Campaign $campaign)
{
$registrationTypes = $this->getRepository('Registration\RegistrationType')->findCampaignRegistrationTypes($campaign);
return $this->render('@BidcozFrontend/Campaign/Registrations/index.html.twig', [
'organization' => $organization,
'campaign' => $campaign,
'registrationTypes' => $registrationTypes,
]);
}
/**
* @Route("/registrations/{registrationId}", name="campaign_registration_view", methods={"GET"})
* @ParamConverter("registrationType", class="Bidcoz\Bundle\CoreBundle\Entity\Registration\RegistrationType", options={"id" = "registrationId"})
*/
public function buyRegistrationAction(Organization $organization, Campaign $campaign, RegistrationType $registrationType)
{
$user = $this->getUser();
if (!$user) {
$this->messageAccessDeniedException('You must login or create an account to purchase registrations');
}
$proxy = $this->createRegistrationProxy($registrationType, $campaign);
$formOptions = $this->getPurchaseRegistrationFormOptions($campaign, $registrationType, $user);
$form = $this->getPurchaseRegistrationForm($proxy, $formOptions);
return $this->render('@BidcozFrontend/Campaign/Registrations/buy.html.twig', array_merge($formOptions, [
'organization' => $organization,
'campaign' => $campaign,
'registrationType' => $registrationType,
'form' => $form->createView(),
]));
}
/**
* @Route("/registrations/{registrationId}", name="campaign_registration_purchase", methods={"POST"})
* @ParamConverter("registrationType", class="Bidcoz\Bundle\CoreBundle\Entity\Registration\RegistrationType", options={"id" = "registrationId"})
*/
public function purchaseRegistrationAction(Request $request, Organization $organization, Campaign $campaign, RegistrationType $registrationType)
{
if (!$user = $this->getUser()) {
$this->addFlash('info', 'Please login or create an account before purchasing a registration.');
throw $this->createAccessDeniedException('Unable to access this page!');
}
$proxy = $this->createRegistrationProxy($registrationType, $campaign);
$formOptions = $this->getPurchaseRegistrationFormOptions($campaign, $registrationType, $user);
$form = $this->getPurchaseRegistrationForm($proxy, $formOptions);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user = $this->getUser();
$this->getRegistrationManager()->createRegistrationPurchase($campaign, $user, $proxy);
$this->getEntityManager()->flush();
$this->addFlash('success', 'Registration purchased');
if ('0.00' === $registrationType->getPrice()) {
return $this->redirectToRoute('campaign_home', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
}
return $this->redirectToRoute('account_campaign_purchases', [
'orgSlug' => $organization->getSlug(),
'campaignSlug' => $campaign->getSlug(),
]);
}
return $this->render('@BidcozFrontend/Campaign/Registrations/buy.html.twig', array_merge($formOptions, [
'organization' => $organization,
'campaign' => $campaign,
'registrationType' => $registrationType,
'form' => $form->createView(),
]));
}
protected function createRegistrationProxy(RegistrationType $registrationType, Campaign $campaign)
{
$user = $this->getUser();
$questions = $this->getRepository('Registration\RegistrationQuestion')->findActiveByCampaign($campaign);
$registrationAnswers = array_map(function ($registrationQuestion) use ($user) {
$question = $registrationQuestion->getQuestion();
return $this->getQuestionManager()->createRegistrationAnswer($question, $user);
}, $questions);
$proxy = new RegistrationPurchaseProxy($registrationType);
$proxy->setRegistrationAnswers($registrationAnswers);
return $proxy;
}
protected function getPurchaseRegistrationFormOptions(Campaign $campaign, RegistrationType $registrationType, User $user)
{
$discounts = $this->getRepository('Discount\RegistrationTypeDiscount')->findActiveRegistrationTypeDiscounts($registrationType);
$hasActiveDiscountCode = count($discounts) > 0;
return [
'require_name' => $registrationType->getRequireName(),
'require_address' => $registrationType->getRequireAddress(),
'require_email' => $registrationType->getRequireEmail(),
'require_phone' => $registrationType->getRequirePhone(),
'require_waiver' => $campaign->getRequireRegistrationWaiver(),
'waiver_text' => $campaign->getRegistrationWaiver(),
'user' => $user,
'show_discount_code' => $hasActiveDiscountCode,
// 'cascade_validation' => true,
];
}
protected function getPurchaseRegistrationForm(RegistrationPurchaseProxy $proxy, array $options)
{
return $this->createForm(RegistrationPurchaseType::class, $proxy, $options);
}
}