<?php
namespace App\EventListener;
use App\Application\Service\Api\Service\FileService;
use App\Application\Service\Helper\ToolsService;
use App\Application\Service\Session\SessionService;
use App\Entity\System\Catalog;
use App\Service\EnvironmentService;
use Request as LegacyRequest;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\RouterInterface;
class LegacyBootstrapListener
{
public const CONTOLLERS_CHECKOUT = ['cartController', 'subscriptionController'];
public const METHOD_CHECKOUT = ['checkout', 'mobilecart'];
private RequestStack $requestStack;
private RouterInterface $router;
private EnvironmentService $environmentService;
private string $legacyDir;
private SessionService $sessionService;
private ToolsService $toolsService;
public function __construct(
RequestStack $requestStack,
RouterInterface $router,
EnvironmentService $environmentService,
FileService $fileService,
SessionService $sessionService,
ToolsService $toolsService
) {
$this->requestStack = $requestStack;
$this->router = $router;
$this->legacyDir = $fileService->getLegacyDir();
$this->environmentService = $environmentService;
$this->sessionService = $sessionService;
$this->toolsService = $toolsService;
}
public function onKernelRequest(RequestEvent $event): void
{
if ($this->environmentService->isApi()) {
return;
}
$symfonyRequest = $event->getRequest();
$refTapfiliate = $symfonyRequest->query->get('ref');
$this->requestStack->getSession()->set('isCheckout', false);
try {
$pathInfo = $this->router->match($event->getRequest()->getPathInfo());
} catch (ResourceNotFoundException $exception) {
return;
}
$this->defineLayoutsPath($event->getRequest()->getPathInfo());
if (
\array_key_exists('_route', $pathInfo)
&& ($pathInfo['_route'] === 'legacy_front_endpoints'
|| $pathInfo['_route'] === 'legacy_admin_endpoints')
) {
$legacyRequest = new LegacyRequest(); // TODO move logic inside LegacyRequest here
$controller = $legacyRequest->getControlador().LegacyRequest::DEFAULT_NAME_CONTROLLER;
$method = $legacyRequest->getMetodo();
$args = $legacyRequest->getArgumentos();
$this->sessionService->set('controller', $controller);
$this->sessionService->set('metodo', $method);
$this->sessionService->set('argumentos', $args);
$this->sessionService->set('url', $legacyRequest->getUrl());
if (!$this->sessionService->get(SessionService::ALLOWED_CATALOGS_KEY) || empty($this->sessionService->get(SessionService::ALLOWED_CATALOGS_KEY))) {
$this->sessionService->set(SessionService::ALLOWED_CATALOGS_KEY, [Catalog::DEFAULT_CATALOG_BIGBUY_REFERENCE]);
}
$resolvedController = $this->resolveLegacyController($legacyRequest, $controller, $method, $args);
$this->saveGoogleAnalyticsCookie($legacyRequest, $resolvedController['class']);
$symfonyRequestData = $symfonyRequest->request->get('legacy_controller');
$symfonyRequest->request->set('legacy_controller', [
'url' => $legacyRequest->getUrl(),
'controller' => $resolvedController['class'],
'method' => $resolvedController['method'],
'args' => $resolvedController['args'],
]);
if (
$symfonyRequestData !== null
&& !isset($symfonyRequestData['ref'])
&& $refTapfiliate !== null
) {
$symfonyRequest->request->set('legacy_controller', [
'url' => $legacyRequest->getUrl(),
'controller' => $resolvedController['class'],
'method' => $resolvedController['method'],
'args' => $resolvedController['args'],
'ref' => $refTapfiliate,
]);
}
$this->populateSfSessionFromSessionGlobal($symfonyRequest->getSession());
if (in_array($controller, self::CONTOLLERS_CHECKOUT) && in_array($method, self::METHOD_CHECKOUT)) {
$this->requestStack->getSession()->set('isCheckout', true);
}
}
}
/**
* @param string $path
* @param string $controller
*
* @return string
*/
private function getLegacyControllerPath(string $path, string $controller): string
{
return $this->legacyDir.'/controllers'.DIRECTORY_SEPARATOR.$path.DIRECTORY_SEPARATOR.$controller.'.php';
}
/**
* @param LegacyRequest $legacyRequest
* @param string $controller
* @param string $method
* @param array $args
*
* @return array
*/
private function resolveLegacyController(LegacyRequest $legacyRequest, string $controller, string $method, array $args): array
{
if ($legacyRequest->getAdmin()) {
$path = ADMIN_DIR;
} elseif ($legacyRequest->getService()) {
$path = SERVICE_DIR;
} else {
$path = FRONT_DIR;
}
$controllerPath = $this->getLegacyControllerPath($path, $controller);
$realIP = '';
if (isset($_SERVER['HTTP_X_REAL_IP'])) {
$realIP = $_SERVER['HTTP_X_REAL_IP'];
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
$realIP = $_SERVER['REMOTE_ADDR'];
}
if (!empty($args) && $legacyRequest->getService()) {
$args = $this->sessionService->get('argumentos');
}
if (!is_callable([$controller, $method]) || !is_readable($controllerPath)) {
return [
'class' => LegacyRequest::NOT_FOUND_CONTROLLER,
'method' => LegacyRequest::DEFAULT_METHOD,
'args' => $args,
];
// throw new NotFoundHttpException('Not Found');
}
// Require requested controller and all the rest from the same folder (service, admin, front..) because in certain cases a controller calls another...
// Sort descending because of a single case (admin/sliderController must be loaded before admin/bannerController). So dirty, I know.
foreach (scandir($this->legacyDir.'/controllers'.DIRECTORY_SEPARATOR.$path, SCANDIR_SORT_DESCENDING) as $filename) {
$controllerPath = $this->legacyDir.'/controllers'.DIRECTORY_SEPARATOR.$path.'/'.$filename;
if (is_file($controllerPath) && strpos($filename, 'Controller')) {
require_once $controllerPath;
}
}
return [
'class' => $controller,
'method' => $method,
'args' => $args,
];
}
private function saveGoogleAnalyticsCookie(LegacyRequest $legacyRequest, string $class): void
{
if (
LegacyRequest::NOT_FOUND_CONTROLLER !== $class && LegacyRequest::MAINTENANCE_CONTROLLER !== $class
&& $legacyRequest->getFront() && !\Tools::getValue('ajax')
) {
\GACookie::SaveCookie();
}
}
private function populateSfSessionFromSessionGlobal(SessionInterface $session): void
{
foreach ($_SESSION as $key => $value) {
if ($key !== '_sf2_attributes') {
$session->set($key, $value);
}
}
}
private function defineLayoutsPath(string $route): void
{
$templateDir = FRONT_DIR;
$isMobile = $this->toolsService::isMobile();
if (preg_match('/^\/'.ADMIN_DIR.'\//', $route, $m)) {
$templateDir = ADMIN_DIR;
if (!defined('IS_ADMIN')) {
define('IS_ADMIN', '1');
}
} // SI ESTAMOS EN SERVICE
elseif (preg_match('/^\/'.SERVICE_DIR.'\//', $route, $m)) {
$templateDir = SERVICE_DIR;
if (!defined('IS_SERVICE')) {
define('IS_SERVICE', '1');
}
}
if (!defined('LAYOUTS_PATH')) {
/** @phpstan-ignore-next-line */
define('LAYOUTS_PATH', ($isMobile ? MOBILE_VIEWS.DIRECTORY_SEPARATOR : '').$templateDir.DIRECTORY_SEPARATOR.'layout'.DIRECTORY_SEPARATOR);
}
if (!defined('PARTIALS_PATH')) {
/** @phpstan-ignore-next-line */
define('PARTIALS_PATH', ($isMobile ? MOBILE_VIEWS.DIRECTORY_SEPARATOR : '').$templateDir.DIRECTORY_SEPARATOR.'partial'.DIRECTORY_SEPARATOR);
}
}
}