<?php
namespace App\Controller;
use Exception;
use App\Manager\Api\ApiManager;
use App\Manager\Api\ApiManagerInterface;
use App\Service\ResponseGeneratorInterface;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ApiController
*/
class ApiController extends BaseController
{
protected ?string $mockupFile = null;
protected ?string $endpoint = null;
protected ?string $finalPath = null;
protected ?string $queryString = null;
protected array $config = [];
/**
* ApiController constructor.
*/
public function __construct(
array $config,
ResponseGeneratorInterface $responseGenerator,
CacheItemPoolInterface $cacheItemPool,
private readonly ApiManagerInterface $apiManager
) {
parent::__construct($config, $responseGenerator, $cacheItemPool);
}
/**
* This pages actions.
*/
public function pages(RequestStack $request, Session $session): Response
{
$querySearch = [];
$apiResponse = $this->getApiResponse($request);
if (ApiManager::isProgramTv($apiResponse)) {
return $this->apiManager->getResponseProgram(
$apiResponse,
$this->setMode(self::MODE_STATIC)->getResponseStatic($request)
);
}
if (ApiManager::isOperation($apiResponse)) {
return $this->apiManager::redirectResponse($apiResponse);
}
if (ApiManager::isSearch($apiResponse)) {
$apiResponse = $this->apiManager->getApiSearchResponse($request, $querySearch, $apiResponse);
}
if (ApiManager::isDeleteAccount($session)) {
$apiResponse['notification_type'] = 'account_deleted';
$session->remove('notification_type');
}
return $this->apiManager->renderTemplate($apiResponse, $this->getMode());
}
/**
* This method allows getting final path.
*/
protected function getFinalPath(RequestStack $request): ?string
{
if (empty($this->finalPath)) {
$this->initFinalPath($request);
}
return $this->finalPath;
}
/**
* Init the final path.
*/
protected function initFinalPath(RequestStack $request): self
{
$endpoint = $this->getEndpoint($request);
if (!str_starts_with($endpoint, '/')) {
$endpoint = sprintf('/%s', $endpoint);
}
$queryString = (string)$this->queryString;
if (!empty($queryString)) {
$queryString = "?$queryString";
}
$this->finalPath = $this->apiManager->getApi($endpoint, $queryString);
return $this;
}
/**
* Load the final file path (internal|remote).
*/
protected function initMockFile(RequestStack $request): self
{
$this->mockupFile = $this->apiManager->getAssetsPath(
$this->getMode(),
$this->getEndpoint($request)
);
return $this;
}
/**
* Load the appropriate json error file.
*/
protected function getMockFile(RequestStack $request): ?string
{
if (empty($this->mockupFile)) {
$this->initMockFile($request);
}
return $this->mockupFile;
}
/**
* Get the file path contents.
*
* @return mixed[]
*/
protected function getResponseStatic(RequestStack $request): array
{
$content = json_decode((string) @file_get_contents($this->getMockFile($request)));
if (empty($content)) {
if ('prod' !== getenv('APP_ENV')) {
$content = json_decode(
(string)@file_get_contents(
$this->setMode(self::MODE_LOCAL)
->initMockFile($request)
->getMockFile($request)
)
);
} else {
throw new NotFoundHttpException();
}
}
return (array)$content;
}
/**
* Get the endpoint.
*/
protected function getEndpoint(RequestStack $request): ?string
{
if (empty($this->endpoint)) {
$this->initEndpoint($request);
}
return $this->endpoint;
}
/**
* Init the endpoint.
*
* @return $this
*/
protected function initEndpoint(RequestStack $request): self
{
$request = $request->getCurrentRequest();
$this->endpoint = (string)$request->get('endpoint');
if ('/' == substr($this->endpoint, -1)) {
$this->endpoint = rtrim($this->endpoint, '/');
}
if (empty($this->endpoint)) {
$this->endpoint = 'portal';
throw new NotFoundHttpException();
}
$this->queryString = $request->getQueryString();
return $this;
}
/**
* Get response api.
*/
protected function getApiResponse(RequestStack $request): array
{
try {
$apiResponse = $this->apiManager->getResponseDynamic($this->getFinalPath($request));
} catch (Exception) {
$apiResponse = $this
->setMode(self::MODE_STATIC)
->getResponseStatic($request)
;
}
return $apiResponse;
}
}