src/Flexy/FrontBundle/EventSubscriber/KernelListener.php line 185
<?php
namespace App\Flexy\FrontBundle\EventSubscriber;
use App\Entity\Settings;
use App\Service\FlexyGeoIp2Provider;
use App\Service\FlexyGeolocationProvider;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\RateLimiter\RateLimiterFactory;
#[AsEventListener(event: RequestEvent::class, method: 'onKernelRequest')]
#[AsEventListener(event: ExceptionEvent::class, method: 'onKernelException')]
class KernelListener
{
public function __construct(
private readonly ManagerRegistry $doctrine,
private readonly FlexyGeolocationProvider $flexyGeolocationProvider,
private readonly RateLimiterFactory $apiLimitLimiter
){
}
public function onKernelException(ExceptionEvent $event): void
{
// You get the exception object from the received event
$request = $event->getRequest();
$exception = $event->getThrowable();
$message = $exception->getMessage();
// Example pattern - adjust based on actual exception message format
if (preg_match('/Invalid upload directory "(.+)"/', $message, $matches)) {
$directory = $matches[1];
if (!is_dir($directory)) {
mkdir($directory, 0777, true);
// Optionally, you might want to reload the request or redirect after fixing the issue
$event->setResponse(new RedirectResponse($event->getRequest()->getRequestUri()));
}
}
//$statusCode = $event->getThrowable()->getStatusCode();
// To check with code later
$request = $event->getRequest();
$pathInfo = $request->getPathInfo();
$locale = $request->getLocale();
$bddLang = $this->doctrine->getRepository(Settings::class)->findOneBy(["code"=>"main"])->getDefaultLang();
if($request->query->get("_locale")){
if($request->query->get("_locale") != $locale){
$request->setLocale($request->query->get("_locale"));
}
}
if($request->server->get("APP_ENV") == "prod"){
//dd($event->getThrowable());
if(strpos($pathInfo, '/' . $locale) === 0){
if(method_exists($event->getThrowable(),"getStatusCode") ){
$response = new RedirectResponse('/'.$request->getLocale().'/page-not-found?message='.$event->getThrowable()->getMessage());
$event->setResponse($response);
}else{
$response = new RedirectResponse('/'.$request->getLocale().'/page-not-found');
$event->setResponse($response);
}
}
elseif (strpos($pathInfo, '/' . $locale) !== 0) {
// If the path does not start with the locale, redirect by adding the locale
$newUrl = '/' . $locale . $pathInfo;
//dd($newUrl);
$response = new RedirectResponse($newUrl);
//dd($response);
$event->setResponse($response);
}
}
}
public function onKernelRequest(RequestEvent $event)
{
// if (!$event->isMainRequest()) {
// return; // Ensure this odnly runs for the main request
// }
$request = $event->getRequest();
// Get the rate limiter for a specific limit name
$limiter = $this->apiLimitLimiter->create($request->getClientIp());
// Consume one token from the limit
$limit = $limiter->consume(1);
// If the limit is exceeded, deny access
if (!$limit->isAccepted()) {
$event->setResponse(new JsonResponse(['error' => 'Rate limit exceeded'], 429));
}
$pathInfo = $request->getPathInfo();
// Define a list of file extensions that should be treated as assets
$assetExtensions = ['css', 'js', 'jpg', 'jpeg', 'png', 'gif', 'ico', 'woff', 'woff2', 'ttf', 'eot'];
// Check if the request path ends with one of the asset extensions
$isAsset = preg_match('/\.(' . implode('|', $assetExtensions) . ')$/i', $pathInfo);
$mainSettings = $this->doctrine->getRepository(Settings::class)->findOneBy(["code"=>"main"]);
$accepredCurrencies = [
"USD","EUR","MAD"
];
$ipAddress = $request->server->get("REMOTE_ADDR");
$session = $request->getSession();
$defaultCurrency = $mainSettings->getCurrency();
$defaultCountryCode = "US";
if(!$session->get("_currency")){
if($mainSettings->isIsGeoLocalisationApiEnabled()){
$geoData = $this->flexyGeolocationProvider->getCountryCodeAndLanguage($ipAddress);
if($geoData){
if(array_key_exists("currency",$geoData)){
$defaultCurrency = $geoData['currency'];
}
}
}
if(!$defaultCurrency){
$session->set("_currency","USD");
}else{
$session->set("_currency",$defaultCurrency);
}
}else{
if( !in_array($session->get("_currency"),$accepredCurrencies) and !$request->query->get("_currency")){
$defaultCurrency = $this->doctrine->getRepository(Settings::class)->findOneBy(["code"=>"main"])->getCurrency();
$session->set("_currency",$defaultCurrency );
}
}
if(!$session->get("_countryCode")){
if($mainSettings->isIsGeoLocalisationApiEnabled()){
$geoData = $this->flexyGeolocationProvider->getCountryCodeAndLanguage($ipAddress);
if($geoData){
//dd($geoData);
$defaultCountryCode = $geoData['country_code'];
}
}
if(!$defaultCountryCode)
{
$defaultCountryCode = "US";
}
$session->set("_countryCode",$defaultCountryCode);
}
// if(!$session->get("_locale")){
// $geoData = $this->flexyGeolocationProvider->getCountryCodeAndLanguage($ipAddress);
// if($geoData){
// $defaultLang = $geoData['language'];
// $request->setLocale(strtolower($defaultLang));
// $session->set("_locale",strtolower($defaultLang));
// }
// }else{
// $request->setLocale($session->get("_locale"));
// }
$locale = $request->getLocale();
$bddLang = $mainSettings->getDefaultLang();
if($request->query->get("_locale")){
if($request->query->get("_locale") != $locale){
$request->setLocale($request->query->get("_locale"));
if($request->attributes->get("_route") == "front_home"){
$pattern = '#^/([a-z]{2}(?:_[a-z]{2})?)#'; // This pattern matches standard locale formats like en, en_US, etc.
}else{
$pattern = '#^/([a-z]{2}(?:_[a-z]{2})?)/#'; // This pattern matches standard locale formats like en, en_US, etc.
}
// Remove the locale part from the path
$newUrl = preg_replace($pattern,"/".$request->query->get("_locale")."/", $pathInfo);
$response = new RedirectResponse($newUrl);
$event->setResponse($response);
}
}
if($request->query->get("_currency")){
if( in_array($request->query->get("_currency"),$accepredCurrencies)){
$session->set("_currency",$request->query->get("_currency"));
}
}
if($request->query->get("_countryCode")){
$session->set("_countryCode",$request->query->get("_countryCode"));
// Reset Cart
$cart = $session->get("cart",[]);
if(array_key_exists("ready_to_checkout",$cart)){
$cart["ready_to_checkout"] = false;
$session->set("cart",$cart);
}
}
/*
elseif($bddLang){
$request->setLocale($bddLang);
}*/
//dd(strpos($pathInfo, '/' . $locale.'/') !== 0);
//dd($pathInfo);
$exeptionPaths = [
"/api_login_check"
];
if (strpos($pathInfo, '/' . $locale) !== 0 and !$isAsset) {
// If the path does not start with the locale, redirect by adding the locale
$newUrl = '/' . $locale . $pathInfo;
//dd($newUrl);
$response = new RedirectResponse($newUrl);
if (strpos($request->attributes->get("_controller"), 'web_profiler') !== false) {
return;
} else {
$event->setResponse($response);
}
}
// Check if the requested locale is in the allowed locales
if (!in_array($request->getLocale(), ["en","ar","fr"])) {
// Set a default locale if the requested locale is not allowed
$request->setLocale('en'); // Set your default locale here
$response = new RedirectResponse('/'.$request->getLocale());
$event->setResponse($response);
}
}
}