8000 fixed inconsistency when calling the Http Kernel instance from an event · lcf/symfony@7e66933 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7e66933

Browse files
committed
fixed inconsistency when calling the Http Kernel instance from an event
1 parent a46ca47 commit 7e66933

File tree

7 files changed

+189
-138
lines changed

7 files changed

+189
-138
lines changed

src/Symfony/Bundle/FrameworkBundle/RequestListener.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public function resolve(Event $event)
6767
$this->logger->info(sprintf('Matched route "%s" (parameters: %s)', $parameters['_route'], str_replace("\n", '', var_export($parameters, true))));
6868
}
6969

70-
$request->attributes->replace($parameters);
70+
$request->attributes->add($parameters);
7171
} elseif (null !== $this->logger) {
7272
$this->logger->err(sprintf('No route found for %s', $request->getPathInfo()));
7373
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
</service>
2626

2727
<service id="http_kernel" class="%http_kernel.class%">
28+
<argument type="service" id="service_container" />
2829
<argument type="service" id="event_dispatcher" />
2930
<argument type="service" id="controller_resolver" />
3031
</service>
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
3+
namespace Symfony\Component\HttpKernel;
4+
5+
use Symfony\Component\EventDispatcher\Event;
6+
use Symfony\Component\EventDispatcher\EventDispatcher;
7+
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
8+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
9+
use Symfony\Component\HttpFoundation\Request;
10+
use Symfony\Component\HttpFoundation\Response;
11+
12+
/*
13+
* This file is part of the Symfony package.
14+
*
15+
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
16+
*
17+
* For the full copyright and license information, please view the LICENSE
18+
* file that was distributed with this source code.
19+
*/
20+
21+
/**
22+
* BaseHttpKernel notifies events to convert a Request object to a Response one.
23+
*
24+
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
25+
*/
26+
class BaseHttpKernel implements HttpKernelInterface
27+
{
28+
protected $dispatcher;
29+
protected $resolver;
30+
protected $request;
31+
32+
/**
33+
* Constructor
34+
*
35+
* @param EventDispatcher $dispatcher An event dispatcher instance
36+
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
37+
*/
38+
public function __construct(EventDispatcher $dispatcher, ControllerResolverInterface $resolver)
39+
{
40+
$this->dispatcher = $dispatcher;
41+
$this->resolver = $resolver;
42+
}
43+
44+
/**
45+
* Gets the Request instance associated with the master request.
46+
*
47+
* @return Request A Request instance
48+
*/
49+
public function getRequest()
50+
{
51+
return $this->request;
52+
}
53+
54+
/**
55+
* Handles a Request to convert it to a Response.
56+
*
57+
* All exceptions are caught, and a core.exception event is notified
58+
* for user management.
59+
*
60+
* @param Request $request A Request instance
61+
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
62+
* @param Boolean $raw Whether to catch exceptions or not
63+
*
64+
* @return Response A Response instance
65+
*
66+
* @throws \Exception When an Exception occurs during processing
67+
* and couldn't be caught by event processing or $raw is true
68+
*/
69+
public function handle(Request $request = null, $type = HttpKernelInterface::MASTER_REQUEST, $raw = false)
70+
{
71+
if (null === $request) {
72+
$request = new Request();
73+
}
74+
75+
if (HttpKernelInterface::MASTER_REQUEST === $type) {
76+
$this->request = $request;
77+
}
78+
79+
try {
80+
return $this->handleRaw($request, $type);
81+
} catch (\Exception $e) {
82+
if (true === $raw) {
83+
throw $e;
84+
}
85+
86+
// exception
87+
$event = $this->dispatcher->notifyUntil(new Event($this, 'core.exception', array('request_type' => $type, 'request' => $request, 'exception' => $e)));
88+
if ($event->isProcessed()) {
89+
return $this->filterResponse($event->getReturnValue(), $request, 'A "core.exception" listener returned a non response object.', $type);
90+
}
91+
92+
throw $e;
93+
}
94+
}
95+
96+
/**
97+
* Handles a request to convert it to a response.
98+
*
99+
* Exceptions are not caught.
100+
*
101+
* @param Request $request A Request instance
102+
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
103+
*
104+
* @return Response A Response instance
105+
*
106+
* @throws \LogicException If one of the listener does not behave as expected
107+
* @throws NotFoundHttpException When controller cannot be found
108+
*/
109+
protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)
110+
{
111+
// request
112+
$event = $this->dispatcher->notifyUntil(new Event($this, 'core.request', array('request_type' => $type, 'request' => $request)));
113+
if ($event->isProcessed()) {
114+
return $this->filterResponse($event->getReturnValue(), $request, 'A "core.request" listener returned a non response object.', $type);
115+
}
116+
117+
// load controller
118+
if (false === $controller = $this->resolver->getController($request)) {
119+
throw new NotFoundHttpException('Unable to find the controller.');
120+
}
121+
122+
$event = $this->dispatcher-&g 1C72 t;filter(new Event($this, 'core.controller', array('request_type' => $type, 'request' => $request)), $controller);
123+
$controller = $event->getReturnValue();
124+
125+
// controller must be a callable
126+
if (!is_callable($controller)) {
127+
throw new \LogicException(sprintf('The controller must be a callable (%s).', var_export($controller, true)));
128+
}
129+
130+
// controller arguments
131+
$arguments = $this->resolver->getArguments($request, $controller);
132+
133+
// call controller
134+
$retval = call_user_func_array($controller, $arguments);
135+
136+
// view
137+
$event = $this->dispatcher->filter(new Event($this, 'core.view', array('request_type' => $type, 'request' => $request)), $retval);
138+
139+
return $this->filterResponse($event->getReturnValue(), $request, sprintf('The controller must return a response (instead of %s).', is_object($event->getReturnValue()) ? 'an object of class '.get_class($event->getReturnValue()) : is_array($event->getReturnValue()) ? 'an array' : str_replace("\n", '', var_export($event->getReturnValue(), true))), $type);
140+
}
141+
142+
/**
143+
* Filters a response object.
144+
*
145+
* @param Response $response A Response instance
146+
* @param string $message A error message in case the response is not a Response object
147+
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
148+
*
149+
* @return Response The filtered Response instance
150+
*
151+
* @throws \RuntimeException if the passed object is not a Response instance
152+
*/
153+
protected function filterResponse($response, $request, $message, $type)
154+
{
155+
if (!$response instanceof Response) {
156+
throw new \RuntimeException($message);
157+
}
158+
159+
$event = $this->dispatcher->filter(new Event($this, 'core.response', array('request_type' => $type, 'request' => $request)), $response);
160+
$response = $event->getReturnValue();
161+
162+
if (!$response instanceof Response) {
163+
throw new \RuntimeException('A "core.response" listener returned a non response object.');
164+
}
165+
166+
return $response;
167+
}
168+
}

