vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php line 234

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Bundle\FrameworkBundle\Controller;
  11. use Doctrine\Common\Persistence\ManagerRegistry;
  12. use Psr\Container\ContainerInterface;
  13. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  14. use Symfony\Component\HttpFoundation\JsonResponse;
  15. use Symfony\Component\HttpFoundation\Response;
  16. use Symfony\Component\HttpFoundation\RedirectResponse;
  17. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  18. use Symfony\Component\HttpFoundation\StreamedResponse;
  19. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  20. use Symfony\Component\HttpKernel\HttpKernelInterface;
  21. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  22. use Symfony\Component\Security\Csrf\CsrfToken;
  23. use Symfony\Component\Form\Extension\Core\Type\FormType;
  24. use Symfony\Component\Form\FormInterface;
  25. use Symfony\Component\Form\FormBuilderInterface;
  26. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  27. /**
  28.  * Common features needed in controllers.
  29.  *
  30.  * @author Fabien Potencier <fabien@symfony.com>
  31.  *
  32.  * @internal
  33.  *
  34.  * @property ContainerInterface $container
  35.  */
  36. trait ControllerTrait
  37. {
  38.     /**
  39.      * Generates a URL from the given parameters.
  40.      *
  41.      * @param string $route         The name of the route
  42.      * @param array  $parameters    An array of parameters
  43.      * @param int    $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
  44.      *
  45.      * @return string The generated URL
  46.      *
  47.      * @see UrlGeneratorInterface
  48.      */
  49.     protected function generateUrl($route$parameters = array(), $referenceType UrlGeneratorInterface::ABSOLUTE_PATH)
  50.     {
  51.         return $this->container->get('router')->generate($route$parameters$referenceType);
  52.     }
  53.     /**
  54.      * Forwards the request to another controller.
  55.      *
  56.      * @param string $controller The controller name (a string like BlogBundle:Post:index)
  57.      * @param array  $path       An array of path parameters
  58.      * @param array  $query      An array of query parameters
  59.      *
  60.      * @return Response A Response instance
  61.      */
  62.     protected function forward($controller, array $path = array(), array $query = array())
  63.     {
  64.         $request $this->container->get('request_stack')->getCurrentRequest();
  65.         $path['_forwarded'] = $request->attributes;
  66.         $path['_controller'] = $controller;
  67.         $subRequest $request->duplicate($querynull$path);
  68.         return $this->container->get('http_kernel')->handle($subRequestHttpKernelInterface::SUB_REQUEST);
  69.     }
  70.     /**
  71.      * Returns a RedirectResponse to the given URL.
  72.      *
  73.      * @param string $url    The URL to redirect to
  74.      * @param int    $status The status code to use for the Response
  75.      *
  76.      * @return RedirectResponse
  77.      */
  78.     protected function redirect($url$status 302)
  79.     {
  80.         return new RedirectResponse($url$status);
  81.     }
  82.     /**
  83.      * Returns a RedirectResponse to the given route with the given parameters.
  84.      *
  85.      * @param string $route      The name of the route
  86.      * @param array  $parameters An array of parameters
  87.      * @param int    $status     The status code to use for the Response
  88.      *
  89.      * @return RedirectResponse
  90.      */
  91.     protected function redirectToRoute($route, array $parameters = array(), $status 302)
  92.     {
  93.         return $this->redirect($this->generateUrl($route$parameters), $status);
  94.     }
  95.     /**
  96.      * Returns a JsonResponse that uses the serializer component if enabled, or json_encode.
  97.      *
  98.      * @param mixed $data    The response data
  99.      * @param int   $status  The status code to use for the Response
  100.      * @param array $headers Array of extra headers to add
  101.      * @param array $context Context to pass to serializer when using serializer component
  102.      *
  103.      * @return JsonResponse
  104.      */
  105.     protected function json($data$status 200$headers = array(), $context = array())
  106.     {
  107.         if ($this->container->has('serializer')) {
  108.             $json $this->container->get('serializer')->serialize($data'json'array_merge(array(
  109.                 'json_encode_options' => JsonResponse::DEFAULT_ENCODING_OPTIONS,
  110.             ), $context));
  111.             return new JsonResponse($json$status$headerstrue);
  112.         }
  113.         return new JsonResponse($data$status$headers);
  114.     }
  115.     /**
  116.      * Returns a BinaryFileResponse object with original or customized file name and disposition header.
  117.      *
  118.      * @param \SplFileInfo|string $file        File object or path to file to be sent as response
  119.      * @param string|null         $fileName    File name to be sent to response or null (will use original file name)
  120.      * @param string              $disposition Disposition of response ("attachment" is default, other type is "inline")
  121.      *
  122.      * @return BinaryFileResponse
  123.      */
  124.     protected function file($file$fileName null$disposition ResponseHeaderBag::DISPOSITION_ATTACHMENT)
  125.     {
  126.         $response = new BinaryFileResponse($file);
  127.         $response->setContentDisposition($dispositionnull === $fileName $response->getFile()->getFilename() : $fileName);
  128.         return $response;
  129.     }
  130.     /**
  131.      * Adds a flash message to the current session for type.
  132.      *
  133.      * @param string $type    The type
  134.      * @param string $message The message
  135.      *
  136.      * @throws \LogicException
  137.      */
  138.     protected function addFlash($type$message)
  139.     {
  140.         if (!$this->container->has('session')) {
  141.             throw new \LogicException('You can not use the addFlash method if sessions are disabled.');
  142.         }
  143.         $this->container->get('session')->getFlashBag()->add($type$message);
  144.     }
  145.     /**
  146.      * Checks if the attributes are granted against the current authentication token and optionally supplied object.
  147.      *
  148.      * @param mixed $attributes The attributes
  149.      * @param mixed $object     The object
  150.      *
  151.      * @return bool
  152.      *
  153.      * @throws \LogicException
  154.      */
  155.     protected function isGranted($attributes$object null)
  156.     {
  157.         if (!$this->container->has('security.authorization_checker')) {
  158.             throw new \LogicException('The SecurityBundle is not registered in your application.');
  159.         }
  160.         return $this->container->get('security.authorization_checker')->isGranted($attributes$object);
  161.     }
  162.     /**
  163.      * Throws an exception unless the attributes are granted against the current authentication token and optionally
  164.      * supplied object.
  165.      *
  166.      * @param mixed  $attributes The attributes
  167.      * @param mixed  $object     The object
  168.      * @param string $message    The message passed to the exception
  169.      *
  170.      * @throws AccessDeniedException
  171.      */
  172.     protected function denyAccessUnlessGranted($attributes$object null$message 'Access Denied.')
  173.     {
  174.         if (!$this->isGranted($attributes$object)) {
  175.             $exception $this->createAccessDeniedException($message);
  176.             $exception->setAttributes($attributes);
  177.             $exception->setSubject($object);
  178.             throw $exception;
  179.         }
  180.     }
  181.     /**
  182.      * Returns a rendered view.
  183.      *
  184.      * @param string $view       The view name
  185.      * @param array  $parameters An array of parameters to pass to the view
  186.      *
  187.      * @return string The rendered view
  188.      */
  189.     protected function renderView($view, array $parameters = array())
  190.     {
  191.         if ($this->container->has('templating')) {
  192.             return $this->container->get('templating')->render($view$parameters);
  193.         }
  194.         if (!$this->container->has('twig')) {
  195.             throw new \LogicException('You can not use the "renderView" method if the Templating Component or the Twig Bundle are not available.');
  196.         }
  197.         return $this->container->get('twig')->render($view$parameters);
  198.     }
  199.     /**
  200.      * Renders a view.
  201.      *
  202.      * @param string   $view       The view name
  203.      * @param array    $parameters An array of parameters to pass to the view
  204.      * @param Response $response   A response instance
  205.      *
  206.      * @return Response A Response instance
  207.      */
  208.     protected function render($view, array $parameters = array(), Response $response null)
  209.     {
  210.         if ($this->container->has('templating')) {
  211.             $content $this->container->get('templating')->render($view$parameters);
  212.         } elseif ($this->container->has('twig')) {
  213.             $content $this->container->get('twig')->render($view$parameters);
  214.         } else {
  215.             throw new \LogicException('You can not use the "render" method if the Templating Component or the Twig Bundle are not available.');
  216.         }
  217.         if (null === $response) {
  218.             $response = new Response();
  219.         }
  220.         $response->setContent($content);
  221.         return $response;
  222.     }
  223.     /**
  224.      * Streams a view.
  225.      *
  226.      * @param string           $view       The view name
  227.      * @param array            $parameters An array of parameters to pass to the view
  228.      * @param StreamedResponse $response   A response instance
  229.      *
  230.      * @return StreamedResponse A StreamedResponse instance
  231.      */
  232.     protected function stream($view, array $parameters = array(), StreamedResponse $response null)
  233.     {
  234.         if ($this->container->has('templating')) {
  235.             $templating $this->container->get('templating');
  236.             $callback = function () use ($templating$view$parameters) {
  237.                 $templating->stream($view$parameters);
  238.             };
  239.         } elseif ($this->container->has('twig')) {
  240.             $twig $this->container->get('twig');
  241.             $callback = function () use ($twig$view$parameters) {
  242.                 $twig->display($view$parameters);
  243.             };
  244.         } else {
  245.             throw new \LogicException('You can not use the "stream" method if the Templating Component or the Twig Bundle are not available.');
  246.         }
  247.         if (null === $response) {
  248.             return new StreamedResponse($callback);
  249.         }
  250.         $response->setCallback($callback);
  251.         return $response;
  252.     }
  253.     /**
  254.      * Returns a NotFoundHttpException.
  255.      *
  256.      * This will result in a 404 response code. Usage example:
  257.      *
  258.      *     throw $this->createNotFoundException('Page not found!');
  259.      *
  260.      * @param string          $message  A message
  261.      * @param \Exception|null $previous The previous exception
  262.      *
  263.      * @return NotFoundHttpException
  264.      */
  265.     protected function createNotFoundException($message 'Not Found', \Exception $previous null)
  266.     {
  267.         return new NotFoundHttpException($message$previous);
  268.     }
  269.     /**
  270.      * Returns an AccessDeniedException.
  271.      *
  272.      * This will result in a 403 response code. Usage example:
  273.      *
  274.      *     throw $this->createAccessDeniedException('Unable to access this page!');
  275.      *
  276.      * @param string          $message  A message
  277.      * @param \Exception|null $previous The previous exception
  278.      *
  279.      * @return AccessDeniedException
  280.      */
  281.     protected function createAccessDeniedException($message 'Access Denied.', \Exception $previous null)
  282.     {
  283.         return new AccessDeniedException($message$previous);
  284.     }
  285.     /**
  286.      * Creates and returns a Form instance from the type of the form.
  287.      *
  288.      * @param string $type    The fully qualified class name of the form type
  289.      * @param mixed  $data    The initial data for the form
  290.      * @param array  $options Options for the form
  291.      *
  292.      * @return FormInterface
  293.      */
  294.     protected function createForm($type$data null, array $options = array())
  295.     {
  296.         return $this->container->get('form.factory')->create($type$data$options);
  297.     }
  298.     /**
  299.      * Creates and returns a form builder instance.
  300.      *
  301.      * @param mixed $data    The initial data for the form
  302.      * @param array $options Options for the form
  303.      *
  304.      * @return FormBuilderInterface
  305.      */
  306.     protected function createFormBuilder($data null, array $options = array())
  307.     {
  308.         return $this->container->get('form.factory')->createBuilder(FormType::class, $data$options);
  309.     }
  310.     /**
  311.      * Shortcut to return the Doctrine Registry service.
  312.      *
  313.      * @return ManagerRegistry
  314.      *
  315.      * @throws \LogicException If DoctrineBundle is not available
  316.      */
  317.     protected function getDoctrine()
  318.     {
  319.         if (!$this->container->has('doctrine')) {
  320.             throw new \LogicException('The DoctrineBundle is not registered in your application.');
  321.         }
  322.         return $this->container->get('doctrine');
  323.     }
  324.     /**
  325.      * Get a user from the Security Token Storage.
  326.      *
  327.      * @return mixed
  328.      *
  329.      * @throws \LogicException If SecurityBundle is not available
  330.      *
  331.      * @see TokenInterface::getUser()
  332.      */
  333.     protected function getUser()
  334.     {
  335.         if (!$this->container->has('security.token_storage')) {
  336.             throw new \LogicException('The SecurityBundle is not registered in your application.');
  337.         }
  338.         if (null === $token $this->container->get('security.token_storage')->getToken()) {
  339.             return;
  340.         }
  341.         if (!is_object($user $token->getUser())) {
  342.             // e.g. anonymous authentication
  343.             return;
  344.         }
  345.         return $user;
  346.     }
  347.     /**
  348.      * Checks the validity of a CSRF token.
  349.      *
  350.      * @param string $id    The id used when generating the token
  351.      * @param string $token The actual token sent with the request that should be validated
  352.      *
  353.      * @return bool
  354.      */
  355.     protected function isCsrfTokenValid($id$token)
  356.     {
  357.         if (!$this->container->has('security.csrf.token_manager')) {
  358.             throw new \LogicException('CSRF protection is not enabled in your application.');
  359.         }
  360.         return $this->container->get('security.csrf.token_manager')->isTokenValid(new CsrfToken($id$token));
  361.     }
  362. }