. // }}} /** * Base class for controllers * * @package GNUsocial * @category Controller * * @author Hugo Sales * @copyright 2020 Free Software Foundation, Inc http://www.fsf.org * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later */ namespace App\Core; use App\Util\Common; use App\Util\Exception\RedirectException; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\ControllerEvent; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\HttpKernel\Event\ViewEvent; use Symfony\Component\HttpKernel\KernelEvents; class Controller extends AbstractController implements EventSubscriberInterface { private array $vars = []; public function __invoke(Request $request) { $class = get_called_class(); $method = 'on' . ucfirst(strtolower($request->getMethod())); if (method_exists($class, $method)) { return $class::$method($request, $this->vars); } else { return $class::handle($request, $this->vars); } } public function onKernelController(ControllerEvent $event) { $controller = $event->getController(); $request = $event->getRequest(); $this->vars = ['controler' => $controller, 'request' => $request, 'have_user' => Common::user() !== null]; Event::handle('StartTwigPopulateVars', [&$this->vars]); $event->stopPropagation(); return $event; } public function onKernelView(ViewEvent $event) { $request = $event->getRequest(); $response = $event->getControllerResult(); if (!is_array($response)) { return $event; } $this->vars = array_merge_recursive($this->vars, $response); Event::handle('EndTwigPopulateVars', [&$this->vars]); $template = $this->vars['_template']; unset($this->vars['_template'], $this->vars['request']); // Respond in the the most preffered acceptable content type $format = $request->getFormat($request->getAcceptableContentTypes()[0]); switch ($format) { case 'html': $event->setResponse($this->render($template, $this->vars)); break; case 'json': $event->setResponse(new JsonResponse($this->vars)); // no break default: throw new BadRequestHttpException('Unsupported format', null, 406); } return $event; } public function onKernelException(ExceptionEvent $event) { $except = $event->getThrowable(); do { if ($except instanceof RedirectException) { if (($redir = $except->redirect_response) != null) { $event->setResponse($redir); } else { $event->setResponse(new RedirectResponse($event->getRequest()->getPathInfo())); } } } while ($except != null && ($except = $except->getPrevious()) != null); return $event; } public static function getSubscribedEvents() { return [ KernelEvents::CONTROLLER => 'onKernelController', KernelEvents::EXCEPTION => 'onKernelException', KernelEvents::VIEW => 'onKernelView', ]; } }