src/Controller/FrontController.php line 171

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Service\SessionManagerLMDV;
  4. use App\Service\SessionManagerLMDVInterface;
  5. use App\Service\WebServiceLMDV;
  6. use App\Service\WebServiceLMDVInterface;
  7. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  8. use Symfony\Component\Routing\Annotation\Route;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpFoundation\RequestStack;
  11. use Psr\Log\LoggerInterface;
  12. use Symfony\Component\Finder\Exception\AccessDeniedException;
  13. use Symfony\Contracts\Translation\TranslatorInterface;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\HttpKernel\KernelInterface;
  16. use App\ValueObject\Flight;
  17. use App\ValueObject\Money;
  18. use App\Exception\LMDVException;
  19. use App\Exception\NonTranslatedExceptionInterface;
  20. use App\Exception\NonTranslatedException;
  21. use App\Service\SalesForceConnectorInterface;
  22. use Symfony\Component\Console\Input\ArrayInput;
  23. use Symfony\Component\Console\Output\BufferedOutput;
  24. use Symfony\Bundle\FrameworkBundle\Console\Application;
  25. use App\Exception\WebServiceException;
  26. /**
  27.  * This class has only one route "/" (front) which is the entry-point for all the LMDV forms.
  28.  * It inspects the query string parameters in order to take a decision over which LMDV form
  29.  * we must head on (GIRDirectAgence, GIRDirectMail, GIRDistrib, GIRResaWeb, GRPFactIndivAgence,
  30.  * GRPFactIndivMail, GRPFactIndivWeb).
  31.  *
  32.  * @author jra
  33.  *
  34.  */
  35. class FrontController extends AbstractController
  36. {
  37.   
  38.   use LMDVControllerTrait;
  39.   
  40.   public const PARAM_AGENCE_EMAIL_GIR 'gir';
  41.   public const PARAM_AGENCE_EMAIL_GRP 'grp';
  42.   public const STATUS_REVISON 'Révision';
  43.   public const STATUS_ACCORD_CLIENT 'Accord client';
  44.   public const STATUS_CARNET_VOYAGE 'Carnet de Voyage';
  45.   public const STATUS_SANS_SUITE 'Sans suite';
  46.   public const STATUS_ANNULEE 'Annulée';
  47.   public const STATUS_ARCHIVEE 'Archivée';
  48.   public const BLOCKED_OPP_STATUS = [
  49.       self::STATUS_REVISON,
  50.       self::STATUS_ACCORD_CLIENT,
  51.       self::STATUS_CARNET_VOYAGE,
  52.       self::STATUS_SANS_SUITE,
  53.       self::STATUS_ANNULEE,
  54.       self::STATUS_ARCHIVEE
  55.   ];
  56.   /**
  57.    * @var \App\Service\WebServiceLMDV
  58.    */
  59.   protected $ws;
  60.   /**
  61.    * @var \App\Service\SessionManagerLMDV
  62.    */
  63.   protected $sm;
  64.   /**
  65.    * @var \Symfony\Component\HttpFoundation\Request
  66.    */
  67.   protected $request;
  68.   /**
  69.    * @var \Psr\Log\LoggerInterface
  70.    */
  71.   protected $logger;
  72.   /**
  73.    * @var \Symfony\Contracts\Translation\TranslatorInterface
  74.    */
  75.   protected $translator;
  76.   /**
  77.    * Dependency injection.
  78.    *
  79.    * @param \App\Service\WebServiceLMDVInterface $ws
  80.    * @param \App\Service\SessionManagerLMDVInterface $sm
  81.    */
  82.   public function __construct(RequestStack $request_stackWebServiceLMDVInterface $wsSessionManagerLMDVInterface $smLoggerInterface $loggerTranslatorInterface $translator) {
  83.     $this->request $request_stack->getCurrentRequest();
  84.     $this->ws $ws;
  85.     $this->sm $sm;
  86.     $this->logger $logger;
  87.     $this->translator $translator;
  88.   }
  89.    /**
  90.    * Utility url to clear all caches. Only for DEV/TEST environments
  91.    *
  92.    * @Route("/clear-cache", name="clearCache")
  93.    *
  94.    */
  95.   public function clearCache(SalesForceConnectorInterface $sfKernelInterface $kernel) {
  96.     if(in_array($_ENV['APP_ENV'], ['dev''test'])) {
  97.       // Clean up old session information every time we arrive to this dispatcher.
  98.       // We migrate the session to obtain a new sess_id() which invalidates WS caches.
  99.       $this->request->getSession()->clear();
  100.       $this->request->getSession()->migrate(TRUE);
  101.       // Clear all WS caches
  102.       $sf->invalidateAllCaches();
  103.       // Clear Twig cache like "symfony console cache:clear" does. Note that the cache
  104.       // directory will not be completely empty because after this command is executed,
  105.       // we need to create a Twig template for the final render.
  106.       // @see : https://symfony.com/doc/current/console/command_in_controller.html
  107.       $application = new Application($kernel);
  108.       $application->setAutoExit(false);
  109.       $input = new ArrayInput([
  110.           'command' => 'cache:clear',
  111.           '--no-warmup' => TRUE
  112.       ]);
  113.       $output = new BufferedOutput();
  114.       $application->run($input$output);
  115.       $content $output->fetch();
  116.       $this->logger->error("clear-cache controller output", ['message' => $content]);
  117.       $content array_filter(explode("\n"$content));
  118.       $content array_pop($content);
  119.       // Renders error page
  120.       return $this->render('lmdv/error_page.html.twig', [
  121.           'label' => 'error.clear_cache',
  122.           'errorMsg' => $content
  123.       ], new Response(''400));
  124.     }
  125.     else {
  126.       return $this->redirectToRoute('front');
  127.     }
  128.   }
  129.   /**
  130.    * Controller that decides to which tunnel head in. The first thing that this controller does
  131.    * is to empty the $_SESSION, in order to clean up all previous stored information.
  132.    *
  133.    * @Route("/", name="front")
  134.    *
  135.    * @param Request $request
  136.    * @param WebServiceLMDVInterface $ws
  137.    * @param SessionManagerLMDVInterface $sm
  138.    * @return \Symfony\Component\HttpFoundation\Response|\Symfony\Component\HttpFoundation\RedirectResponse
  139.    */
  140.   public function front() {
  141.     // Generates namespace for all the session values using a timestamp
  142.     $timestamp = (string)microtime(true);
  143.     $this->request->getSession()->setNamespace($timestamp);
  144.     // Grab $_GET parameters and save them into the session
  145.     $this->sm->setExternalParametersIntoSession($timestamp);
  146.     $session $this->request->getSession();
  147.     // Invalidates (old) session data if the timestamp value exists in the url
  148.     if($this->request->query->get('_ts')) {
  149.       $session->invalidateNamespace($this->request->query->get('_ts'));
  150.     }
  151.     $id_opp $session->get('idOppSF');
  152.     if(! $id_opp) {
  153.     /////////////////////////////////////////////
  154.       // There is *not* an idOppSF, then :
  155.       /////////////////////////////////////////////
  156.       $businessCode $session->get('businessCode');
  157.       $productCode $session->get('productCode');
  158.       $departureDate $session->get('departureDate');
  159.       $endDate $session->get('endDate');
  160.       $departureCity $session->get('departureCity');
  161.       if($businessCode) {
  162.         if($productCode && $departureDate && $endDate && $departureCity) {
  163.           // CAS 3 (DISTRIB slide 1.4/ le vendeur Marco Vasco fait une réservation)
  164.           return $this->redirectToRoute('girdistrib_step0', \array_merge($this->request->query->all(), ['_fragment' => 'breadcrumb''_ts' => $timestamp]));
  165.         }
  166.       }
  167.       else {
  168.         if($productCode && $departureDate && $endDate && $departureCity) {
  169.           // CAS 1 (RESAWEB slide 1.3/ le client réserve tout seul en ligne)
  170.           return $this->redirectToRoute('girresaweb_step0', \array_merge($this->request->query->all(), ['_fragment' => 'breadcrumb''_ts' => $timestamp]));
  171.         }
  172.       }
  173.     }
  174.     else {
  175.       ////////////////////////////////////
  176.       // If there is an idOppSF, then :
  177.       ////////////////////////////////////
  178.       try {
  179.         $isOppFille $this->ws->isOpportunityFille($id_opp);
  180.         if($isOppFille) {
  181.           // This is a FILLE opportunity - type GRP
  182.           if($this->request->query->get('agence_email') == self::PARAM_AGENCE_EMAIL_GRP) {
  183.             // FACTINDIV Mail
  184.             $this->ws->getSalesForceDataIntoSession($id_opp$this->ws::TYPE_OPP_FILLETRUE);
  185.             $status $session->get('stageName');
  186.             if(! $this->isValidStatusOppMail($status)) {
  187.               throw new \Exception($this->translator->trans("error.opportunity.invalid_status", ['status' => $status]), LMDVException::ERROR_BAD_OPP_STATUS);
  188.             }
  189.             return $this->redirectToRoute('grpfactindivmail_step0', \array_merge($this->request->query->all(), ['_fragment' => 'breadcrumb''_ts' => $timestamp]));
  190.           }
  191.           elseif($this->ws->isAgent()
  192.               || (in_array($_ENV['APP_ENV'], ['dev''test']) && $this->request->query->get('test_agence'))) {
  193.             // FACTINDIV Agence
  194.             $this->ws->getSalesForceDataIntoSession($id_opp$this->ws::TYPE_OPP_FILLETRUE);
  195.             $status $session->get('stageName');
  196.             if($status != self::STATUS_ACCORD_CLIENT) {
  197.               throw new \Exception($this->translator->trans("error.opportunity.invalid_status", ['status' => $status]));
  198.             }
  199.             return $this->redirectToRoute('grpfactindivagence_step0', \array_merge($this->request->query->all(), ['_fragment' => 'breadcrumb''_ts' => $timestamp]));
  200.           }
  201.           else {
  202.             $this->logger->error("IP check error GRP: clientIP : '" $this->request->getClientIp() + "', agenceIp : '" $_ENV['IP_ADDRESS_AGENCE'] + "'");
  203.           }
  204.         }
  205.         else {
  206.           // This is a GRP PARENT opportunity (or a GIR opportunity - that have no PARENTs).
  207.           if($this->request->query->get('agence_email') == self::PARAM_AGENCE_EMAIL_GIR) {
  208.             // DIRECT Mail
  209.             $this->ws->getSalesForceDataIntoSession($id_opp$this->ws::TYPE_OPP_PARENTFALSE);
  210.             $session->set('businessCode'''); // Eric - Gautier 12/02/2021 : don't send businessCode in this case.
  211.             $status $session->get('stageName');
  212.             if(! $this->isValidStatusOppMail($status)) {
  213.               throw new \Exception($this->translator->trans("error.opportunity.invalid_status", ['status' => $status]), LMDVException::ERROR_BAD_OPP_STATUS);
  214.             }
  215.             return $this->redirectToRoute('girdirectmail_step0', \array_merge($this->request->query->all(), ['_fragment' => 'breadcrumb''_ts' => $timestamp]));
  216.           }
  217.           else {
  218.             $productCode $session->get('productCode');
  219.             $departureDate $session->get('departureDate');
  220.             if($productCode && $departureDate) {
  221.               // FACTINDIV Web : we need to retrive the businessCode from the opp PARENT
  222.               $this->ws->getSalesForceDataIntoSession($id_opp,  $this->ws::TYPE_OPP_PARENTTRUE);
  223.               $status $session->get('stageName');
  224.               if($status != self::STATUS_ACCORD_CLIENT) {
  225.                 throw new \Exception($this->translator->trans("error.opportunity.invalid_status", ['status' => $status]));
  226.               }
  227.               // NOTE: In this case we must create the opp FILLE at the end of the tunnel with createBooking
  228.               //       so we must empty the FILLE and set the PARENT opp.
  229.               $session->set('idOppSFParent'$session->get('idOppSF'));
  230.               $session->set('idOppSF'NULL);
  231.               return $this->redirectToRoute('grpfactindivweb_step0', \array_merge($this->request->query->all(), ['_fragment' => 'breadcrumb''_ts' => $timestamp]));
  232.             }
  233.             elseif($this->ws->isAgent()
  234.               || (in_array($_ENV['APP_ENV'], ['dev''test']) && $this->request->query->get('test_agence'))) {
  235.               // DIRECT Agence
  236.               $this->ws->getSalesForceDataIntoSession($id_opp,  $this->ws::TYPE_OPP_PARENTFALSE);
  237.               $session->set('businessCode'''); // Eric - Gautier 12/02/2021 : don't send businessCode in this case.
  238.               return $this->redirectToRoute('girdirectagence_step0', \array_merge($this->request->query->all(), ['_fragment' => 'breadcrumb''_ts' => $timestamp]));
  239.             }
  240.             else {
  241.               $this->logger->error("IP check error GIR: clientIP : '" $this->request->getClientIp() + "', agenceIp : '" $_ENV['IP_ADDRESS_AGENCE'] + "'");
  242.             }
  243.           }
  244.         }
  245.       }
  246.       catch(\Exception $e) {
  247.         return $this->redirectToErrorPage($e);
  248.       }
  249.     }
  250.     // If we get to here, something went wrong or there a missing case that we have not yet coded.
  251.     $e = new \Exception($this->translator->trans("error.missing_get_parameters"));
  252.     return $this->redirectToErrorPage($e);
  253.   }
  254.   /**
  255.    * Verifies that for GIR and GRP email cases, the opp status is valid, to avoid
  256.    * entering through the tunnel multiple times (@see TICKET JIRA LMDV-445)
  257.    *
  258.    * @param string $status
  259.    * @return bool
  260.    *    TRUE if the status is valid, FALSE otherwise.
  261.    */
  262.   protected function isValidStatusOppMail($status) {
  263.       $check array_search($statusself::BLOCKED_OPP_STATUS);
  264.       $this->logger->notice("isValidStatusOppMail check", ['status' => $status'not allowed values' => self::BLOCKED_OPP_STATUS]);
  265.       if($check === FALSE) {
  266.         return TRUE;
  267.       }
  268.       else {
  269.         return FALSE;
  270.       }
  271.   }
  272. }