<?php
namespace App\Controller\Main;
use App\Enum\ApiCodeEnum;
use App\Enum\FileExtensionEnum;
use App\Services\Main\SecurityService;
use App\Services\Util\ConfigService;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpClient\CurlHttpClient;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* Class ApiController.
*
* @Route("api")
*/
class ApiController extends AbstractController
{
/**
* @var ConfigService
*/
private ConfigService $configService;
/**
* @var SecurityService
*/
private SecurityService $securityService;
private string $apiUrl;
/**
* @var CurlHttpClient
*/
private CurlHttpClient $client;
public function __construct(ConfigService $configService, SecurityService $securityService)
{
$this->configService = $configService;
$this->securityService = $securityService;
$this->apiUrl = $this->configService->getApiUrl();
$this->client = HttpClient::create();
}
/**
* @Route("/{route}", name="api.main", requirements={"route" = ".+"})
*/
public function index(Request $request, string $route)
{
if ($token = $this->securityService->getToken()) {
$options['auth_bearer'] = $token;
}
$options['auth_bearer'] = str_replace('Bearer ', '', $request->headers->get('authorization'));
$options['json'] = json_decode($request->getContent(), true);
$options['headers']['isRemote'] = true;
$query = http_build_query($request->query->all());
$apiRoute = $this->apiUrl . $route;
if (!empty($query)) {
$apiRoute .= "?{$query}";
}
$response = $this->client->request($request->getMethod(), $apiRoute, $options);
if (Response::HTTP_OK !== $response->getStatusCode()) {
return $this->json([
'error' => true,
'message' => ApiCodeEnum::INVALID_REQUEST,
]);
}
$headers = [];
try {
$headers = $response->getHeaders();
} catch (Exception $e) {
return $this->json([
'error' => true,
'message' => $e->getMessage(),
]);
}
$contentType = mb_strtolower($headers['content-type'][0]);
if ('application/json' === $contentType && !empty($request->getContent())) {
return $this->json($response->toArray(false));
}
//Content-Type can contain "png" or "image/png" if resize or format is given
$extension = explode('/', $contentType)[1] ?? '';
if (in_array($contentType, array_keys(FileExtensionEnum::LIST_EXTENSIONS, true))
|| in_array($extension, array_keys(FileExtensionEnum::LIST_EXTENSIONS, true))
) {
$response = new Response($response->getContent());
$response->headers->set('Content-type', $contentType);
$response->headers->set('Content-Disposition', $headers['content-disposition'][0]);
return $response;
}
if (str_contains($contentType, 'text/html')) {
return new Response($response->getContent());
}
return $this->json([
'error' => true,
'message' => ApiCodeEnum::INVALID_REQUEST,
]);
}
}