Merge pull request #1 from pminnieur/post_response
[HttpKernel] Add Kernel::terminate() and HttpKernel::terminate() for post-response logic (without the BC break)
This commit is contained in:
commit
7c2f11f713
@ -23,7 +23,7 @@ class PostResponseEvent extends Event
|
||||
{
|
||||
/**
|
||||
* The kernel in which this event was thrown
|
||||
* @var Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
* @var HttpKernelInterface
|
||||
*/
|
||||
private $kernel;
|
||||
|
||||
@ -35,10 +35,10 @@ class PostResponseEvent extends Event
|
||||
/**
|
||||
* Returns the kernel in which this event was thrown
|
||||
*
|
||||
* @return Symfony\Component\HttpKernel\HttpKernelInterface
|
||||
* @return HttpKernelInterface
|
||||
*/
|
||||
public function getKernel()
|
||||
{
|
||||
return $this->kernel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
namespace Symfony\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\TerminableInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
@ -26,7 +27,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class HttpCache implements HttpKernelInterface
|
||||
class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
{
|
||||
private $kernel;
|
||||
private $store;
|
||||
@ -216,15 +217,15 @@ class HttpCache implements HttpKernelInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates a request/response cycle
|
||||
*
|
||||
* Should be called before shutdown, but after sending the response
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function terminate()
|
||||
{
|
||||
$this->kernel->terminate();
|
||||
if ($this->getKernel() instanceof TerminableInterface) {
|
||||
$this->getKernel()->terminate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class HttpKernel implements HttpKernelInterface
|
||||
class HttpKernel implements HttpKernelInterface, TerminableInterface
|
||||
{
|
||||
private $dispatcher;
|
||||
private $resolver;
|
||||
@ -80,9 +80,7 @@ class HttpKernel implements HttpKernelInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates a request/response cycle
|
||||
*
|
||||
* Should be called before shutdown, but after sending the response
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
@ -44,11 +44,4 @@ interface HttpKernelInterface
|
||||
* @api
|
||||
*/
|
||||
function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
|
||||
|
||||
/**
|
||||
* Terminates a request/response cycle
|
||||
*
|
||||
* Should be called after sending the response
|
||||
*/
|
||||
function terminate();
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ use Symfony\Component\ClassLoader\DebugUniversalClassLoader;
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
abstract class Kernel implements KernelInterface
|
||||
abstract class Kernel implements KernelInterface, TerminableInterface
|
||||
{
|
||||
protected $bundles;
|
||||
protected $bundleMap;
|
||||
@ -134,6 +134,22 @@ abstract class Kernel implements KernelInterface
|
||||
$this->booted = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function terminate()
|
||||
{
|
||||
if (false === $this->booted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->getHttpKernel() instanceof TerminableInterface) {
|
||||
$this->getHttpKernel()->terminate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdowns the kernel.
|
||||
*
|
||||
@ -171,22 +187,6 @@ abstract class Kernel implements KernelInterface
|
||||
return $this->getHttpKernel()->handle($request, $type, $catch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Terminates a request/response cycle
|
||||
*
|
||||
* Should be called before shutdown, but after sending the response
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function terminate()
|
||||
{
|
||||
if (false === $this->booted) {
|
||||
throw new \LogicException('The kernel has been shutdown already');
|
||||
}
|
||||
|
||||
$this->getHttpKernel()->terminate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a http kernel from the container
|
||||
*
|
||||
|
36
src/Symfony/Component/HttpKernel/TerminableInterface.php
Normal file
36
src/Symfony/Component/HttpKernel/TerminableInterface.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?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\Component\HttpKernel;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Terminable extends the Kernel request/response cycle with dispatching a post
|
||||
* response event after sending the response and before shutting down the kernel.
|
||||
*
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @author Pierre Minnieur <pierre.minnieur@sensiolabs.de>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
interface TerminableInterface
|
||||
{
|
||||
/**
|
||||
* Terminates a request/response cycle.
|
||||
*
|
||||
* Should be called after sending the response and before shutting down the kernel.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
function terminate();
|
||||
}
|
@ -11,10 +11,43 @@
|
||||
|
||||
namespace Symfony\Tests\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpKernel\HttpCache\HttpCache;
|
||||
use Symfony\Component\HttpKernel\HttpCache\StoreInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
require_once __DIR__.'/HttpCacheTestCase.php';
|
||||
|
||||
class HttpCacheTest extends HttpCacheTestCase
|
||||
{
|
||||
public function testTerminateDelegatesTerminationOnlyForTerminableInterface()
|
||||
{
|
||||
$storeMock = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\HttpCache\\StoreInterface')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
// does not implement TerminableInterface
|
||||
$kernelMock = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\HttpKernelInterface')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$kernelMock->expects($this->never())
|
||||
->method('terminate');
|
||||
|
||||
$kernel = new HttpCache($kernelMock, $storeMock);
|
||||
$kernel->terminate();
|
||||
|
||||
// implements TerminableInterface
|
||||
$kernelMock = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Kernel')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('terminate', 'registerBundles', 'registerContainerConfiguration'))
|
||||
->getMock();
|
||||
|
||||
$kernelMock->expects($this->once())
|
||||
->method('terminate');
|
||||
|
||||
$kernel = new HttpCache($kernelMock, $storeMock);
|
||||
$kernel->terminate();
|
||||
}
|
||||
|
||||
public function testPassesOnNonGetHeadRequests()
|
||||
{
|
||||
$this->setNextResponse(200);
|
||||
|
@ -652,6 +652,66 @@ EOF;
|
||||
$kernel->initializeBundles();
|
||||
}
|
||||
|
||||
public function testTerminateReturnsSilentlyIfKernelIsNotBooted()
|
||||
{
|
||||
$kernel = $this->getMockBuilder('Symfony\Tests\Component\HttpKernel\KernelForTest')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('getHttpKernel'))
|
||||
->getMock();
|
||||
|
||||
$kernel->expects($this->never())
|
||||
->method('getHttpKernel');
|
||||
|
||||
$kernel->setIsBooted(false);
|
||||
$kernel->terminate();
|
||||
}
|
||||
|
||||
public function testTerminateDelegatesTerminationOnlyForTerminableInterface()
|
||||
{
|
||||
// does not implement TerminableInterface
|
||||
$httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
$httpKernelMock
|
||||
->expects($this->never())
|
||||
->method('terminate');
|
||||
|
||||
$kernel = $this->getMockBuilder('Symfony\Tests\Component\HttpKernel\KernelForTest')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('getHttpKernel'))
|
||||
->getMock();
|
||||
|
||||
$kernel->expects($this->once())
|
||||
->method('getHttpKernel')
|
||||
->will($this->returnValue($httpKernelMock));
|
||||
|
||||
$kernel->setIsBooted(true);
|
||||
$kernel->terminate();
|
||||
|
||||
// implements TerminableInterface
|
||||
$httpKernelMock = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernel')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('terminate'))
|
||||
->getMock();
|
||||
|
||||
$httpKernelMock
|
||||
->expects($this->once())
|
||||
->method('terminate');
|
||||
|
||||
$kernel = $this->getMockBuilder('Symfony\Tests\Component\HttpKernel\KernelForTest')
|
||||
->disableOriginalConstructor()
|
||||
->setMethods(array('getHttpKernel'))
|
||||
->getMock();
|
||||
|
||||
$kernel->expects($this->exactly(2))
|
||||
->method('getHttpKernel')
|
||||
->will($this->returnValue($httpKernelMock));
|
||||
|
||||
$kernel->setIsBooted(true);
|
||||
$kernel->terminate();
|
||||
}
|
||||
|
||||
protected function getBundle($dir = null, $parent = null, $className = null, $bundleName = null)
|
||||
{
|
||||
$bundle = $this
|
||||
|
Reference in New Issue
Block a user