[HttpKernel] Added getRequest() to HttpKernelInterface.

This commit is contained in:
Kris Wallsmith 2010-12-09 12:50:49 -05:00 committed by Fabien Potencier
parent 973a8f1f24
commit 5da423be20
6 changed files with 156 additions and 87 deletions

View File

@ -33,7 +33,7 @@
your front controller (app.php) so that it passes an instance of
YourRequestClass to the Kernel.
-->
<service id="request" factory-service="kernel" factory-method="getRequest" shared="false" />
<service id="request" factory-service="http_kernel" factory-method="getRequest" shared="false" />
<service id="response" class="%response.class%" shared="false" />
</services>

View File

@ -27,6 +27,7 @@ class HttpKernel implements HttpKernelInterface
{
protected $dispatcher;
protected $resolver;
protected $request;
/**
* Constructor
@ -45,9 +46,16 @@ class HttpKernel implements HttpKernelInterface
*/
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
// set the current request, stash the previous one
$previousRequest = $this->request;
$this->request = $request;
try {
return $this->handleRaw($request, $type);
$response = $this->handleRaw($request, $type);
} catch (\Exception $e) {
// restore the previous request
$this->request = $previousRequest;
if (false === $catch) {
throw $e;
}
@ -61,6 +69,19 @@ class HttpKernel implements HttpKernelInterface
throw $e;
}
// restore the previous request
$this->request = $previousRequest;
return $response;
}
/**
* {@inheritdoc}
*/
public function getRequest()
{
return $this->request;
}
/**

View File

@ -39,4 +39,11 @@ interface HttpKernelInterface
* @throws \Exception When an Exception occurs during processing
*/
function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
/**
* Returns the current request.
*
* @return Request|null The request currently being handled
*/
function getRequest();
}

View File

@ -45,7 +45,6 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
protected $booted;
protected $name;
protected $startTime;
protected $request;
const VERSION = '2.0.0-DEV';
@ -175,29 +174,19 @@ abstract class Kernel implements HttpKernelInterface, \Serializable
*/
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
$masterRequest = HttpKernelInterface::MASTER_REQUEST === $type ? $request : $this->request;
$this->request = $request;
if (false === $this->booted) {
$this->boot();
}
$response = $this->container->get('http_kernel')->handle($this->request, $type, $catch);
$this->request = $masterRequest;
return $response;
return $this->container->get('http_kernel')->handle($request, $type, $catch);
}
/**
* Gets the current request.
*
* @return Request
* {@inheritdoc}
*/
public function getRequest()
{
return $this->request;
return $this->container->get('http_kernel')->getRequest();
}
/**

View File

@ -156,20 +156,135 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('foo', $kernel->handle(new Request())->getContent());
}
/**
* @testdox A master request should be set on the kernel for the duration of handle(), then unset
*/
public function testHandleSetsTheCurrentRequest()
{
$dispatcher = new EventDispatcher();
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
$kernel = new HttpKernel($dispatcher, $resolver);
$request = new Request();
$expected = new Response();
$testCase = $this;
$controller = function() use($expected, $kernel, $testCase, $request)
{
$testCase->assertSame($request, $kernel->getRequest(), '->handle() sets the current request when there is no parent request');
return $expected;
};
$resolver->expects($this->once())
->method('getController')
->with($request)
->will($this->returnValue($controller));
$resolver->expects($this->once())
->method('getArguments')
->with($request, $controller)
->will($this->returnValue(array()));
$actual = $kernel->handle($request);
$this->assertSame($expected, $actual, '->handle() returns the response');
$this->assertNull($kernel->getRequest(), '->handle() restores the parent (null) request');
}
/**
* @testdox The parent request is restored following a sub request
* @dataProvider provideRequestTypes
*/
public function testHandleRestoresThePreviousRequest($requestType)
{
$dispatcher = new EventDispatcher();
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
$kernel = new HttpKernel($dispatcher, $resolver);
$parentRequest = new Request(array('name' => 'parent_request'));
$request = new Request(array('name' => 'current_request'));
$expected = new Response();
// sets a parent request to emulate a subrequest
$reflProp = new \ReflectionProperty($kernel, 'request');
$reflProp->setAccessible(true);
$reflProp->setValue($kernel, $parentRequest);
$testCase = $this;
$controller = function() use($expected, $kernel, $testCase, $request)
{
$testCase->assertSame($request, $kernel->getRequest(), '->handle() sets the current request when there is a parent request');
return $expected;
};
$resolver->expects($this->once())
->method('getController')
->with($request)
->will($this->returnValue($controller));
$resolver->expects($this->once())
->method('getArguments')
->with($request, $controller)
->will($this->returnValue(array()));
// the behavior should be the same, regardless of request type
$actual = $kernel->handle($request, $requestType);
$this->assertSame($expected, $actual, '->handle() returns the response');
$this->assertSame($parentRequest, $kernel->getRequest(), '->handle() restores the parent request');
}
public function provideRequestTypes()
{
return array(
array(HttpKernelInterface::MASTER_REQUEST),
array(HttpKernelInterface::SUB_REQUEST),
);
}
public function testHandleRestoresThePreviousRequestOnException()
{
$dispatcher = new EventDispatcher();
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
$kernel = new HttpKernel($dispatcher, $resolver);
$request = new Request();
$expected = new \Exception();
$controller = function() use ($expected)
{
throw $expected;
};
$resolver->expects($this->once())
->method('getController')
->with($request)
->will($this->returnValue($controller));
$resolver->expects($this->once())
->method('getArguments')
->with($request, $controller)
->will($this->returnValue(array()));
try {
$kernel->handle($request);
$this->fail('->handle() suppresses the controller exception');
} catch (\Exception $actual) {
$this->assertSame($expected, $actual, '->handle() throws the controller exception');
}
$this->assertNull($kernel->getRequest(), '->handle() restores the parent (null) request when the controller throws an exception');
}
protected function getResolver($controller = null)
{
if (null === $controller) {
$controller = function () { return new Response('Hello'); };
$controller = function() { return new Response('Hello'); };
}
$resolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface');
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
$resolver->expects($this->any())
->method('getController')
->will($this->returnValue($controller))
;
->method('getController')
->will($this->returnValue($controller));
$resolver->expects($this->any())
->method('getArguments')
->will($this->returnValue(array()))
;
->method('getArguments')
->will($this->returnValue(array()));
return $resolver;
}

