<?php
namespace App\Controller;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Form\FormError;
use Stripe\Stripe;
use Stripe\PaymentIntent;
use App\Form\Type\ParticipantFormType;
use App\Entity\Competition;
use App\Entity\Participant;
class FrontendCompetitionController extends AbstractController {
/**
* @Route("/competition/{slug}", name="competition")
*/
public function single(EntityManagerInterface $em, Request $request, $slug) {
$competition = $em->getRepository(Competition::class)->findOneBy(['slug' => $slug]);
if (null === $competition) {
return $this->redirectToRoute('events');
}
$participant = new Participant();
$form = $this->createForm(ParticipantFormType::class, $participant, ['minimum_down_payment' => $competition->getMinimumDownPayment()]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$recaptchaResponse = $request->get('g-recaptcha-response');
if ($this->captchaVerify($recaptchaResponse) == true) {
$participant->setCompetition($competition);
// save changes to db
$em->persist($participant);
$em->flush();
// redirect to listing page
return $this->redirectToRoute('competition_payment', ['slug' => $slug, 'hash' => $participant->getHash()]);
} else {
$form->get('downPaymentAmount')->addError(new FormError('Invalid reCaptcha'));
}
}
return $this->render('frontend/competition/single.html.twig', [
'competition' => $competition,
'form' => $form->createView()
]);
}
/**
* @Route("/competition/{slug}/payment/{hash}", name="competition_payment")
*/
public function payment(EntityManagerInterface $em, Request $request, $slug, $hash) {
$competition = $em->getRepository(Competition::class)->findOneBy(['slug' => $slug]);
if (null === $competition) {
return $this->redirectToRoute('events');
}
$participant = $em->getRepository(Participant::class)->findOneBy(['hash' => $hash]);
if (null === $participant) {
return $this->redirectToRoute('competition', ['slug' => $slug]);
}
if (!$participant->isPaymentPending()) {
return $this->redirectToRoute('competition', ['slug' => $slug]);
}
// Stripe config
Stripe::setApiKey($this->getParameter('stripe_secret_key'));
// send payment intent request
try {
$amount = $participant->getDownPaymentAmount();
$intent = PaymentIntent::create([
'amount' => floatval($amount * 100),
'currency' => 'USD',
'payment_method_types' => ['card'],
'metadata' => [
'payment_hash' => $hash
]
]);
} catch (\Exception $e) {
$this->get('session')->getFlashBag()->set('danger', $e->getMessage());
return $this->redirectToRoute('competition', ['slug' => $slug]);
}
return $this->render('frontend/competition/payment.html.twig', [
'competition' => $competition,
'participant' => $participant,
'client_secret' => $intent->client_secret,
'publishable_key' => $this->getParameter('stripe_publishable_key'),
'amount' => $amount,
'home' => $this->generateUrl('homepage', ['registered' => 1], UrlGeneratorInterface::ABSOLUTE_URL)
]);
}
/**
* Validate reCaptcha
*
* @param $recaptcha
* @return mixed
*/
private function captchaVerify($recaptcha) {
$url = "https://www.google.com/recaptcha/api/siteverify";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
"secret" => $this->getParameter('recaptcha_secret_key'),
"response" => $recaptcha
)
);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response);
if (JSON_ERROR_NONE !== json_last_error()) {
return false;
}
return $data->success;
}
}