src/Flexy/FrontBundle/EventSubscriber/KernelListener.php line 169

  1. <?php
  2. namespace App\Flexy\FrontBundle\EventSubscriber;
  3. use App\Entity\Settings;
  4. use App\Service\FlexyGeoIp2Provider;
  5. use App\Service\FlexyGeolocationProvider;
  6. use Doctrine\Persistence\ManagerRegistry;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Symfony\Component\HttpKernel\Event\ExceptionEvent;
  9. use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
  10. use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
  11. use Symfony\Component\HttpFoundation\JsonResponse;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpKernel\Event\RequestEvent;
  14. use Symfony\Component\RateLimiter\RateLimiterFactory;
  15. #[AsEventListener(eventRequestEvent::class, method'onKernelRequest')]
  16. #[AsEventListener(eventExceptionEvent::class, method'onKernelException')]
  17. class KernelListener
  18. {
  19.     public function __construct(
  20.         private readonly ManagerRegistry $doctrine,
  21.         private readonly FlexyGeolocationProvider $flexyGeolocationProvider,
  22.         private readonly RateLimiterFactory $apiLimitLimiter
  23.         ){
  24.     }
  25.     
  26.     public function onKernelException(ExceptionEvent $event): void
  27.     {
  28.         // You get the exception object from the received event
  29.         
  30.        
  31.         $request $event->getRequest();
  32.         
  33.         $exception $event->getThrowable();
  34.         $message $exception->getMessage();
  35.         
  36.         // Example pattern - adjust based on actual exception message format
  37.         if (preg_match('/Invalid upload directory "(.+)"/'$message$matches)) {
  38.             $directory $matches[1];
  39.             
  40.             
  41.             if (!is_dir($directory)) {
  42.                 mkdir($directory0777true);
  43.                 // Optionally, you might want to reload the request or redirect after fixing the issue
  44.                 $event->setResponse(new RedirectResponse($event->getRequest()->getRequestUri()));
  45.             }
  46.         }
  47.          
  48.         //$statusCode = $event->getThrowable()->getStatusCode();
  49.         // To check with code later
  50.         $request $event->getRequest();
  51.         $pathInfo $request->getPathInfo();
  52.         $locale $request->getLocale();
  53.         
  54.         
  55.         $bddLang $this->doctrine->getRepository(Settings::class)->findOneBy(["code"=>"main"])->getDefaultLang();
  56.         
  57.         
  58.         
  59.         
  60.     
  61.         if($request->query->get("_locale")){
  62.             if($request->query->get("_locale") != $locale){
  63.                 $request->setLocale($request->query->get("_locale"));
  64.             }
  65.         }
  66.         
  67.         if($request->server->get("APP_ENV") == "prod"){
  68.             //dd($event->getThrowable());
  69.             
  70.             if(strpos($pathInfo'/' $locale) === 0){
  71.                 if(method_exists($event->getThrowable(),"getStatusCode")  ){
  72.                     $response = new RedirectResponse('/'.$request->getLocale().'/page-not-found?message='.$event->getThrowable()->getMessage());
  73.                     $event->setResponse($response);
  74.                  }else{
  75.                     $response = new RedirectResponse('/'.$request->getLocale().'/page-not-found');
  76.                     $event->setResponse($response);
  77.                  }
  78.             }
  79.             elseif (strpos($pathInfo'/' $locale) !== 0) {
  80.                 // If the path does not start with the locale, redirect by adding the locale
  81.                 $newUrl '/' $locale $pathInfo;
  82.                 //dd($newUrl);
  83.                 $response = new RedirectResponse($newUrl);
  84.                 //dd($response);
  85.                 $event->setResponse($response);
  86.             }
  87.             
  88.         }
  89.          
  90.         
  91.  
  92.     }
  93.         public function onKernelRequest(RequestEvent $event)
  94.     {
  95.         // if (!$event->isMainRequest()) {
  96.         //     return; // Ensure this odnly runs for the main request
  97.         // }
  98.         $request $event->getRequest();
  99.        
  100.         // Get the rate limiter for a specific limit name
  101.         $limiter $this->apiLimitLimiter->create($request->getClientIp());
  102.         
  103.         // Consume one token from the limit
  104.         $limit $limiter->consume(1);
  105.         
  106.         // If the limit is exceeded, deny access
  107.         if (!$limit->isAccepted()) {
  108.             $event->setResponse(new JsonResponse(['error' => 'Rate limit exceeded'], 429));
  109.         }
  110.         $pathInfo $request->getPathInfo();
  111.          // Define a list of file extensions that should be treated as assets
  112.          $assetExtensions = ['css''js''jpg''jpeg''png''gif''ico''woff''woff2''ttf''eot'];
  113.          // Check if the request path ends with one of the asset extensions
  114.          $isAsset preg_match('/\.(' implode('|'$assetExtensions) . ')$/i'$pathInfo);
  115.  
  116.          
  117.         $mainSettings $this->doctrine->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
  118.         $accepredCurrencies = [
  119.             "USD","EUR","MAD"
  120.         ];
  121.         $ipAddress $request->server->get("REMOTE_ADDR");
  122.         
  123.         $session =  $request->getSession();
  124.         $defaultCurrency $mainSettings->getCurrency();
  125.         $defaultCountryCode "US";
  126.         
  127.         if(!$session->get("_currency")){
  128.             if($mainSettings->isIsGeoLocalisationApiEnabled()){
  129.                 $geoData $this->flexyGeolocationProvider->getCountryCodeAndLanguage($ipAddress);
  130.                 if($geoData){
  131.                     if(array_key_exists("currency",$geoData)){
  132.                         $defaultCurrency  $geoData['currency'];
  133.                     }
  134.                    
  135.                 }
  136.             }
  137.             
  138.             
  139.             if(!$defaultCurrency){
  140.                 $session->set("_currency","USD");
  141.             }else{
  142.                 $session->set("_currency",$defaultCurrency);
  143.             }
  144.         }else{
  145.             if( !in_array($session->get("_currency"),$accepredCurrencies) and !$request->query->get("_currency")){
  146.                 $defaultCurrency $this->doctrine->getRepository(Settings::class)->findOneBy(["code"=>"main"])->getCurrency();
  147.                 $session->set("_currency",$defaultCurrency );
  148.             }
  149.         }
  150.         
  151.         if(!$session->get("_countryCode")){
  152.             
  153.             
  154.              if($mainSettings->isIsGeoLocalisationApiEnabled()){
  155.                 $geoData $this->flexyGeolocationProvider->getCountryCodeAndLanguage($ipAddress);
  156.                     if($geoData){
  157.                         //dd($geoData);
  158.                         $defaultCountryCode  $geoData['country_code'];
  159.                     }
  160.             }
  161.              if(!$defaultCountryCode)
  162.              {
  163.                 $defaultCountryCode "US";
  164.              }
  165.              $session->set("_countryCode",$defaultCountryCode);
  166.         }
  167.         // if(!$session->get("_locale")){
  168.             
  169.         //     $geoData = $this->flexyGeolocationProvider->getCountryCodeAndLanguage($ipAddress);
  170.         //      if($geoData){
  171.         //         $defaultLang  = $geoData['language'];
  172.         //         $request->setLocale(strtolower($defaultLang));
  173.         //         $session->set("_locale",strtolower($defaultLang));
  174.         //      }
  175.         // }else{
  176.         //     $request->setLocale($session->get("_locale"));
  177.         // }
  178.             
  179.         $locale $request->getLocale();
  180.         
  181.         
  182.         $bddLang $mainSettings->getDefaultLang();
  183.         
  184.         
  185.         
  186.         
  187.     
  188.         if($request->query->get("_locale")){
  189.             if($request->query->get("_locale") != $locale){
  190.                 
  191.                 $request->setLocale($request->query->get("_locale"));
  192.                 
  193.                 if($request->attributes->get("_route") == "front_home"){
  194.                     $pattern '#^/([a-z]{2}(?:_[a-z]{2})?)#'// This pattern matches standard locale formats like en, en_US, etc.
  195.                 }else{
  196.                     $pattern '#^/([a-z]{2}(?:_[a-z]{2})?)/#'// This pattern matches standard locale formats like en, en_US, etc.
  197.                 }
  198.                 
  199.                 // Remove the locale part from the path
  200.                 $newUrl preg_replace($pattern,"/".$request->query->get("_locale")."/"$pathInfo);
  201.                 
  202.                 
  203.                 
  204.                 $response = new RedirectResponse($newUrl);
  205.                 $event->setResponse($response);
  206.             }
  207.         }
  208.         if($request->query->get("_currency")){
  209.             
  210.             if( in_array($request->query->get("_currency"),$accepredCurrencies)){
  211.                 $session->set("_currency",$request->query->get("_currency"));
  212.             }
  213.             
  214.             
  215.         }
  216.         if($request->query->get("_countryCode")){
  217.             
  218.             
  219.         $session->set("_countryCode",$request->query->get("_countryCode"));
  220.         
  221.             // Reset Cart
  222.              $cart $session->get("cart",[]);
  223.              if(array_key_exists("ready_to_checkout",$cart)){
  224.                 $cart["ready_to_checkout"] = false;
  225.                 $session->set("cart",$cart);
  226.              }
  227.         
  228.             
  229.             
  230.         }
  231.         /*
  232.         elseif($bddLang){
  233.             $request->setLocale($bddLang);
  234.         }*/
  235.         
  236.         
  237.         //dd(strpos($pathInfo, '/' . $locale.'/') !== 0);
  238.         //dd($pathInfo);
  239.         $exeptionPaths = [
  240.             "/api_login_check"
  241.         ];
  242.         
  243.         if (strpos($pathInfo'/' $locale) !== and !$isAsset) {
  244.             
  245.           
  246.             
  247.             // If the path does not start with the locale, redirect by adding the locale
  248.             $newUrl '/' $locale $pathInfo;
  249.             //dd($newUrl);
  250.             $response = new RedirectResponse($newUrl);
  251.             
  252.             
  253.         
  254.         if (strpos($request->attributes->get("_controller"), 'web_profiler')  !== false)  {
  255.             return;
  256.         } else {
  257.             
  258.             $event->setResponse($response);
  259.         }
  260.        
  261.     }
  262.       
  263.             
  264.         
  265.             
  266.             
  267.         
  268.         // Check if the requested locale is in the allowed locales
  269.         
  270.         if (!in_array($request->getLocale(), ["en","ar","fr"])) {
  271.             // Set a default locale if the requested locale is not allowed
  272.             $request->setLocale('en'); // Set your default locale here
  273.             $response = new RedirectResponse('/'.$request->getLocale());
  274.             $event->setResponse($response);
  275.         }
  276.         
  277.         
  278.         
  279.         
  280.        
  281.     }
  282. }