src/Symfony/Component/HttpKernel/HttpKernel.php

Lines changed: 14 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
namespace Symfony\Component\HttpKernel;
44

5-
use Symfony\Component\EventDispatcher\Event;
65
use Symfony\Component\EventDispatcher\EventDispatcher;
6+
use Symfony\Component\DependencyInjection\ContainerInterface;
77
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
8-
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
98
use Symfony\Component\HttpFoundation\Request;
10-
use Symfony\Component\HttpFoundation\Response;
9+
use Symfony\Component\HttpKernel\HttpKernelInterface;
1110

1211
/*
1312
* This file is part of the Symfony package.
@@ -23,145 +22,42 @@
2322
*
2423
* @author Fabien Potencier <fabien.potencier@symfony-project.com>
2524
*/
26-
class HttpKernel implements HttpKernelInterface
25+
class HttpKernel extends BaseHttpKernel
2726
{
28-
protected $dispatcher;
29-
protected $resolver;
30-
protected $request;
27+
protected $container;
3128

3229
/**
3330
* Constructor
3431
*
32+
* @param ContainerInterface $container An ContainerInterface instance
3533
* @param EventDispatcher $dispatcher An event dispatcher instance
3634
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
3735
*/
38-
public function __construct(EventDispatcher $dispatcher, ControllerResolverInterface $resolver)
36+
public function __construct(ContainerInterface $container, EventDispatcher $dispatcher, ControllerResolverInterface $resolver)
3937
{
40-
$this->dispatcher = $dispatcher;
41-
$this->resolver = $resolver;
42-
}
38+
$this->container = $container;
4339

44-
/**
45-
* Gets the Request instance associated with the master request.
46-
*
47-
* @return Request A Request instance
48-
*/
49-
public function getRequest()
50-
{
51-
return $this->request;
40+
parent::__construct($dispatcher, $resolver);
5241
}
5342

5443
/**
55-
* Handles a Request to convert it to a Response.
56-
*
57-
* All exceptions are caught, and a core.exception event is notified
58-
* for user management.
59-
*
60-
* @param Request $request A Request instance
61-
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
62-
* @param Boolean $raw Whether to catch exceptions or not
63-
*
64-
* @return Response A Response instance
65-
*
66-
* @throws \Exception When an Exception occurs during processing
67-
* and couldn't be caught by event processing or $raw is true
44+
* {@inheritdoc}
6845
*/
6946
public function handle(Request $request = null, $type = HttpKernelInterface::MASTER_REQUEST, $raw = false)
7047
{
7148
if (null === $request) {
72-
$request = new Request();
49+
$request = $this->container->get('request');
50+
} else {
51+
$this->container->set('request', $request);
7352
}
7453

7554
if (HttpKernelInterface::MASTER_REQUEST === $type) {
7655
$this->request = $request;
7756
}
7857

79-
try {
80-
return $this->handleRaw($request, $type);
81-
} catch (\Exception $e) {
82-
if (true === $raw) {
83-
throw $e;
84-
}
85-
86-
// exception
87-
$event = $this->dispatcher->notifyUntil(new Event($this, 'core.exception', array('request_type' => $type, 'request' => $request, 'exception' => $e)));
88-
if ($event->isProcessed()) {
89-
return $this->filterResponse($event->getReturnValue(), $request, 'A "core.exception" listener returned a non response object.', $type);
90-
}
91-
92-
throw $e;
93-
}
94-
}
95-
96-
/**
97-
* Handles a request to convert it to a response.
98-
*
99-
* Exceptions are not caught.
100-
*
101-
* @param Request $request A Request instance
102-
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
103-
*
104-
* @return Response A Response instance
105-
*
106-
* @throws \LogicException If one of the listener does not behave as expected
107-
* @throws NotFoundHttpException When controller cannot be found
108-
*/
109-
protected function handleRaw(Request $request, $type = self::MASTER_REQUEST)
110-
{
111-
// request
112-
$event = $this->dispatcher->notifyUntil(new Event($this, 'core.request', array('request_type' => $type, 'request' => $request)));
113-
if ($event->isProcessed()) {
114-
return $this->filterResponse($event->getReturnValue(), $request, 'A "core.request" listener returned a non response object.', $type);
115-
}
116-
117-
// load controller
118-
if (false === $controller = $this->resolver->getController($request)) {
119-
throw new NotFoundHttpException('Unable to find the controller.');
120-
}
121-
122-
$event = $this->dispatcher->filter(new Event($this, 'core.controller', array('request_type' => $type, 'request' => $request)), $controller);
123-
$controller = $event->getReturnValue();
124-
125-
// controller must be a callable
126-
if (!is_callable($controller)) {
127-
throw < F438 span class=pl-k>new \LogicException(sprintf('The controller must be a callable (%s).', var_export($controller, true)));
128-
}
129-
130-
// controller arguments
131-
$arguments = $this->resolver->getArguments($request, $controller);
132-
133-
// call controller
134-
$retval = call_user_func_array($controller, $arguments);
135-
136-
// view
137-
$event = $this->dispatcher->filter(new Event($this, 'core.view', array('request_type' => $type, 'request' => $request)), $retval);
138-
139-
return $this->filterResponse($event->getReturnValue(), $request, sprintf('The controller must return a response (instead of %s).', is_object($event->getReturnValue()) ? 'an object of class '.get_class($event->getReturnValue()) : is_array($event->getReturnValue()) ? 'an array' : str_replace("\n", '', var_export($event->getReturnValue(), true))), $type);
140-
}
58+
$response = parent::handle($request, $type, $raw);
14159

142-
/**
143-
* Filters a response object.
144-
*
145-
* @param Response $response A Response instance
146-
* @param string $message A error message in case the response is not a Response object
147-
* @param integer $type The type of the request (one of HttpKernelInterface::MASTER_REQUEST or HttpKernelInterface::SUB_REQUEST)
148-
*
149-
* @return Response The filtered Response instance
150-
*
151-
* @throws \RuntimeException if the passed object is not a Response instance
152-
*/
153-
protected function filterResponse($response, $request, $message, $type)
154-
{
155-
if (!$response instanceof Response) {
156-
throw new \RuntimeException($message);
157-
}
158-
159-
$event = $this->dispatcher->filter(new Event($this, 'core.response', array('request_type' => $type, 'request' => $request)), $response);
160-
$response = $event->getReturnValue();
161-
162-
if (!$response instanceof Response) {
163-
throw new \RuntimeException('A "core.response" listener returned a non response object.');
164-
}
60+
$this->container->set('request', $this->request);
16561

16662
return $response;
16763
}

src/Symfony/Component/HttpKernel/Kernel.php

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -196,21 +196,7 @@ public function handle(Request $request = null, $type = HttpKernelInterface::MAS
196196
$this->boot();
197197
}
198198

199-
if (null === $request) {
200-
$request = $this->container->get('request');
201-
} else {
202-
$this->container->set('request', $request);
203-
}
204-
205-
if (HttpKernelInterface::MASTER_REQUEST === $type) {
206-
$this->request = $request;
207-
}
208-
209-
$response = $this->container->getHttpKernelService()->handle($request, $type, $raw);
210-
211-
$this->container->set('request', $this->request);
212-
213-
return $response;
199+
return $this->container->getHttpKernelService()->handle($request, $type, $raw);
214200
}
215201

216202
/**

tests/Symfony/Tests/Component/HttpKernel/Cache/TestHttpKernel.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111

1212
namespace Symfony\Tests\Component\HttpKernel\Cache;
1313

14-
use Symfony\Component\HttpKernel\HttpKernel;
14+
use Symfony\Component\HttpKernel\BaseHttpKernel;
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\Response;
1717
use Symfony\Component\EventDispatcher\EventDispatcher;
1818
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
1919

20-
class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
20+
class TestHttpKernel extends BaseHttpKernel implements ControllerResolverInterface
2121
{
2222
protected $body;
2323
protected $status;

0 commit comments

Comments
 (0)
0