src/Controller/Tenants/Tenant1/ProfileController.php line 140

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Tenants\Tenant1;
  3. use App\Entity\User;
  4. use App\Exception\reCaptcha3Exception;
  5. use App\Repository\{AuditRepositorySubscriptionRepository};
  6. use App\Services\{OneTimeCodeServiceParameterServicereCaptcha3ValidatorServiceTenantFlowServiceTenantService};
  7. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  8. use Symfony\Component\HttpFoundation\JsonResponse;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\Routing\Annotation\Route;
  11. use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
  12. use Symfony\Component\Security\Core\Security;
  13. use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
  14. class ProfileController extends AbstractController
  15. {
  16.     private $tenant;
  17.     protected $tenantFlowService;
  18.     protected $csrfTokenManager;
  19.     private $auditRepository;
  20.     private $subscriptionRepository;
  21.     private $reCaptcha3ValidatorService;
  22.     private $oneTimeCodeService;
  23.     public function __construct(
  24.         TenantService $tenantService,
  25.         CsrfTokenManagerInterface $csrfTokenManager,
  26.         TenantFlowService $tenantFlowService,
  27.         AuditRepository $auditRepository,
  28.         SubscriptionRepository $subscriptionRepository,
  29.         ParameterService $parameterService,
  30.         reCaptcha3ValidatorService $reCaptcha3ValidatorService,
  31.         OneTimeCodeService $oneTimeCodeService
  32.     ) {
  33.         $this->tenant $tenantService->defineTenant();
  34.         $this->csrfTokenManager $csrfTokenManager;
  35.         $this->tenantFlowService $tenantFlowService;
  36.         $this->auditRepository $auditRepository;
  37.         $this->subscriptionRepository $subscriptionRepository;
  38.         $this->reCaptcha3ValidatorService $reCaptcha3ValidatorService;
  39.         $this->reCaptcha3ValidatorService->setAccess(
  40.             $parameterService->getParameter($this->tenant->getSettingsArrayAssoc()['config'] ?? 'non-existent''reCaptcha3.secretKey'),
  41.             $parameterService->getParameter($this->tenant->getSettingsArrayAssoc()['config'] ?? 'non-existent''reCaptcha3.allowableScore')
  42.         );
  43.         $this->oneTimeCodeService $oneTimeCodeService;
  44.     }
  45.     
  46.     /**
  47.      * @Route("/profile", name="user_profile")
  48.      */
  49.     public function profile(Request $request)
  50.     {
  51.         /** @var User $user */
  52.         $user $this->getUser();
  53.         return $this->render("{$this->tenant->getRootPath()}/pages/profile.html.twig", [
  54.                 'rootPath' => $this->tenant->getRootPath(),
  55.                 'message' => $message ?? '',
  56.                 'user' => $user,
  57.             ]
  58.             + $this->tenantFlowService->prepareTemplateArguments('plans'$this->tenant)
  59.             + $this->tenantFlowService->prepareTemplateArguments('subscription'$this->tenant)
  60.             + $this->tenantFlowService->prepareTemplateArguments('setupIntentClientSecretAndCard'$this->tenant)
  61.             + $this->tenantFlowService->prepareTemplateArguments('shippingAddress'$this->tenant)
  62.             + $this->tenantFlowService->prepareTemplateArguments('charges'$this->tenant)
  63.             + $this->tenantFlowService->prepareTemplateArguments('signUp'$this->tenant)
  64.             + $this->tenantFlowService->prepareTemplateArguments('stripe'$this->tenant)
  65.             + $this->tenantFlowService->prepareTemplateArguments('frequency'$this->tenant)
  66.             + $this->tenantFlowService->prepareTemplateArguments('menu'$this->tenant)
  67.             + $this->tenantFlowService->prepareTemplateArguments('societies'$this->tenant)
  68.         );
  69.     }
  70.     /**
  71.      * @Route("/profile/change/name", name="user_profile_change_name", methods={"POST"})
  72.      * @Route("/profile/change/other", name="user_profile_change_other", methods={"POST"})
  73.      * @Route("/profile/change/shipping", name="user_profile_change_shipping", methods={"POST"})
  74.      * @Route("/profile/change/nameOnCard", name="user_profile_change_name_on_card", methods={"POST"})
  75.      * @Route("/profile/change/press", name="user_profile_change_press", methods={"POST"})
  76.      */
  77.     public function profileChangeInfo(Request $request)
  78.     {
  79.         try {
  80.             /** @var User $user */
  81.             $user $this->getUser();
  82.             if ( $csrf $request->request->get('_csrf_token') ) {
  83.                 switch ($request->get('_route')) {
  84.                     case 'user_profile_change_name':
  85.                         $token 'ChangeName';
  86.                         break;
  87.                     case 'user_profile_change_other':
  88.                         $token 'ChangeOther';
  89.                         break;
  90.                     case 'user_profile_change_shipping':
  91.                         $token 'ShippingAddress';
  92.                         break;
  93.                     case 'user_profile_change_name_on_card':
  94.                         $token 'UpdateCardDetail';
  95.                         break;
  96.                     case 'user_profile_change_press':
  97.                         $token 'PressPlus';
  98.                         break;
  99.                 }
  100.                 if ( ! $this->isCsrfTokenValid($token$csrf) ) {
  101.                     throw new InvalidCsrfTokenException('Invalid CSRF token.');
  102.                 }
  103.                 $this->tenantFlowService->controlUserRequest($user$request);
  104.             }
  105.         } catch (\Exception $exception) {
  106.             $errorMessage $exception->getMessage();
  107.         }
  108.         return new JsonResponse([
  109.             'status' => (!isset($errorMessage)) ? true false ,
  110.             'message' => $errorMessage ?? '',
  111.         ]);
  112.     }
  113.     /**
  114.      * @Route("/profile/update/nameOnCard", name="user_profile_update_name_on_card", methods={"POST"})
  115.      */
  116.     public function profileUpdateNameOnCard(Request $request)
  117.     {
  118.         try {
  119.             /** @var User $user */
  120.             $user $this->getUser();
  121.             $this->tenantFlowService->controlUserRequest($user$request);
  122.         } catch (\Exception $exception) {
  123.             $errorMessage $exception->getMessage();
  124.         }
  125.         return new JsonResponse([
  126.             'status' => (!isset($errorMessage)) ? true false ,
  127.             'message' => $errorMessage ?? '',
  128.         ]);
  129.     }
  130.     /**
  131.      * @Route("/profile/password", name="user_password")
  132.      */
  133.     public function profilePassword(Request $request)
  134.     {
  135.         try {
  136.             if ( 'GET' == $request->getMethod() ) {
  137.                 $user $this->oneTimeCodeService->findUserByCode($this->tenant$request->query->get('code'));
  138.                 if (is_null($user)) return $this->redirectToRoute('user_sign_in');
  139.             } elseif ( 'POST' == $request->getMethod() && $csrf $request->request->get('_csrf_token') ) {
  140.                 if ( ! $this->isCsrfTokenValid('ChangePassword'$csrf) ) {
  141.                     throw new InvalidCsrfTokenException('Invalid CSRF token.');
  142.                 }
  143.                 $this->reCaptcha3ValidatorService->setToken($request->request->get('reCAPTCHA_token'));
  144.                 if ($this->reCaptcha3ValidatorService->validate()) {
  145.                     throw new reCaptcha3Exception('reCaptcha3 validation failed.');
  146.                 }
  147.                 $user $this->oneTimeCodeService->findUserByCode($this->tenant$request->request->get('code'));
  148.                 return $this->tenantFlowService->controlUserRequest($user$request);
  149.             }
  150.         } catch (\Exception $exception) {
  151.             $message $exception->getMessage();
  152.         }
  153.         return $this->render("{$this->tenant->getRootPath()}/pages/profile-password.html.twig", [
  154.             'rootPath' => $this->tenant->getRootPath(),
  155.             'message' => $message ?? '',
  156.             'activeTab' => 'password',
  157.             'user' => $user,
  158.         ]
  159.             + $this->tenantFlowService->prepareTemplateArguments('signUp'$this->tenant)
  160.             + $this->tenantFlowService->prepareTemplateArguments('menu'$this->tenant)
  161.         );
  162.     }
  163.     /**
  164.      * @Route("/profile/change/password", name="user_profile_change_password", methods={"POST"})
  165.      */
  166.     public function changePassword(Request $request)
  167.     {
  168.         try {
  169.             /** @var User $user */
  170.             $user $this->getUser();
  171.             if ( 'POST' == $request->getMethod() && $csrf $request->request->get('_csrf_token') ) {
  172.                 if ( ! $this->isCsrfTokenValid('ChangePassword'$csrf) ) {
  173.                     throw new InvalidCsrfTokenException('Invalid CSRF token.');
  174.                 }
  175.                 $this->tenantFlowService->controlUserRequest($user$request);
  176.             }
  177.         } catch (\Exception $exception) {
  178.             $errorMessage $exception->getMessage();
  179.         }
  180.         return new JsonResponse([
  181.             'status' => (!isset($errorMessage)) ? true false ,
  182.             'message' => $errorMessage ?? '',
  183.         ]);
  184.     }
  185.     /**
  186.      * @Route("/profile/forgot/password", name="user_profile_forgot_password", methods={"POST"})
  187.      */
  188.     public function forgotPassword(Request $request)
  189.     {
  190.         try {
  191.             /** @var User $user */
  192.             $user $this->getUser();
  193.             if ( 'POST' == $request->getMethod() && $csrf $request->request->get('_csrf_token') ) {
  194.                 if ( ! $this->isCsrfTokenValid('ForgotPassword'$csrf) ) {
  195.                     throw new InvalidCsrfTokenException('Invalid CSRF token.');
  196.                 }
  197.                 $this->tenantFlowService->controlUserRequest($user$request);
  198.             }
  199.         } catch (\Exception $exception) {
  200.             $errorMessage $exception->getMessage();
  201.         }
  202.         return new JsonResponse([
  203.             'status' => (!isset($errorMessage)) ? true false ,
  204.             'message' => $errorMessage ?? '',
  205.         ]);
  206.     }
  207.     /**
  208.      * @Route("/profile/subscription/cancel", name="profile_subscription_cancel", methods={"POST"})
  209.      */
  210.     public function profileSubscriptionCancel(Request $request)
  211.     {
  212.         try {
  213.             /** @var User $user */
  214.             $user $this->getUser();
  215.             if ( 'POST' == $request->getMethod() && $csrf $request->request->get('_csrf_token') ) {
  216.                 if ( ! $this->isCsrfTokenValid('SubscriptionCancel'$csrf) ) {
  217.                     throw new InvalidCsrfTokenException('Invalid CSRF token.');
  218.                 }
  219.                 $this->tenantFlowService->controlUserRequest($user$request);
  220.             }
  221.         } catch (\Exception $exception) {
  222.             $errorMessage $exception->getMessage();
  223.         }
  224.         $data = [
  225.             'planHtml' => $this->refreshPlan(),
  226.             'popupHtml' => $this->renderPopup('renew')
  227.         ];
  228.         return new JsonResponse([
  229.             'status'    => (!isset($errorMessage)) ? true false ,
  230.             'data'      => (!isset($errorMessage)) ? $data '' ,
  231.             'message'   => $errorMessage ?? '',
  232.         ]);
  233.     }
  234.     /**
  235.      * @Route("/profile/subscription/upgrade", name="profile_subscription_upgrade", methods={"POST"})
  236.      */
  237.     public function profileSubscriptionUpgrade(Request $request)
  238.     {
  239.         try {
  240.             /** @var User $user */
  241.             $user $this->getUser();
  242.             if ( 'POST' == $request->getMethod() && $csrf $request->request->get('_csrf_token') ) {
  243.                 if ( ! $this->isCsrfTokenValid('SubscriptionUpgrade'$csrf) ) {
  244.                     throw new InvalidCsrfTokenException('Invalid CSRF token.');
  245.                 }
  246.                 $this->tenantFlowService->controlUserRequest($user$request);
  247.             }
  248.         } catch (\Exception $exception) {
  249.             $errorMessage $exception->getMessage();
  250.         }
  251.         return new JsonResponse([
  252.             'status'    => (!isset($errorMessage)) ? true false ,
  253.             'data'      => (!isset($errorMessage)) ? $this->refreshPlan() : '' ,
  254.             'message'   => $errorMessage ?? '',
  255.         ]);
  256.     }
  257.     /**
  258.      * @Route("/profile/check-updates", name="profile_check_updates", methods={"POST"})
  259.      */
  260.     public function profileCheckUpdates(Request $request)
  261.     {
  262.         switch ($request->request->get('webhook')) {
  263.             case 'setup_intent.succeeded':
  264.                 $flowName 'WEBHOOK_SETUP_INTENT_SUCCEEDED';
  265.                 $flowAction 'WEBHOOK_SETUP_INTENT_UPDATE_DEFAULT_METHOD';
  266.                 break;
  267.             case 'charge.succeeded':
  268.                 $flowName 'CONFIRM_USER_IS_PREMIUM_ONETIME_BY_WEBHOOK';
  269.                 $flowAction 'UPDATE_USER_FIELDS';
  270.                 break;
  271.             case 'invoice.payment_succeeded':
  272.                 $flowName 'CONFIRM_USER_IS_PREMIUM_SUBSCRIPTION_BY_WEBHOOK';
  273.                 $flowAction 'UPDATE_USER_FIELDS';
  274.                 break;
  275.         }
  276.         $user $this->getUser();
  277.         $checking $this->auditRepository->checkUpdates(
  278.             $user,
  279.             $flowName,
  280.             $flowAction,
  281.             $request->request->get('input')
  282.         );
  283.         $data null;
  284.         if (!is_null($checking)) {
  285.             if ($request->request->get('webhook') == 'setup_intent.succeeded') {
  286.                 $data json_decode($checking->getOutput(), 1);
  287.             } else {
  288.                 $setupIntentClientSecretAndCard $this->tenantFlowService->prepareTemplateArguments('setupIntentClientSecretAndCard'$this->tenant);
  289.                 $data = [
  290.                     'planHtml' => $this->refreshPlan(),
  291.                     'setupIntentClientSecretAndCard' => $setupIntentClientSecretAndCard,
  292.                     'cardDetailsHtml' => $this->refreshCardDetails($setupIntentClientSecretAndCard),
  293.                     'popupDiscontinue' => $this->renderPopup('discontinue'),
  294.                     'popupUpgrade' => $this->renderPopup('upgrade'),
  295.                     'popupPremium' => $this->renderPopup('renew'),
  296.                 ];
  297.             }
  298.         }
  299.         $subscription null;
  300.         if ($request->request->get('webhook') == 'invoice.payment_succeeded') {
  301.             $subscription = (!is_null($checking)) 
  302.                 ? \json_decode($checking->getOutput(), 1
  303.                 : null
  304.             ;
  305.             if (!is_null($subscription)) {
  306.                 $subscriptionEntity $this->subscriptionRepository->findOneBy(['externalId' => $subscription['subscriptionId']]);
  307.             }
  308.         }
  309.         $responseData = [
  310.             'status'            => (!is_null($checking)) ? true false,
  311.             'data'              => $data,
  312.             'subscription'      => $subscription,
  313.             'plan'              => $user->getFieldsArrayAssoc()['chosenPlan'] ?? '',
  314.         ];
  315.         if (isset($subscriptionEntity)) {
  316.             switch ($subscriptionEntity->getFrequency()) {
  317.                 case 'MONTHLY':
  318.                     $frequency 'month';
  319.                     break;
  320.                 
  321.                 case 'ANNUALLY':
  322.                     $frequency 'year';
  323.                     break;
  324.                 
  325.                 default:
  326.                     $frequency '';
  327.                     break;
  328.             }
  329.             $responseData['frequency'] = $frequency;
  330.             $responseData['amount'] = $subscriptionEntity->getRecurringChargeAmount();
  331.         }
  332.         return new JsonResponse($responseData);
  333.     }
  334.     public function refreshPlan()
  335.     {
  336.         return $this->renderView("tenants/tenant1/parts/plan.html.twig", [
  337.                 'user' => $this->getUser(),
  338.             ]
  339.             + $this->tenantFlowService->prepareTemplateArguments('plans'$this->tenant)
  340.             + $this->tenantFlowService->prepareTemplateArguments('subscription'$this->tenant)
  341.             + $this->tenantFlowService->prepareTemplateArguments('societies'$this->tenant)
  342.         );
  343.     }
  344.     public function refreshCardDetails($setupIntentClientSecretAndCard)
  345.     {
  346.         return $this->renderView("tenants/tenant1/parts/cardDetails.html.twig", [
  347.                 'user' => $this->getUser(),
  348.             ]
  349.             + $setupIntentClientSecretAndCard
  350.             $this->tenantFlowService->prepareTemplateArguments('subscription'$this->tenant)
  351.         );
  352.     }
  353.     public function renderPopup(string $type)
  354.     {
  355.         switch ($type) {
  356.             case 'renew':
  357.                 return $this->renderView("tenants/tenant1/parts/planInGracePeriodDialog.html.twig", [
  358.                         'user' => $this->getUser(),
  359.                         'route' => 'user_profile'
  360.                     ]
  361.                     + $this->tenantFlowService->prepareTemplateArguments('frequency'$this->tenant)
  362.                     + $this->tenantFlowService->prepareTemplateArguments('countries'$this->tenant)
  363.                 );
  364.             
  365.             case 'discontinue':
  366.                 return $this->renderView("tenants/tenant1/parts/subscriptionCancelationDialog.html.twig", [
  367.                         'user' => $this->getUser(),
  368.                         'route' => 'user_profile'
  369.                     ]
  370.                     + $this->tenantFlowService->prepareTemplateArguments('subscription'$this->tenant)
  371.                 );
  372.             
  373.             case 'upgrade':
  374.                 return $this->renderView("tenants/tenant1/parts/UpgradePlanDialog.html.twig", [
  375.                         'user' => $this->getUser(),
  376.                         'route' => 'user_profile'
  377.                     ]
  378.                     + $this->tenantFlowService->prepareTemplateArguments('subscription'$this->tenant)
  379.                     + $this->tenantFlowService->prepareTemplateArguments('frequency'$this->tenant)
  380.                 );
  381.             
  382.             default:
  383.                 // code...
  384.                 break;
  385.         }
  386.     }
  387.     /**
  388.      * @Route("/user/getInfo", name="user_get_info", methods={"GET"})
  389.      */
  390.     public function userGetInfo()
  391.     {
  392.         $user $this->getUser();
  393.         if (!$user) {
  394.             return new JsonResponse([
  395.                 'error' => 'general',
  396.                 'message' => 'Error: An unexpected error has occurred. Please refresh the page or try again later.'
  397.             ], 401);
  398.         }
  399.         return new JsonResponse(
  400.             [
  401.                 'id'        => $user->getId(),
  402.                 'email'     => $user->getEmail(),
  403.                 'firstName' => $user->getFieldsArrayAssoc()['firstName'] ?? '',
  404.                 'lastName'  => $user->getFieldsArrayAssoc()['lastName'] ?? '',
  405.                 'status'    => $user->getStatus(),
  406.             ]
  407.         );
  408.     }
  409. }