<?php declare(strict_types=1);
namespace App\Controller\CRUD;
use App\Response\ActionResult;
use InvalidArgumentException;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\Security\Core\User\UserInterface;
abstract class ActionController extends AbstractController
{
/**
* @var array<string, string|int|float|bool|object|mixed[]|null>
*/
protected array $templateParams = [];
/**
* @return ActionResult|Response
*/
abstract public function handleRequest(Request $request);
/**
* Do whatever you want with response in this method, don't called for redirects
*
* @param ActionResult|Response|null $actionResponse
*/
protected function handleResponse($actionResponse = null, ?Response $response = null): Response
{
if (null === $response) {
throw new RuntimeException('There is no response to handle');
}
return $response;
}
public function executeAction(Request $request): Response
{
$response = $this->handleRequest($request);
if ($response instanceof Response) {
return $this->handleResponse(null, $response);
}
foreach ($this->templateParams as $key => $value) {
$response->setParam($key, $value);
}
if ($response->getRedirect() !== null) {
return $this->redirect($response->getRedirect());
}
$template = $response->getTemplate();
if (null === $template) {
throw new InvalidArgumentException('Template must be set if you want to render something.');
}
return $this->handleResponse(
$response,
$this->render($template, $response->getParams(), $response->getResponse())
);
}
/**
* @param string|int|float|bool|object|mixed[]|null $value
*/
public function addTemplateParam(string $key, $value): void
{
$this->templateParams[$key] = $value;
}
/**
* @throws AccessDeniedException
*/
public function getAuthenticatedUser(): UserInterface
{
if (null === ($user = $this->getUser())) {
throw $this->createAccessDeniedException();
}
return $user;
}
protected function isHandlingJson(Request $request): bool
{
return true;
}
protected function isAjaxRequest(Request $request): bool
{
$acceptHeader = $request->headers->get('accept');
return $request->isXmlHttpRequest()
|| (null !== $acceptHeader && strpos($acceptHeader, 'application/json') !== false);
}
}