vendor/sensio/framework-extra-bundle/EventListener/TemplateListener.php line 77

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony framework.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * This source file is subject to the MIT license that is bundled
  8.  * with this source code in the file LICENSE.
  9.  */
  10. namespace Sensio\Bundle\FrameworkExtraBundle\EventListener;
  11. use Symfony\Component\DependencyInjection\ContainerInterface;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
  14. use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
  15. use Symfony\Component\HttpKernel\KernelEvents;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. use Symfony\Component\HttpFoundation\StreamedResponse;
  18. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  19. /**
  20.  * Handles the Template annotation for actions.
  21.  *
  22.  * Depends on pre-processing of the ControllerListener.
  23.  *
  24.  * @author Fabien Potencier <fabien@symfony.com>
  25.  */
  26. class TemplateListener implements EventSubscriberInterface
  27. {
  28.     /**
  29.      * @var ContainerInterface
  30.      */
  31.     protected $container;
  32.     /**
  33.      * Constructor.
  34.      *
  35.      * @param ContainerInterface $container The service container instance
  36.      */
  37.     public function __construct(ContainerInterface $container)
  38.     {
  39.         $this->container $container;
  40.     }
  41.     /**
  42.      * Guesses the template name to render and its variables and adds them to
  43.      * the request object.
  44.      *
  45.      * @param FilterControllerEvent $event A FilterControllerEvent instance
  46.      */
  47.     public function onKernelController(FilterControllerEvent $event)
  48.     {
  49.         $request $event->getRequest();
  50.         $template $request->attributes->get('_template');
  51.         if (!$template instanceof Template) {
  52.             return;
  53.         }
  54.         $template->setOwner($controller $event->getController());
  55.         // when no template has been given, try to resolve it based on the controller
  56.         if (null === $template->getTemplate()) {
  57.             $guesser $this->container->get('sensio_framework_extra.view.guesser');
  58.             $template->setTemplate($guesser->guessTemplateName($controller$request$template->getEngine()));
  59.         }
  60.     }
  61.     /**
  62.      * Renders the template and initializes a new response object with the
  63.      * rendered template content.
  64.      *
  65.      * @param GetResponseForControllerResultEvent $event
  66.      */
  67.     public function onKernelView(GetResponseForControllerResultEvent $event)
  68.     {
  69.         /* @var Template $template */
  70.         $request $event->getRequest();
  71.         $template $request->attributes->get('_template');
  72.         if (!$template instanceof Template) {
  73.             return;
  74.         }
  75.         $parameters $event->getControllerResult();
  76.         $owner $template->getOwner();
  77.         list($controller$action) = $owner;
  78.         // when the annotation declares no default vars and the action returns
  79.         // null, all action method arguments are used as default vars
  80.         if (null === $parameters) {
  81.             $parameters $this->resolveDefaultParameters($request$template$controller$action);
  82.         }
  83.         // attempt to render the actual response
  84.         $templating $this->container->get('templating');
  85.         if ($template->isStreamable()) {
  86.             $callback = function () use ($templating$template$parameters) {
  87.                 return $templating->stream($template->getTemplate(), $parameters);
  88.             };
  89.             $event->setResponse(new StreamedResponse($callback));
  90.         } else {
  91.             $event->setResponse($templating->renderResponse($template->getTemplate(), $parameters));
  92.         }
  93.         // make sure the owner (controller+dependencies) is not cached or stored elsewhere
  94.         $template->setOwner(array());
  95.     }
  96.     public static function getSubscribedEvents()
  97.     {
  98.         return array(
  99.             KernelEvents::CONTROLLER => array('onKernelController', -128),
  100.             KernelEvents::VIEW => 'onKernelView',
  101.         );
  102.     }
  103.     /**
  104.      * @param Request  $request
  105.      * @param Template $template
  106.      * @param object   $controller
  107.      * @param string   $action
  108.      *
  109.      * @return array
  110.      */
  111.     private function resolveDefaultParameters(Request $requestTemplate $template$controller$action)
  112.     {
  113.         $parameters = array();
  114.         $arguments $template->getVars();
  115.         if (=== count($arguments)) {
  116.             $r = new \ReflectionObject($controller);
  117.             $arguments = array();
  118.             foreach ($r->getMethod($action)->getParameters() as $param) {
  119.                 $arguments[] = $param;
  120.             }
  121.         }
  122.         // fetch the arguments of @Template.vars or everything if desired
  123.         // and assign them to the designated template
  124.         foreach ($arguments as $argument) {
  125.             if ($argument instanceof \ReflectionParameter) {
  126.                 $parameters[$name $argument->getName()] = !$request->attributes->has($name) && $argument->isDefaultValueAvailable() ? $argument->getDefaultValue() : $request->attributes->get($name);
  127.             } else {
  128.                 $parameters[$argument] = $request->attributes->get($argument);
  129.             }
  130.         }
  131.         return $parameters;
  132.     }
  133. }