<?php 
 
namespace Whater\UI\WebBundle\Controller; 
 
use Monolog\Logger; 
use Whater\Domain\User\Model\User; 
use Whater\Infrastructure\SecurityBundle\Security\Model\Auth; 
use JMS\Serializer\Serializer; 
use Cocur\Slugify\Slugify; 
use FOS\RestBundle\View\View; 
use FOS\RestBundle\View\ViewHandlerInterface; 
use Knp\Snappy\Pdf; 
use Symfony\Component\EventDispatcher\EventDispatcherInterface; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Component\HttpFoundation\RequestStack; 
use Symfony\Component\Form\FormFactory; 
use Symfony\Component\HttpFoundation\Session\Session; 
use Symfony\Bundle\FrameworkBundle\Routing\Router; 
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; 
use FOS\RestBundle\Controller\ControllerTrait as FOSControllerTrait; 
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface; 
use Symfony\Contracts\Translation\TranslatorInterface; 
use Twig\Environment; 
use GeoIp2\Database\Reader; 
 
/** 
 * Class AbstractController 
 * 
 * @package Whater\UI\WebBundle\Controller 
 */ 
abstract class AbstractController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController 
{ 
 
    use FOSControllerTrait; 
 
    protected function getViewHandler(): ViewHandlerInterface 
    { 
        return $this->viewHandler(); 
    } 
 
    protected function viewHandler(): ViewHandlerInterface 
    { 
        return $this->container->get('fos_rest.view_handler'); 
    } 
 
    protected function requestStack(): RequestStack 
    { 
        return $this->container->get('request_stack'); 
    } 
 
    protected function templating(): Environment 
    { 
        return $this->container->get('twig'); 
    } 
 
    protected function formFactory(): FormFactory 
    { 
        return $this->container->get('form.factory'); 
    } 
 
    protected function session(): Session 
    { 
        return $this->container->get('session'); 
    } 
 
    protected function router(): Router 
    { 
        return $this->container->get('router'); 
    } 
 
    protected function translator(): TranslatorInterface 
    { 
        return $this->container->get('translator'); 
    } 
 
    protected function jmsSerializer(): Serializer 
    { 
        return $this->container->get('jms_serializer'); 
    } 
 
    protected function authorizationChecker(): AuthorizationCheckerInterface 
    { 
        return $this->container->get('security.authorization_checker'); 
    } 
 
    protected function tokenStorage(): TokenStorageInterface 
    { 
        return $this->container->get('security.token_storage'); 
    } 
 
    protected function eventDispatcher(): EventDispatcherInterface 
    { 
        return $this->container->get('event_dispatcher'); 
    } 
 
    protected function knpSnappyPdf(): Pdf 
    { 
        return $this->container->get('knp_snappy.pdf'); 
    } 
 
    protected function logger(): Logger 
    { 
        return $this->container->get('whater.logger'); 
    } 
 
    protected function slugify(): Slugify 
    { 
        return $this->container->get('slugify'); 
    } 
 
    protected function geoIpReader(): Reader 
    { 
        return $this->container->get('geoip2.reader'); 
    } 
 
    private $parameterBag; 
 
    /** 
     * @param ParameterBagInterface $parameterBag 
     */ 
    public function setParameterBag(ParameterBagInterface $parameterBag) 
    { 
        $this->parameterBag = $parameterBag; 
    } 
 
    protected function parameterBag(): ParameterBagInterface 
    { 
        return $this->parameterBag; 
    } 
 
    protected $form; 
    protected $form_handler; 
    protected $form_errors = array(); 
    protected $errors = array(); 
 
    /** 
     * 
     * @param FormType $formType 
     * @param string $formName 
     * @param boolean $csrfProtection 
     * @return Form  
     */ 
    protected function getFormFactory() 
    { 
        return $this->formFactory(); 
    } 
 
    /** 
     *  
     * @param type $action 
     * @param type $value 
     */ 
    protected function setFlash($action, $value) 
    { 
        $this->session()->getFlashBag()->add($action, $value); 
    } 
 
    /** 
     *  
     * @param type $action 
     * @return type 
     */ 
    protected function getFlash($action) 
    { 
        $values = $this->session()->getFlashBag()->get($action); 
        if (empty($values)) { 
            return null; 
        } else if (\count($values) == 1) { 
            return $values[0]; 
        } else { 
            return $values; 
        } 
    } 
 
 
    /** 
     * Returns a rendered view. 
     * 
     * @param string $view       The view name 
     * @param array  $parameters An array of parameters to pass to the view 
     * 
     * @return string The rendered view 
     */ 
    protected function renderView(string $view, array $parameters = array()): string 
    { 
        return $this->templating()->render($view, $parameters); 
    } 
 
    /** 
     * Renders a view. 
     * 
     * @param string   $view       The view name 
     * @param array    $parameters An array of parameters to pass to the view 
     * @param Response $response   A response instance 
     * 
     * @return Response A Response instance 
     */ 
    protected function render(string $view, array $parameters = array(), Response $response = null): Response 
    { 
        if ($response == null) { 
            return new Response($this->templating()->render($view, $parameters)); 
        } else { 
            $response->setContent($this->templating()->render($view, $parameters)); 
            return $response; 
        } 
    } 
 
    /** 
     * Check if user has a role 
     *  
     * @return true|false 
     */ 
    protected function isGranted($attributes, $subject = null): bool 
    { 
        return $this->authorizationChecker()->isGranted($attributes, $subject); 
    } 
 
    /** 
     * Return the authenticated auth 
     *  
     * @return ?User 
     */ 
    protected function getGrantedAuth(): ?Auth 
    { 
        if (is_null($this->tokenStorage())) { 
            return null; 
        } 
 
        $token = $this->tokenStorage()->getToken(); 
 
        if (empty($token)) { 
            return null; 
        } 
 
        $auth = $token->getUser(); 
 
        if (empty($auth) || is_string($auth)) { 
            return null; 
        } 
 
        return $auth; 
    } 
 
    /** 
     * Return the authenticated user 
     *  
     * @return ?User 
     */ 
    protected function getGrantedUser(): ?User 
    { 
        $auth = $this->getGrantedAuth(); 
 
        if (empty($auth)) { 
            return null; 
        } 
 
        return $auth->user(); 
    } 
 
    /** 
     * Bad Request response 
     * 
     * @param string $data 
     * 
     * @return View  
     */ 
    protected function sendBadRequestResponse($data = null) 
    { 
        $view = View::create(); 
        $view->setStatusCode(400); 
        $view->setData(array('message' => $data)); 
 
        return $this->viewHandler()->handle($view); 
    } 
 
    /** 
     * Unauthorized Request response 
     * 
     * @param string $data 
     * 
     * @return View  
     */ 
    protected function sendUnauthorizedRequestResponse($data = null) 
    { 
        $view = View::create(); 
        $view->setStatusCode(401); 
        $view->setData(array('message' => $data)); 
 
        return $this->viewHandler()->handle($view); 
    } 
}