View File

@ -12,8 +12,6 @@
namespace Symfony\Tests\Component\HttpKernel;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\Loader\LoaderInterface;
class KernelTest extends \PHPUnit_Framework_TestCase
@ -24,57 +22,6 @@ class KernelTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('foo', $kernel->getSafeName());
}
public function testHandleSetsTheRequest()
{
$masterRequest = Request::create('/');
$subRequest = Request::create('/');
$httpKernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
->disableOriginalConstructor()
->setMethods(array('handle'))
->getMock();
$httpKernel->expects($this->at(0))
->method('handle')
->with($masterRequest);
$httpKernel->expects($this->at(1))
->method('handle')
->with($subRequest);
$container = $this->getMockBuilder('Symfony\Component\DependencyInjection\Container')
->disableOriginalConstructor()
->setMethods(array('get'))
->getMock();
$container->expects($this->exactly(2))
->method('get')
->with('http_kernel')
->will($this->returnValue($httpKernel));
$kernel = $this->getMockBuilder('Symfony\Tests\Component\HttpKernel\KernelForTest')
->setConstructorArgs(array('dev', true, '-foo-'))
->setMethods(array('boot'))
->getMock();
$kernel->setContainer($container);
$testCase = $this;
$bootCallback = function() use ($masterRequest, $kernel, $testCase) {
$kernel->setBooted(true);
$testCase->assertSame($masterRequest, $kernel->getRequest(), '->handle() sets the Request before booting');
};
$kernel->expects($this->once())
->method('boot')
->will($this->returnCallback($bootCallback));
$kernel->handle($masterRequest);
$kernel->handle($subRequest, HttpKernelInterface::SUB_REQUEST);
$this->assertSame($masterRequest, $kernel->getRequest(), '->handle() restores the master Request after handling a sub-request');
}
}
class KernelForTest extends Kernel
@ -101,14 +48,4 @@ class KernelForTest extends Kernel
public function registerContainerConfiguration(LoaderInterface $loader)
{
}
public function setBooted($booted)
{
$this->booted = $booted;
}
public function setContainer($container)
{
$this->container = $container;
}
}