<?php
namespace App\Controller;
use App\Entity\Order;
use App\Entity\Payment;
use App\Entity\User;
use App\Form\User\ActivationFeeType;
use App\Form\User\GetStartedType;
use App\Service\Api\StripeApi;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class RegisterController extends AbstractController
{
//const ACTIVATION_FEE_PER_RESTAURANT = 1200;
const ACTIVATION_FEE_PER_RESTAURANT = 0;
#[Route(path: '/get-started', name: 'register', methods: ['POST', 'GET'])]
public function index(Request $request, UserPasswordHasherInterface $encoder): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('default');
}
$user = null;
if ($request->request->has('get_started')) {
$r = $request->request->get('get_started');
if (isset($r['email'])) {
$user = $this->getDoctrine()->getRepository(User::class)
->findOneBy(['email'=>$r['email']]);
if ($user && $user->getState()!=User::STATE_PAYMENT) {
$user=null;
}
}
}
if (!$user) {
$user = new User();
$user
->setManager(null)
->setState(User::STATE_PAYMENT);
}
$form = $this->createForm(GetStartedType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setPassword($encoder->hashPassword(
$user,
sha1($user->getId().random_bytes(5))
));
try {
$user->addRole('ROLE_ADMIN_USER');
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('register_subscription',['id'=>$user->getId()]);
} catch (\Exception $e) {
$this->addFlash('danger','It looks like you already have an account in REMS');
}
}
return $this->render('register/index.html.twig', [
'controller_name' => self::class,
'user' => $user,
'form' => $form->createView(),
]);
}
#[Route(path: '/get-started/subscription/{id}', name: 'register_subscription', methods: ['POST', 'GET'])]
#[Route(path: '/get-started/subscription/{id}/{token}', name: 'register_subscription_retry', methods: ['POST', 'GET'])]
public function requestActivationFee(Request $request, User $user, StripeApi $stripeApi, string $token=''):Response
{
$order = null;
if ($request->attributes->get('_route')=='register_subscription_retry') {
$order = $this->getDoctrine()->getRepository(Order::class)
->findOneBy(['token'=>$token]);
}
if (!$order) {
$order = new Order();
$order
->setUser($user)
->setState(Order::STATE_CART)
->setAmount($user->getMaxRestaurantsCount() * self::ACTIVATION_FEE_PER_RESTAURANT)
->setMemo('Activation fee. '.$user->getMaxRestaurantsCount().' restaurant(s)');
}
if ($order->getState()==Order::STATE_PAID) {
//
}
$form = $this->createForm(ActivationFeeType::class, $order);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$order->setState(Order::STATE_WAITING);
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
$stripeApi->initializeClient();
$stripeApi->createSession($order);
if ($order->getAmount()==0) {
$order->setState(Order::STATE_PAID);
$order->setToken('');
$order->getUser()->setState(User::STATE_PENDING);
$this->getDoctrine()->getManager()->persist($order->getUser());
$this->getDoctrine()->getManager()->persist($order);
$this->getDoctrine()->getManager()->flush();
//ToDo: send notification
return $this->redirectToRoute('register-thanks');
}
if ($order->getPayments()->last()->getState()!=Payment::SESSION_CREATED) {
$this->addFlash('danger', 'Failed to create payment session. Please try again or contact our support team.');
return $this->redirectToRoute('register_subscription_retry', ['id'=>$user->getId(),'token'=>$order->getToken()]);
}
return $this->render('register/payment.html.twig', [
'order' => $order
]);
}
return $this->render('register/confirmActivation.html.twig', [
'controller_name' => self::class,
'user' => $user,
'order' => $order,
'form' => $form->createView()
]);
}
#[Route(path: '/get-started/success/{token}', name: 'register_payment_success')]
public function paymentCapture(Request $request, string $token, StripeApi $stripeApi): Response
{
$order = $this->getDoctrine()->getRepository(Order::class)
->findOneBy(['token'=>$token]);
if (!$order) {
$this->addFlash('danger', 'Something went wrong. System is not able to locate your purchase order.');
return $this->redirectToRoute('register');
}
$stripeApi->initializeClient();
$stripeApi->retrieveSession($order);
if ($order->getState()!=Order::STATE_PAID) {
$this->addFlash('danger', 'Payment failed! Unfortunately something went wrong during payment. You haven\'t been charged. Please try again.');
return $this->redirectToRoute('register_subscription_retry', ['id'=>$order->getUser()->getId()]);
}
$order->getUser()->setState(User::STATE_PENDING);
$order->setToken('');
$this->getDoctrine()->getManager()->persist($order->getUser());
$this->getDoctrine()->getManager()->persist($order);
$this->getDoctrine()->getManager()->flush();
//ToDo: send notification
return $this->redirectToRoute('register-thanks');
}
#[Route(path: '/get-started/cancel/{token}', name: 'register_payment_cancel')]
public function paymentCancel(Request $request, string $token): Response
{
$this->addFlash('warning', 'Payment cancelled! You haven\'t been charged. You can try again payment again.');
$order = $this->getDoctrine()->getRepository(Order::class)
->findOneBy(['token'=>$token]);
if (!$order) {
$this->addFlash('danger', 'Something went wrong. System is not able to locate your purchase order.');
return $this->redirectToRoute('register');
}
$order->setState(Order::STATE_CANCELLED);
$order->getPayments()->last()->setState(Payment::STATE_CANCEL);
$this->getDoctrine()->getManager()->persist($order);
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('register_subscription_retry', ['id'=>$order->getUser()->getId()]);
}
#[Route(path: '/get-started/thank-you', name: 'register-thanks')]
public function thankYou(Request $request): Response
{
if ($this->getUser()) {
return $this->redirectToRoute('default');
}
return $this->render('register/thankyou.html.twig', [
'controller_name' => 'RegisterController',
]);
}
}