Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[FrameworkBundle] Add new TemplateResponse class #21765

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ public function load(array $configs, ContainerBuilder $container)
$this->registerTemplatingConfiguration($config['templating'], $container, $loader);
}

if ($container->hasDefinition('twig')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the container will never have a Twig service here, as extensions can only see services they define themselves.

$loader->load('twig.xml');
}

$this->registerValidationConfiguration($config['validation'], $container, $loader);
$this->registerEsiConfiguration($config['esi'], $container, $loader);
$this->registerSsiConfiguration($config['ssi'], $container, $loader);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?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\EventListener;

use Symfony\Bundle\FrameworkBundle\Templating\TemplatedResponseInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\KernelEvents;

/**
* @author Pierre du Plessis <pdples@gmail.com>
*/
class TwigTemplateListener implements EventSubscriberInterface
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A Twig listener should be in TwigBundle or in the Twig bridge (if it depends on FramworkBundle, it should be in TwigBundle).
FrameworkBundle is not allowed to depend on Twig.

{
private $twig;

public function __construct(\Twig_Environment $twig)
{
$this->twig = $twig;
}

public static function getSubscribedEvents()
{
return array(
KernelEvents::VIEW => array('onView', 128),
);
}

public function onView(GetResponseForControllerResultEvent $event)
{
$result = $event->getControllerResult();

if (!$result instanceof TemplatedResponseInterface) {
return;
}

$response = $result->getResponse($this->twig);

if (!$response instanceof Response) {
$msg = sprintf('The method %s::getResponse() must return a response (%s given).', get_class($result), is_object($response) ? get_class($response) : gettype($response));

throw new \LogicException($msg);
}

$event->setResponse($response);
}
}
13 changes: 13 additions & 0 deletions 13 src/Symfony/Bundle/FrameworkBundle/Resources/config/twig.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<service id="twig.templating.listener" class="Symfony\Bundle\FrameworkBundle\EventListener\TwigTemplateListener">
<tag name="kernel.event_subscriber" />
<argument type="service" id="twig" />
</service>
</services>
</container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?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\Templating;

use Symfony\Component\HttpFoundation\Response;

/**
* @author Pierre du Plessis <pdples@gmail.com>
*/
class TemplatedResponse implements TemplatedResponseInterface
{
private $template;
private $parameters;
private $response;

public function __construct($template, array $parameters = array(), Response $response = null)
{
$this->template = $template;
$this->parameters = $parameters;
$this->response = $response ?: new Response();
}

/**
* {@inheritdoc}
*/
public function getResponse(\Twig_Environment $twig)
{
$this->response->setContent($twig->render($this->template, $this->parameters));

return $this->response;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?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\Templating;

use Symfony\Component\HttpFoundation\Response;

/**
* @author Pierre du Plessis <pdples@gmail.com>
*/
interface TemplatedResponseInterface
{
/**
* @param \Twig_Environment $twig
*
* @return Response
*/
public function getResponse(\Twig_Environment $twig);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this interface depends on Twig, so it cannot be in FrameworkBundle

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?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\Tests\EventListener;

use Symfony\Bundle\FrameworkBundle\EventListener\TwigTemplateListener;
use Symfony\Bundle\FrameworkBundle\Templating\TemplatedResponse;
use Symfony\Bundle\FrameworkBundle\Templating\TemplatedResponseInterface;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Kernel;

class TwigTemplateListenerTest extends TestCase
{
public function testTemplateReference()
{
$template = new TemplatedResponse('dummy_template.html.php', array('var' => 'dummy'));

$event = $this->getEvent($template);

$twig = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock();
$twig->expects($this->once())
->method('render')
->willReturn('This is dummy content');

$listener = new TwigTemplateListener($twig);
$listener->onView($event);

$response = $event->getResponse();

$this->assertSame('This is dummy content', $response->getContent());
$this->assertSame(200, $response->getStatusCode());
}

public function testInvalidResponse()
{
$twig = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock();

$template = $this->getMockBuilder(TemplatedResponseInterface::class)->getMock();
$template->expects($this->once())
->method('getResponse')
->with($twig)
->will($this->throwException(new \LogicException()));

$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('LogicException');

$event = $this->getEvent($template);

$listener = new TwigTemplateListener($twig);
$listener->onView($event);
}

private function getEvent($template)
{
$request = new Request(array(), array(), array());
$mockKernel = $this->getMockForAbstractClass('Symfony\Component\HttpKernel\Kernel', array('', ''));

return new GetResponseForControllerResultEvent($mockKernel, $request, Kernel::MASTER_REQUEST, $template);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?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\Tests\Templating;

use Symfony\Bundle\FrameworkBundle\Templating\TemplatedResponse;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Component\HttpFoundation\Response;

class TemplatedResponseTest extends TestCase
{
public function testResponse()
{
$templating = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock();

$templating->expects($this->once())
->method('render')
->with('dummy_template.html.twig', array('var' => 'dummy'))
->will($this->returnValue(new Response()));

$templateResponse = new TemplatedResponse('dummy_template.html.twig', array('var' => 'dummy'));

$this->assertInstanceOf(Response::class, $templateResponse->getResponse($templating));
}

public function testSameResponse()
{
$templating = $this->getMockBuilder('Twig_Environment')->disableOriginalConstructor()->getMock();

$response = new Response();
$templating->expects($this->once())
->method('render')
->with('dummy_template.html.twig', array('var' => 'dummy'))
->will($this->returnValue($response));

$templateResponse = new TemplatedResponse('dummy_template.html.twig', array('var' => 'dummy'), $response);

$this->assertSame($response, $templateResponse->getResponse($templating));
}
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.