<?php
namespace Boab\CmsBundle\Controller;
use Boab\CmsBundle\Entity\UserInterface;
use Symfony\Component\Form\Form;
use Boab\CmsBundle\Util\FlashInterface;
use Doctrine\ORM\EntityManagerInterface;
use Boab\CmsBundle\View\ViewManagerInterface;
use Boab\CmsBundle\View\ThemeManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
abstract class BaseController
{
protected $viewManager;
protected $themeManager;
protected $flash;
protected $router;
protected $formFactory;
protected $authorizationChecker;
protected $tokenStorage;
protected $entityManager;
protected $eventDispatcher;
protected $paginator;
protected $logger;
/**
* @required
*/
public function setEventDispatcher(EventDispatcherInterface $eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}
/**
* @required
*/
public function setEntityManager(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* @required
*/
public function setTemplate(ViewManagerInterface $viewManager)
{
$this->viewManager = $viewManager;
}
/**
* @required
*/
public function setThemeManager(ThemeManagerInterface $themeManager)
{
$this->themeManager = $themeManager;
}
/**
* @required
*/
public function setFormFactory(FormFactoryInterface $formFactory)
{
$this->formFactory = $formFactory;
}
/**
* @required
*/
public function setFlash(FlashInterface $flash)
{
$this->flash = $flash;
}
/**
* @required
*/
public function setAuthorizationChecker(AuthorizationCheckerInterface $authorizationChecker)
{
$this->authorizationChecker = $authorizationChecker;
}
/**
* @required
*/
public function setTokenStorage(TokenStorageInterface $tokenStorage)
{
$this->tokenStorage = $tokenStorage;
}
/**
* @required
*/
public function setRouter(RouterInterface $router)
{
$this->router = $router;
}
/**
* @required
*/
public function setLogger(LoggerInterface $logger)
{
$this->logger = $logger;
}
/**
* Creates and returns a Form instance from the type of the form.
*
* @param string|FormTypeInterface $type The built type of the form
* @param mixed $data The initial data for the form
* @param array $options Options for the form
*
* @return Form
*/
protected function createForm($type, $data = null, array $options = array())
{
return $this->formFactory->create($type, $data, $options);
}
/**
* Creates and returns a form builder instance.
*
* @param mixed $data The initial data for the form
* @param array $options Options for the form
*
* @return FormBuilder
*/
protected function createFormBuilder($data = null, array $options = array())
{
return $this->formFactory->createBuilder('form', $data, $options);
}
protected function getUserToken()
{
return $this->tokenStorage->getToken()->getUser();
}
protected function getUser(): ?UserInterface
{
$token = $this->tokenStorage->getToken();
if($token instanceof UsernamePasswordToken){
return $token->getUser();
}
return null;
}
protected function redirect($url, $status = 302)
{
return new RedirectResponse($url);
}
protected function save($entity)
{
$this->entityManager->persist($entity);
$this->entityManager->flush();
$this->entityManager->refresh($entity);
return $entity;
}
protected function update($entity)
{
$this->entityManager->persist($entity);
$this->entityManager->flush();
$this->entityManager->refresh($entity);
return $entity;
}
/**
* Checks if the attribute is granted against the current authentication token and optionally supplied subject.
*
* @throws \LogicException
*/
protected function isGranted($attribute, $subject = null): bool
{
if (!$this->authorizationChecker) {
throw new \LogicException('The SecurityBundle is not registered in your application. Try running "composer require symfony/security-bundle".');
}
return $this->authorizationChecker->isGranted($attribute, $subject);
}
/**
* Throws an exception unless the attribute is granted against the current authentication token and optionally
* supplied subject.
*
* @throws AccessDeniedException
*/
protected function denyAccessUnlessGranted($attribute, $subject = null, string $message = 'Access Denied.'): void
{
if (!$this->isGranted($attribute, $subject)) {
$exception = $this->createAccessDeniedException($message);
$exception->setAttributes($attribute);
$exception->setSubject($subject);
throw $exception;
}
}
/**
* Returns an AccessDeniedException.
*
* This will result in a 403 response code. Usage example:
*
* throw $this->createAccessDeniedException('Unable to access this page!');
*
* @throws \LogicException If the Security component is not available
*/
protected function createAccessDeniedException(string $message = 'Access Denied.', \Throwable $previous = null): AccessDeniedException
{
if (!class_exists(AccessDeniedException::class)) {
throw new \LogicException('You cannot use the "createAccessDeniedException" method if the Security component is not available. Try running "composer require symfony/security-bundle".');
}
return new AccessDeniedException($message, $previous);
}
public function delete($entity)
{
$this->entityManager->remove($entity);
$this->entityManager->flush();
return;
}
protected function getErrorMessages(\Symfony\Component\Form\Form $form)
{
$errors = array();
foreach ($form->getErrors(true, true) as $error) {
// My personnal need was to get translatable messages
// $errors[] = $this->trans($error->getMessage());
$errors[] = $error->getMessage();
}
return $errors;
}
public function render(string $template, array $data=[])
{
$html = $this->viewManager->load($template)->render($data);
return new Response($html);
}
protected function redirectToRoute(string $routeName, $params=[])
{
return $this->redirect($this->router->generate($routeName, $params));
}
}