2016-03-16 07:48:30 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Bundle\FrameworkBundle\Controller ;
2017-10-28 19:50:41 +01:00
use Doctrine\Common\Persistence\ManagerRegistry ;
2017-05-05 11:24:11 +01:00
use Psr\Container\ContainerInterface ;
2016-03-16 07:48:30 +00:00
use Symfony\Component\HttpFoundation\BinaryFileResponse ;
use Symfony\Component\HttpFoundation\JsonResponse ;
use Symfony\Component\HttpFoundation\Response ;
use Symfony\Component\HttpFoundation\RedirectResponse ;
use Symfony\Component\HttpFoundation\ResponseHeaderBag ;
use Symfony\Component\HttpFoundation\StreamedResponse ;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException ;
use Symfony\Component\HttpKernel\HttpKernelInterface ;
use Symfony\Component\Security\Core\Exception\AccessDeniedException ;
use Symfony\Component\Security\Csrf\CsrfToken ;
2017-03-25 12:43:01 +00:00
use Symfony\Component\Form\Extension\Core\Type\FormType ;
2017-10-28 19:50:41 +01:00
use Symfony\Component\Form\FormInterface ;
use Symfony\Component\Form\FormBuilderInterface ;
2016-03-16 07:48:30 +00:00
use Symfony\Component\Routing\Generator\UrlGeneratorInterface ;
/**
* Common features needed in controllers .
*
* @ author Fabien Potencier < fabien @ symfony . com >
*
2017-03-25 12:43:01 +00:00
* @ internal
2017-05-05 11:24:11 +01:00
*
* @ property ContainerInterface $container
2016-03-16 07:48:30 +00:00
*/
trait ControllerTrait
{
2017-10-03 10:44:07 +01:00
/**
* Returns true if the service id is defined .
*
* @ final since version 3.4
*/
2017-10-28 19:15:32 +01:00
protected function has ( string $id ) : bool
2017-10-03 10:44:07 +01:00
{
return $this -> container -> has ( $id );
}
/**
* Gets a container service by its id .
*
* @ return object The service
*
* @ final since version 3.4
*/
2017-10-28 19:15:32 +01:00
protected function get ( string $id )
2017-10-03 10:44:07 +01:00
{
return $this -> container -> get ( $id );
}
2016-03-16 07:48:30 +00:00
/**
* Generates a URL from the given parameters .
*
* @ see UrlGeneratorInterface
2017-10-03 10:44:07 +01:00
*
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function generateUrl ( string $route , array $parameters = array (), int $referenceType = UrlGeneratorInterface :: ABSOLUTE_PATH ) : string
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
return $this -> container -> get ( 'router' ) -> generate ( $route , $parameters , $referenceType );
2016-03-16 07:48:30 +00:00
}
/**
* Forwards the request to another controller .
*
* @ param string $controller The controller name ( a string like BlogBundle : Post : index )
2017-10-03 10:44:07 +01:00
*
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function forward ( string $controller , array $path = array (), array $query = array ()) : Response
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
$request = $this -> container -> get ( 'request_stack' ) -> getCurrentRequest ();
2016-03-16 07:48:30 +00:00
$path [ '_forwarded' ] = $request -> attributes ;
$path [ '_controller' ] = $controller ;
$subRequest = $request -> duplicate ( $query , null , $path );
2017-03-25 12:43:01 +00:00
return $this -> container -> get ( 'http_kernel' ) -> handle ( $subRequest , HttpKernelInterface :: SUB_REQUEST );
2016-03-16 07:48:30 +00:00
}
/**
* Returns a RedirectResponse to the given URL .
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function redirect ( string $url , int $status = 302 ) : RedirectResponse
2016-03-16 07:48:30 +00:00
{
return new RedirectResponse ( $url , $status );
}
/**
* Returns a RedirectResponse to the given route with the given parameters .
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function redirectToRoute ( string $route , array $parameters = array (), int $status = 302 ) : RedirectResponse
2016-03-16 07:48:30 +00:00
{
return $this -> redirect ( $this -> generateUrl ( $route , $parameters ), $status );
}
/**
2017-03-25 12:43:01 +00:00
* Returns a JsonResponse that uses the serializer component if enabled , or json_encode .
2016-03-16 07:48:30 +00:00
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function json ( $data , int $status = 200 , array $headers = array (), array $context = array ()) : JsonResponse
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
if ( $this -> container -> has ( 'serializer' )) {
$json = $this -> container -> get ( 'serializer' ) -> serialize ( $data , 'json' , array_merge ( array (
'json_encode_options' => JsonResponse :: DEFAULT_ENCODING_OPTIONS ,
), $context ));
2016-03-16 07:48:30 +00:00
2017-03-25 12:43:01 +00:00
return new JsonResponse ( $json , $status , $headers , true );
}
return new JsonResponse ( $data , $status , $headers );
2016-03-16 07:48:30 +00:00
}
/**
* Returns a BinaryFileResponse object with original or customized file name and disposition header .
*
2017-10-28 19:15:32 +01:00
* @ param \SplFileInfo | string $file File object or path to file to be sent as response
2017-10-03 10:44:07 +01:00
*
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function file ( $file , string $fileName = null , string $disposition = ResponseHeaderBag :: DISPOSITION_ATTACHMENT ) : BinaryFileResponse
2016-03-16 07:48:30 +00:00
{
$response = new BinaryFileResponse ( $file );
2017-09-15 11:08:59 +01:00
$response -> setContentDisposition ( $disposition , null === $fileName ? $response -> getFile () -> getFilename () : $fileName );
2016-03-16 07:48:30 +00:00
return $response ;
}
/**
* Adds a flash message to the current session for type .
*
* @ throws \LogicException
2017-10-03 10:44:07 +01:00
*
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function addFlash ( string $type , string $message )
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
if ( ! $this -> container -> has ( 'session' )) {
2017-11-23 12:12:55 +00:00
throw new \LogicException ( 'You can not use the addFlash method if sessions are disabled. Enable them in config/packages/framework.yaml.' );
2017-03-21 17:12:21 +00:00
}
2017-03-25 12:43:01 +00:00
$this -> container -> get ( 'session' ) -> getFlashBag () -> add ( $type , $message );
2016-03-16 07:48:30 +00:00
}
/**
2017-06-15 17:40:16 +01:00
* Checks if the attributes are granted against the current authentication token and optionally supplied subject .
2016-03-16 07:48:30 +00:00
*
2017-03-25 12:43:01 +00:00
* @ throws \LogicException
2017-10-03 10:44:07 +01:00
*
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function isGranted ( $attributes , $subject = null ) : bool
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
if ( ! $this -> container -> has ( 'security.authorization_checker' )) {
2017-11-23 12:12:55 +00:00
throw new \LogicException ( 'The SecurityBundle is not registered in your application. Try running "composer require security"' );
2017-03-25 12:43:01 +00:00
}
2017-06-15 17:40:16 +01:00
return $this -> container -> get ( 'security.authorization_checker' ) -> isGranted ( $attributes , $subject );
2016-03-16 07:48:30 +00:00
}
/**
* Throws an exception unless the attributes are granted against the current authentication token and optionally
2017-06-15 17:40:16 +01:00
* supplied subject .
2016-03-16 07:48:30 +00:00
*
* @ throws AccessDeniedException
2017-10-03 10:44:07 +01:00
*
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function denyAccessUnlessGranted ( $attributes , $subject = null , string $message = 'Access Denied.' )
2016-03-16 07:48:30 +00:00
{
2017-06-15 17:40:16 +01:00
if ( ! $this -> isGranted ( $attributes , $subject )) {
2016-03-16 07:48:30 +00:00
$exception = $this -> createAccessDeniedException ( $message );
$exception -> setAttributes ( $attributes );
2017-06-15 17:40:16 +01:00
$exception -> setSubject ( $subject );
2017-03-25 12:43:01 +00:00
2016-03-16 07:48:30 +00:00
throw $exception ;
}
}
/**
* Returns a rendered view .
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function renderView ( string $view , array $parameters = array ()) : string
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
if ( $this -> container -> has ( 'templating' )) {
return $this -> container -> get ( 'templating' ) -> render ( $view , $parameters );
}
if ( ! $this -> container -> has ( 'twig' )) {
2017-11-23 12:12:55 +00:00
throw new \LogicException ( 'You can not use the "renderView" method if the Templating Component or the Twig Bundle are not available. Try running "composer require twig"' );
2017-03-25 12:43:01 +00:00
}
return $this -> container -> get ( 'twig' ) -> render ( $view , $parameters );
2016-03-16 07:48:30 +00:00
}
/**
* Renders a view .
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function render ( string $view , array $parameters = array (), Response $response = null ) : Response
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
if ( $this -> container -> has ( 'templating' )) {
2017-10-05 09:44:57 +01:00
$content = $this -> container -> get ( 'templating' ) -> render ( $view , $parameters );
} elseif ( $this -> container -> has ( 'twig' )) {
$content = $this -> container -> get ( 'twig' ) -> render ( $view , $parameters );
} else {
2017-11-23 12:12:55 +00:00
throw new \LogicException ( 'You can not use the "render" method if the Templating Component or the Twig Bundle are not available. Try running "composer require twig"' );
2017-03-25 12:43:01 +00:00
}
2016-03-16 07:48:30 +00:00
if ( null === $response ) {
$response = new Response ();
}
2017-10-05 09:44:57 +01:00
$response -> setContent ( $content );
2017-03-25 12:43:01 +00:00
return $response ;
2016-03-16 07:48:30 +00:00
}
/**
* Streams a view .
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function stream ( string $view , array $parameters = array (), StreamedResponse $response = null ) : StreamedResponse
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
if ( $this -> container -> has ( 'templating' )) {
$templating = $this -> container -> get ( 'templating' );
$callback = function () use ( $templating , $view , $parameters ) {
$templating -> stream ( $view , $parameters );
};
} elseif ( $this -> container -> has ( 'twig' )) {
$twig = $this -> container -> get ( 'twig' );
$callback = function () use ( $twig , $view , $parameters ) {
$twig -> display ( $view , $parameters );
};
} else {
2017-11-23 12:12:55 +00:00
throw new \LogicException ( 'You can not use the "stream" method if the Templating Component or the Twig Bundle are not available. Try running "composer require twig"' );
2017-03-25 12:43:01 +00:00
}
2016-03-16 07:48:30 +00:00
if ( null === $response ) {
return new StreamedResponse ( $callback );
}
$response -> setCallback ( $callback );
return $response ;
}
/**
* Returns a NotFoundHttpException .
*
* This will result in a 404 response code . Usage example :
*
* throw $this -> createNotFoundException ( 'Page not found!' );
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function createNotFoundException ( string $message = 'Not Found' , \Exception $previous = null ) : NotFoundHttpException
2016-03-16 07:48:30 +00:00
{
return new NotFoundHttpException ( $message , $previous );
}
/**
* Returns an AccessDeniedException .
*
* This will result in a 403 response code . Usage example :
*
* throw $this -> createAccessDeniedException ( 'Unable to access this page!' );
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function createAccessDeniedException ( string $message = 'Access Denied.' , \Exception $previous = null ) : AccessDeniedException
2016-03-16 07:48:30 +00:00
{
return new AccessDeniedException ( $message , $previous );
}
/**
* Creates and returns a Form instance from the type of the form .
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function createForm ( string $type , $data = null , array $options = array ()) : FormInterface
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
return $this -> container -> get ( 'form.factory' ) -> create ( $type , $data , $options );
2016-03-16 07:48:30 +00:00
}
/**
* Creates and returns a form builder instance .
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function createFormBuilder ( $data = null , array $options = array ()) : FormBuilderInterface
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
return $this -> container -> get ( 'form.factory' ) -> createBuilder ( FormType :: class , $data , $options );
}
/**
* Shortcut to return the Doctrine Registry service .
*
* @ throws \LogicException If DoctrineBundle is not available
2017-10-03 10:44:07 +01:00
*
* @ final since version 3.4
2017-03-25 12:43:01 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function getDoctrine () : ManagerRegistry
2017-03-25 12:43:01 +00:00
{
if ( ! $this -> container -> has ( 'doctrine' )) {
2017-11-23 12:12:55 +00:00
throw new \LogicException ( 'The DoctrineBundle is not registered in your application. Try running "composer require doctrine"' );
2017-03-25 12:43:01 +00:00
}
return $this -> container -> get ( 'doctrine' );
2016-03-16 07:48:30 +00:00
}
/**
* Get a user from the Security Token Storage .
*
* @ return mixed
*
2017-03-25 12:43:01 +00:00
* @ throws \LogicException If SecurityBundle is not available
*
2016-03-16 07:48:30 +00:00
* @ see TokenInterface :: getUser ()
2017-10-03 10:44:07 +01:00
*
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
protected function getUser ()
{
2017-03-25 12:43:01 +00:00
if ( ! $this -> container -> has ( 'security.token_storage' )) {
2017-11-23 12:12:55 +00:00
throw new \LogicException ( 'The SecurityBundle is not registered in your application. Try running "composer require security"' );
2017-03-25 12:43:01 +00:00
}
if ( null === $token = $this -> container -> get ( 'security.token_storage' ) -> getToken ()) {
2016-03-16 07:48:30 +00:00
return ;
}
if ( ! is_object ( $user = $token -> getUser ())) {
// e.g. anonymous authentication
return ;
}
return $user ;
}
/**
* Checks the validity of a CSRF token .
*
* @ param string $id The id used when generating the token
* @ param string $token The actual token sent with the request that should be validated
*
2017-10-03 10:44:07 +01:00
* @ final since version 3.4
2016-03-16 07:48:30 +00:00
*/
2017-10-28 19:15:32 +01:00
protected function isCsrfTokenValid ( string $id , string $token ) : bool
2016-03-16 07:48:30 +00:00
{
2017-03-25 12:43:01 +00:00
if ( ! $this -> container -> has ( 'security.csrf.token_manager' )) {
2017-11-23 12:12:55 +00:00
throw new \LogicException ( 'CSRF protection is not enabled in your application. Enable it with the "csrf_protection" key in "config/packages/framework.yaml"' );
2017-03-25 12:43:01 +00:00
}
return $this -> container -> get ( 'security.csrf.token_manager' ) -> isTokenValid ( new CsrfToken ( $id , $token ));
2016-03-16 07:48:30 +00:00
}
}