<?php
namespace App\Controller;
use App\Components\PaymentStatus;
use App\Entity\Account;
use App\Entity\Payment;
use App\Entity\Plan;
use App\Paypal\PaypalHandler;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class PlanController extends AbstractController
{
private $paypalHandler;
/**
* PlanController constructor.
* @param $paypalHandler
*/
public function __construct(PaypalHandler $paypalHandler)
{
$this->paypalHandler = $paypalHandler;
}
/**
* @return Response
*
* @Route("/plans", name="plans_redirect")
*/
public function redirectPlans(): Response
{
return $this->redirectToRoute("pricing", [], Response::HTTP_MOVED_PERMANENTLY);
}
/**
* @Route("/pricing", name="pricing")
*/
public function index(): Response
{
$plans = $this->getDoctrine()->getRepository(Plan::class)->findBy([
'version' => 2,
'show' => 1
], ['price' => 'DESC']);
return $this->render('plans/index.html.twig', [
'plans' => $plans,
]);
}
/**
* @return Response
*
* @Route("/account/plans", name="account_plans")
*/
public function accountPlans(): Response
{
/** @var Account $user */
$user = $this->getDoctrine()->getRepository(Account::class)->findOneByEmail($this->getUser()->getUsername());
/** @var Plan[] $plans */
$plans = $this->getDoctrine()->getRepository(Plan::class)->findBy([
'version' => 2,
'show' => 1
], ['price' => 'DESC']);
return $this->render('plans/account_plans.html.twig', [
'plans' => $plans,
'user' => $user
]);
}
/**
* @return Response
*
* @Route("/account/plans/cancel", name="account_plans_cancel")
*/
public function cancelPlan(): Response
{
/** @var Account $user */
$user = $this->getDoctrine()->getRepository(Account::class)->findOneByEmail($this->getUser()->getUsername());
/** @var Payment $payment */
$payment = $this->getDoctrine()->getRepository(Payment::class)->findBy(['account' => $user],
['created' => 'DESC'], 1)[0];
// Get the Paypal Auth Token
$authToken = $this->paypalHandler->getAuthToken();
if (!$authToken) {
$this->addFlash("flash_error", "Unable to connect to Paypal at this time.");
return $this->redirectToRoute("account_plans");
}
// With the Auth token cancel the plan
$cancelSubscription = $this->paypalHandler->cancelSubscription($payment, $authToken);
if (!$cancelSubscription) {
$this->addFlash("flash_error", "Unable to cancel current plan with Paypal. Please try again.");
return $this->redirectToRoute("account_plans");
}
$plan = $this->getDoctrine()->getRepository(Plan::class)->findOneBy([
'version' => 2,
'name' => 'Starter'
]);
$user->setPlan($plan);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return $this->redirectToRoute("account_plans");
}
/**
* @param Request $request
* @param Plan $plan
* @return Response
*
* @Route("/account/plans/{plan}", name="account_plans_create")
*/
public function selectPlan(Request $request, Plan $plan): JsonResponse
{
/** @var Account $user */
$user = $this->getDoctrine()->getRepository(Account::class)->findOneByEmail($this->getUser()->getUsername());
try {
$payment = new Payment($request->get('subscriptionID'), PaymentStatus::INITIALIZED, $user, $plan);
if ($request->get('billingToken')) {
$payment->setBillingToken($request->get('billingToken'));
}
if ($request->get('orderID')) {
$payment->setOrderId($request->get('orderID'));
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($payment);
// Update to set the new plan
$user->setPlan($plan);
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash("flash_success", "Thank you! Your plan is now active on your account.");
return new JsonResponse("Successfully stored");
} catch (\Exception $e) {
$this->addFlash("flash_error", "Unable to activate this plan on your account.");
return new JsonResponse(
sprintf("Unable to complete request: %s", $e->getMessage()),
Response::HTTP_INTERNAL_SERVER_ERROR
);
}
}
}