<?php
namespace App\CmsBundle\Controller;
use App\CasinoBundle\Service\Bonus\BonusHtmlExtractorService;
use App\CmsBundle\Exception\PageNotFoundException;
use App\CmsBundle\Exception\RedirectException;
use App\CmsBundle\Exception\SiteNotFoundException;
use App\CmsBundle\Helper\ContentHelper;
use App\CmsBundle\Service\CmsService;
use App\CmsBundle\Service\MetricsCollectorService;
use App\CmsBundle\Service\OptionResolverService;
use Prometheus\Exception\MetricsRegistrationException;
use Psr\Cache\InvalidArgumentException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as SymfonyAbstractController;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Stopwatch\Stopwatch;
final class ContentController extends SymfonyAbstractController
{
private const EXCEPTION_MESSAGE_PAGE_NOT_FOUND = 'Page does not exist';
private const EXCEPTION_MESSAGE_SITE_NOT_FOUND = 'Site does not exist';
private const BLOCKED_DOMAINS = [
'kasinotanalyzer.com',
'spanishcasinosanalyzer.com',
'arabcasinosanalyzer.com',
'frenchcasinosanalyzer.com',
'irishcasinosanalyzer.com',
'thaicasinosanalyzer.com',
'swisscasinosanalyzer.com',
'norskcasinosanalyzer.com',
'kaszinokanalyzer.com',
'kazinoanalyzer.com',
'kasinaanalyzer.com',
'casinoernalyzer.com',
'greekcasinosanalyzer.com',
'casinolaranalyzer.com',
'vietnamcasinosanalyzer.com',
'chinacasinosanalyzer.com',
'ukrcasinosanalyzer.com',
'slvcasinosanalyzer.com',
'argcasinosanalyzer.com',
'blrcasinosanalyzer.com',
'mdacasinosanalyzer.com',
'tjkcasinosanalyzer.com',
'tkmcasinosanalyzer.com',
'serbiancasinosanalyzer.com',
'bulgariancasinosanalyzer.com',
'casinosanalyzer.jp',
'kasinaanalyzer.sk',
'casinosanalyzer.kr',
'casinosanalyzer.it',
'cassinosanalyzer.com.br',
'casinosanalyzer.nl',
'cazinourianalyzer.ro',
'casinosanalyzer.ug',
'casinosanalyzer.si',
'casinosanalyzer.co.ke',
'casinosanalyzer.co.tz',
'casinosanalyzer.co.za',
'casinosanalyzer.at',
];
private CmsService $cmsService;
private OptionResolverService $optionResolverService;
private MetricsCollectorService $metricsCollectorService;
protected AdapterInterface $cache;
protected BonusHtmlExtractorService $bonusHtmlExtractorService;
public function __construct(
CmsService $cmsService,
OptionResolverService $optionResolverService,
MetricsCollectorService $metricsCollectorService,
AdapterInterface $cache,
BonusHtmlExtractorService $bonusHtmlExtractorService
)
{
$this->cmsService = $cmsService;
$this->optionResolverService = $optionResolverService;
$this->metricsCollectorService = $metricsCollectorService;
$this->cache = $cache;
$this->bonusHtmlExtractorService = $bonusHtmlExtractorService;
}
/**
* @return Response
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws MetricsRegistrationException
* @throws InvalidArgumentException
* @throw NotFoundHttpException
* @throw RedirectException
*/
public function index(): Response
{
$this->optionResolverService->getRequest()?->attributes->set('is_main_request', true);
if (in_array($this->cmsService->removeSubdomainPrefix($_SERVER['HTTP_HOST']), self::BLOCKED_DOMAINS)) {
return new Response(
'',
Response::HTTP_FORBIDDEN,
);
}
try {
$content = $this->getContentFromCache();
/*
* Need Check Page Loading [5563]
*
$offersData = $this->bonusHtmlExtractorService->extractFromHtml(
$content,
$this->optionResolverService->getRequest()
);
$this->optionResolverService
->getRequest()
->attributes
->set(
'bonus_offer_stats',
$offersData
);
*/
return new Response(
$content,
Response::HTTP_OK,
$this->getHeaders()
);
} catch (PageNotFoundException $e) {
throw new NotFoundHttpException(
sprintf('%s: %s', self::EXCEPTION_MESSAGE_PAGE_NOT_FOUND, $this->optionResolverService->getRequest()?->getUri()),
$e
);
} catch (SiteNotFoundException $e) {
throw new NotFoundHttpException(
sprintf('%s: %s', self::EXCEPTION_MESSAGE_SITE_NOT_FOUND, $this->optionResolverService->getRequest()?->getUri()),
$e
);
} catch (RedirectException $exception) {
if (!empty($exception->getUrl())) {
return $this->redirect($exception->getUrl(), $exception->getStatus());
} else {
throw new NotFoundHttpException(self::EXCEPTION_MESSAGE_PAGE_NOT_FOUND);
}
}
}
/**
* @return string|null
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws PageNotFoundException
* @throws RedirectException
* @throws SiteNotFoundException
* @throws MetricsRegistrationException
*/
private function getContent(): ?string
{
$stopwatch = new Stopwatch();
$stopwatch->start('response_generation_time');
$stopwatch->start('content_generation_time');
$domain = $this->optionResolverService->getSite()->getDomain();
$environment = $this->optionResolverService->getEnvironment();
$route = $this->optionResolverService->getRoute()?->getParameter('route');
$pageData = $this->cmsService->getPageData();
$this->metricsCollectorService->incContentGenerationTime(
$stopwatch->stop('content_generation_time')->getDuration(),
$environment,
$domain,
$route
);
$content = $this->render(
$this->cmsService->getPageTemplate(),
$pageData
)->getContent();
$this->metricsCollectorService->incResponseGenerationTime(
$stopwatch->stop('response_generation_time')->getDuration(),
$environment,
$domain,
$route
);
return ContentHelper::removeShortCodes($content);
}
/**
* @return string
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws PageNotFoundException
* @throws RedirectException
* @throws SiteNotFoundException
* @throws MetricsRegistrationException
* @throws InvalidArgumentException
*/
private function getContentFromCache(): string
{
$applyCache = (!$this->getUser() and $this->optionResolverService->getEnvironment() != 'loc');
$cachedResult = null;
if ($applyCache) {
$cacheKey = 'page_' . md5($this->optionResolverService->getClientCountryCodeCf() . '_' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
$cachedResult = $this->cache->getItem($cacheKey);
}
if (($cachedResult or $cachedResult?->isHit()) and ($content = $cachedResult->get())) {
//release content from cache
} else {
$content = $this->getContent();
if ($applyCache) {
$cachedResult->set($content);
$cachedResult->expiresAfter(172800); // 2d
$this->cache->save($cachedResult);
}
}
return $content;
}
/**
* @return string[]
*/
private function getHeaders(): array
{
return [
'X-Frame-Options' => 'SAMEORIGIN',
'Access-Control-Allow-Origin' => '*',
'Link' => '<https://api.amplitude.com>; rel="preconnect"'
. ', <https://cdn.amplitude.com>; rel="preconnect"'
. ', <https://cdn.growthbook.io>; rel="preconnect"'
. ', </build/midori/assets/bootstrap/css/bootstrap-grid.min.css>; rel="preload"; as="style"; crossorigin="anonymous"'
. ', </build/midori/assets/css/base.css?v=' . $this->optionResolverService->getAppVersion() . '>; rel="preload"; as="style"; crossorigin="anonymous"'
. ', </build/midori/assets/fonts/Poppins-Bold.woff2>; rel="preload"; as="font"; crossorigin="anonymous"'
. ', </build/midori/assets/fonts/Poppins-SemiBold.woff2>; rel="preload"; as="font"; crossorigin="anonymous"'
. ', </build/midori/assets/fonts/Poppins-Medium.woff2>; rel="preload"; as="font"; crossorigin="anonymous"'
. ', </build/midori/assets/fonts/Poppins-Regular.woff2>; rel="preload"; as="font"; crossorigin="anonymous"'
. ', </build/midori/assets/fonts/Poppins-ExtraBold.woff2>; rel="preload"; as="font"; crossorigin="anonymous"'
];
}
}