8000 added a RequestStack class · symfony/symfony@c55f1ea · GitHub
[go: up one dir, main page]

Skip to content

Commit c55f1ea

Browse files
beberleifabpot
authored andcommitted
added a RequestStack class
1 parent 08ec911 commit c55f1ea

File tree

19 files changed

+477
-139
lines changed

19 files changed

+477
-139
lines changed

src/Symfony/Bridge/Twig/Tests/Extension/HttpKernelExtensionTest.php

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
use Symfony\Bridge\Twig\Extension\HttpKernelExtension;
1515
use Symfony\Bridge\Twig\Tests\TestCase;
1616
use Symfony\Component\HttpFoundation\Request;
17+
use Symfony\Component\HttpFoundation\Response;
1718
use Symfony\Component\HttpKernel\Fragment\FragmentHandler;
19+
use Symfony\Component\HttpKernel\RequestContext;
1820

1921
class HttpKernelExtensionTest extends TestCase
2022
{
@@ -23,13 +25,30 @@ class HttpKernelExtensionTest extends TestCase
2325
*/
2426
public function testFragmentWithError()
2527
{
26-
$kernel = $this->getFragmentHandler($this->throwException(new \Exception('foo')));
28+
$renderer = $this->getFragmentHandler($this->throwException(new \Exception('foo')));
2729

28-
$loader = new \Twig_Loader_Array(array('index' => '{{ fragment("foo") }}'));
29-
$twig = new \Twig_Environment($loader, array('debug' => true, 'cache' => false));
30-
$twig->addExtension(new HttpKernelExtension($kernel));
30+
$this->renderTemplate($renderer);
31+
}
32+
33+
public function testRenderFragment()
34+
{
35+
$renderer = $this->getFragmentHandler($this->returnValue(new Response('html')));
36+
37+
$response = $this->renderTemplate($renderer);
3138

32-
$this->renderTemplate($kernel);
39+
$this->assertEquals('html', $response);
40+
}
41+
42+
public function testUnknownFragmentRenderer()
43+
{
44+
$context = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\RequestContext')
45+
->disableOriginalConstructor()
46+
->getMock()
47+
;
48+
$renderer = new FragmentHandler($context, array());
49+
50+
$this->setExpectedException('InvalidArgumentException', 'The "inline" renderer does not exist.');
51+
$renderer->render('/foo');
3352
}
3453

3554
protected function getFragmentHandler($return)
@@ -38,8 +57,14 @@ protected function getFragmentHandler($return)
3857
$strategy->expects($this->once())->method('getName')->will($this->returnValue('inline'));
3958
$strategy->expects($this->once())->method('render')->will($return);
4059

41-
$renderer = new FragmentHandler(array($strategy));
42-
$renderer->setRequest(Request::create('/'));
60+
$context = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\RequestContext')
61+
->disableOriginalConstructor()
62+
->getMock()
63+
;
64+
65+
$context->expects($this->any())->method('getCurrentRequest')->will($this->returnValue(Request::create('/')));
66+
67+
$renderer = new FragmentHandler($context, array($strategy));
4368

4469
return $renderer;
4570
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/fragment_renderer.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515

1616
<services>
1717
<service id="fragment.handler" class="%fragment.handler.class%">
18+
<argument type="service" id="request_context" />
1819
<argument type="collection" />
1920
<argument>%kernel.debug%</argument>
20-
<call method="setRequest"><argument type="service" id="request" on-invalid="null" strict="false" /></call>
2121
</service>
2222

2323
<service id="fragment.renderer.inline" class="%fragment.renderer.inline.class%">

src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@
9292
<tag name="kernel.event_subscriber" />
9393
<tag name="monolog.logger" channel="request" />
9494
<argument type="service" id="router" />
95+
<argument type="service" id="request_context" />
9596
<argument type="service" id="router.request_context" on-invalid="ignore" />
9697
<argument type="service" id="logger" on-invalid="ignore" />
97-
<call method="setRequest"><argument type="service" id="request" on-invalid="null" strict="false" /></call>
9898
</service>
9999
</services>
100100
</container>

src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
<parameter key="cache_clearer.class">Symfony\Component\HttpKernel\CacheClearer\ChainCacheClearer</parameter>
1313
<parameter key="file_locator.class">Symfony\Component\HttpKernel\Config\FileLocator</parameter>
1414
<parameter key="uri_signer.class">Symfony\Component\HttpKernel\UriSigner</parameter>
15+
<parameter key="request_stack.class">Symfony\Component\HttpKernel\RequestStack</parameter>
16+
<parameter key="request_context.class">Symfony\Component\HttpKernel\RequestContext</parameter>
1517
</parameters>
1618

1719
<services>
@@ -23,6 +25,14 @@
2325
<argument type="service" id="event_dispatcher" />
2426
<argument type="service" id="service_container" />
2527
<argument type="service" id="controller_resolver" />
28+
<argument type="service" id="request_stack" />
29+
</service>
30+
31+
<service id="request_stack" class="%request_stack.class%">
32+
</service>
33+
34+
<service id="request_context" class="%request_context.class%">
35+
<argument type="service" id="request_stack" />
2636
</service>
2737

2838
<service id="cache_warmer" class="%cache_warmer.class%">

src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
<service id="locale_listener" class="%locale_listener.class%">
3838
<tag name="kernel.event_subscriber" />
3939
<argument>%kernel.default_locale%</argument>
40+
<argument type="service" id="request_context" />
4041
<argument type="service" id="router" on-invalid="ignore" />
41-
<call method="setRequest"><argument type="service" id="request" on-invalid="null" strict="false" /></call>
4242
</service>
4343
</services>
4444
</container>

src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\HttpFoundation\Request;
1515
use Symfony\Component\HttpKernel\HttpKernelInterface;
1616
use Symfony\Component\HttpKernel\HttpKernel;
17+
use Symfony\Component\HttpKernel\RequestStack;
1718
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
1819
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1920
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -28,17 +29,19 @@
2829
class ContainerAwareHttpKernel extends HttpKernel
2930
{
3031
protected $container;
32+
protected $requestStack;
3133

3234
/**
3335
* Constructor.
3436
*
3537
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
3638
* @param ContainerInterface $container A ContainerInterface instance
3739
* @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance
40+
* @param RequestStack $requestStack A stack for master/sub requests
3841
*/
39-
public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver)
42+
public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack)
4043
{
41-
parent::__construct($dispatcher, $controllerResolver);
44+
parent::__construct($dispatcher, $controllerResolver, $requestStack);
4245

4346
$this->container = $container;
4447

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpKernel\Event;
13+
14+
/**
15+
* Triggered whenever a request is fully processed.
16+
*
17+
* @author Benjamin Eberlei <kontakt@beberlei.de>
18+
*/
19+
class RequestFinishedEvent extends KernelEvent
20+
{
21+
}

src/Symfony/Component/HttpKernel/EventListener/LocaleListener.php

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
namespace Symfony\Component\HttpKernel\EventListener;
1313

1414
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
15+
use Symfony\Component\HttpKernel\Event\RequestFinishedEvent;
1516
use Symfony\Component\HttpKernel\KernelEvents;
17+
use Symfony\Component\HttpKernel\RequestContext;
1618
use Symfony\Component\HttpFoundation\Request;
1719
use Symfony\Component\Routing\RequestContextAwareInterface;
1820
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -26,41 +28,64 @@ class LocaleListener implements EventSubscriberInterface
2628
{
2729
private $router;
2830
private $defaultLocale;
31+
private $requestContext;
2932

30-
public function __construct($defaultLocale = 'en', RequestContextAwareInterface $router = null)
33+
public function __construct($defaultLocale = 'en', RequestContext $requestContext, RequestContextAwareInterface $router = null)
3134
{
3235
$this->defaultLocale = $defaultLocale;
36+
$this->requestContext = $requestContext;
3337
$this->router = $router;
3438
}
3539

36-
public function setRequest(Request $request = null)
40+
public function onKernelRequest(GetResponseEvent $event)
41+
{
42+
$request = $event->getRequest();
43+
$request->setDefaultLocale($this->defaultLocale);
44+
45+
$this->setLocale($request);
46+
$this->setRouterContext($request);
47+
}
48+
49+
public function onKernelRequestFinished(RequestFinishedEvent $event)
3750
{
38-
if (null === $request) {
51+
$this->resetRouterContext();
52+
}
53+
54+
private function resetRouterContext()
55+
{
56+
if ($this->requestContext === null) {
57+
return;
58+
}
59+
60+
$parentRequest = $this->requestContext->getParentRequest();
61+
62+
if ($parentRequest === null) {
3963
return;
4064
}
4165

66+
$this->setRouterContext($parentRequest);
67+
}
68+
69+
private function setLocale(Request $request)
70+
{
4271
if ($locale = $request->attributes->get('_locale')) {
4372
$request->setLocale($locale);
4473
}
74+
}
4575

76+
private function setRouterContext(Request $request)
77+
{
4678
if (null !== $this->router) {
4779
$this->router->getContext()->setParameter('_locale', $request->getLocale());
4880
}
4981
}
5082

51-
public function onKernelRequest(GetResponseEvent $event)
52-
{
53-
$request = $event->getRequest();
54-
$request->setDefaultLocale($this->defaultLocale);
55-
56-
$this->setRequest($request);
57-
}
58-
5983
public static function getSubscribedEvents()
6084
{
6185
return array(
6286
// must be registered after the Router to have access to the _locale
6387
KernelEvents::REQUEST => array(array('onKernelRequest', 16)),
88+
KernelEvents::REQUEST_FINISHED => array(array('onKernelRequestFinished', 0)),
6489
);
6590
}
6691
}

src/Symfony/Component/HttpKernel/EventListener/RouterListener.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@
1313

1414
use Psr\Log\LoggerInterface;
1515
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
16+
use Symfony\Component\HttpKernel\Event\RequestFinishedEvent;
1617
use Symfony\Component\HttpKernel\KernelEvents;
1718
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
1819
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
20+
use Symfony\Component\HttpKernel\RequestContext as KernelRequestContext;
1921
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
2022
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
2123
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
@@ -36,6 +38,7 @@ class RouterListener implements EventSubscriberInterface
3638
private $context;
3739
private $logger;
3840
private $request;
41+
private $kernelContext;
3942

4043
/**
4144
* Constructor.
@@ -46,7 +49,7 @@ class RouterListener implements EventSubscriberInterface
4649
*
4750
* @throws \InvalidArgumentException
4851
*/
49-
public function __construct($matcher, RequestContext $context = null, LoggerInterface $logger = null)
52+
public function __construct($matcher, KernelRequestContext $kernelContext, RequestContext $context = null, LoggerInterface $logger = null)
5053
{
5154
if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
5255
throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
@@ -58,6 +61,7 @@ public function __construct($matcher, RequestContext $context = null, LoggerInte
5861

5962
$this->matcher = $matcher;
6063
$this->context = $context ?: $matcher->getContext();
64+
$this->kernelContext = $kernelContext;
6165
$this->logger = $logger;
6266
}
6367

@@ -71,22 +75,27 @@ public function __construct($matcher, RequestContext $context = null, LoggerInte
7175
*
7276
* @param Request|null $request A Request instance
7377
*/
74-
public function setRequest(Request $request = null)
78+
private function populateRoutingContext(Request $request = null)
7579
{
7680
if (null !== $request && $this->request !== $request) {
7781
$this->context->fromRequest($request);
7882
}
7983
$this->request = $request;
8084
}
8185

86+
public function onKernelRequestFinished(RequestFinishedEvent $event)
87+
{
88+
$this->populateRoutingContext($this->kernelContext->getParentRequest());
89+
}
90+
8291
public function onKernelRequest(GetResponseEvent $event)
8392
{
8493
$request = $event->getRequest();
8594

8695
// initialize the context that is also used by the generator (assuming matcher and generator share the same context instance)
8796
// we call setRequest even if most of the time, it has already been done to keep compatibility
8897
// with frameworks which do not use the Symfony service container
89-
$this->setRequest($request);
98+
$this->populateRoutingContext($request);
9099

91100
if ($request->attributes->has('_controller')) {
92101
// routing is already done
@@ -139,6 +148,7 @@ public static function getSubscribedEvents()
139148
{
140149
return array(
141150
KernelEvents::REQUEST => array(array('onKernelRequest', 32)),
151+
KernelEvents::REQUEST_FINISHED => array(array('onKernelRequestFinished', 0)),
142152
);
143153
}
144154
}

src/Symfony/Component/HttpKernel/Fragment/FragmentHandler.php

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\HttpFoundation\Response;
1616
use Symfony\Component\HttpFoundation\StreamedResponse;
1717
use Symfony\Component\HttpKernel\Controller\ControllerReference;
18+
use Symfony\Component\HttpKernel\RequestContext;
1819

1920
/**
2021
* Renders a URI that represents a resource fragment.
@@ -30,16 +31,17 @@ class FragmentHandler
3031
{
3132
private $debug;
3233
private $renderers;
33-
private $request;
34+
private $context;
3435

3536
/**
3637
* Constructor.
3738
*
3839
* @param FragmentRendererInterface[] $renderers An array of FragmentRendererInterface instances
3940
* @param Boolean $debug Whether the debug mode is enabled or not
4041
*/
41-
public function __construct(array $renderers = array(), $debug = false)
42+
public function __construct(RequestContext $context, array $renderers = array(), $debug = false)
4243
{
44+
$this->context = $context;
4345
$this->renderers = array();
4446
foreach ($renderers as $renderer) {
4547
$this->addRenderer($renderer);
@@ -57,16 +59,6 @@ public function addRenderer(FragmentRendererInterface $renderer)
5759
$this->renderers[$renderer->getName()] = $renderer;
5860
}
5961

60-
/**
61-
* Sets the current Request.
62-
*
63-
* @param Request $request The current Request
64-
*/
65-
public function setRequest(Request $request = null)
66-
{
67-
$this->request = $request;
68-
}
69-
7062
/**
7163
* Renders a URI and returns the Response content.
7264
*
@@ -93,11 +85,7 @@ public function render($uri, $renderer = 'inline', array $options = array())
9385
throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer));
9486
}
9587

96-
if (null === $this->request) {
97-
throw new \LogicException('Rendering a fragment can only be done when handling a master Request.');
98-
}
99-
100-
return $this->deliver($this->renderers[$renderer]->render($uri, $this->request, $options));
88+
return $this->deliver($this->renderers[$renderer]->render($uri, $this->context->getCurrentRequest(), $options));
10189
}
10290

10391
/**
@@ -115,7 +103,8 @@ public function render($uri, $renderer = 'inline', array $options = array())
115103
protected function deliver(Response $response)
116104
{
117105
if (!$response->isSuccessful()) {
118-
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->request->getUri(), $response->getStatusCode()));
106+
$request = $this->context->getCurrentRequest();
107+
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $request->getUri(), $response->getStatusCode()));
119108
}
120109

121110
if (!$response instanceof StreamedResponse) {

0 commit comments

Comments
 (0)
0