-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[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
Changes from all commits
ec36c71
f9e2e6e
0689f35
4019f25
a4e36ca
6793c4d
2c1dd08
92867c2
e2bee38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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). |
||
{ | ||
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); | ||
} | ||
} |
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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)); | ||
} | ||
} |
There was a problem hiding this comment.
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.