Added the SessionValueResolver

This commit is contained in:
Iltar van der Berg 2017-01-06 08:18:08 +01:00
parent 0e92e0a7ba
commit b4464dcea1
5 changed files with 161 additions and 10 deletions

View File

@ -32,6 +32,10 @@
<tag name="controller.argument_value_resolver" priority="50" />
</service>
<service id="argument_resolver.session" class="Symfony\Component\HttpKernel\Controller\ArgumentResolver\SessionValueResolver" public="false">
<tag name="controller.argument_value_resolver" priority="50" />
</service>
<service id="argument_resolver.default" class="Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver" public="false">
<tag name="controller.argument_value_resolver" priority="-100" />
</service>

View File

@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\SessionValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\VariadicValueResolver;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactoryInterface;
@ -85,6 +86,7 @@ final class ArgumentResolver implements ArgumentResolverInterface
return array(
new RequestAttributeValueResolver(),
new RequestValueResolver(),
new SessionValueResolver(),
new DefaultValueResolver(),
new VariadicValueResolver(),
);

View File

@ -0,0 +1,53 @@
<?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\Controller\ArgumentResolver;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
/**
* Yields the Session.
*
* @author Iltar van der Berg <kjarli@gmail.com>
*/
final class SessionValueResolver implements ArgumentValueResolverInterface
{
/**
* {@inheritdoc}
*/
public function supports(Request $request, ArgumentMetadata $argument)
{
if (SessionInterface::class !== $argument->getType() && !is_subclass_of($argument->getType(), SessionInterface::class)) {
return false;
}
$session = $request->getSession();
if (null === $session) {
return false;
}
$class = get_class($session);
return $class === $argument->getType() || is_subclass_of($class, $argument->getType());
}
/**
* {@inheritdoc}
*/
public function resolve(Request $request, ArgumentMetadata $argument)
{
yield $request->getSession();
}
}

View File

@ -12,14 +12,15 @@
namespace Symfony\Component\HttpKernel\Tests\Controller;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\VariadicValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory;
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\ExtendingRequest;
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\ExtendingSession;
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\NullableController;
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\VariadicController;
use Symfony\Component\HttpFoundation\Request;
@ -32,14 +33,8 @@ class ArgumentResolverTest extends TestCase
public static function setUpBeforeClass()
{
$factory = new ArgumentMetadataFactory();
$argumentValueResolvers = array(
new RequestAttributeValueResolver(),
new RequestValueResolver(),
new DefaultValueResolver(),
new VariadicValueResolver(),
);
self::$resolver = new ArgumentResolver($factory, $argumentValueResolvers);
self::$resolver = new ArgumentResolver($factory);
}
public function testDefaultState()
@ -241,6 +236,73 @@ class ArgumentResolverTest extends TestCase
$this->assertEquals(array(null, null, 'value', 'mandatory'), self::$resolver->getArguments($request, $controller));
}
public function testGetSessionArguments()
{
$session = new Session(new MockArraySessionStorage());
$request = Request::create('/');
$request->setSession($session);
$controller = array($this, 'controllerWithSession');
$this->assertEquals(array($session), self::$resolver->getArguments($request, $controller));
}
public function testGetSessionArgumentsWithExtendedSession()
{
$session = new ExtendingSession(new MockArraySessionStorage());
$request = Request::create('/');
$request->setSession($session);
$controller = array($this, 'controllerWithExtendingSession');
$this->assertEquals(array($session), self::$resolver->getArguments($request, $controller));
}
public function testGetSessionArgumentsWithInterface()
{
$session = $this->getMockBuilder(SessionInterface::class)->getMock();
$request = Request::create('/');
$request->setSession($session);
$controller = array($this, 'controllerWithSessionInterface');
$this->assertEquals(array($session), self::$resolver->getArguments($request, $controller));
}
/**
* @expectedException \RuntimeException
*/
public function testGetSessionMissMatchWithInterface()
{
$session = $this->getMockBuilder(SessionInterface::class)->getMock();
$request = Request::create('/');
$request->setSession($session);
$controller = array($this, 'controllerWithExtendingSession');
self::$resolver->getArguments($request, $controller);
}
/**
* @expectedException \RuntimeException
*/
public function testGetSessionMissMatchWithImplementation()
{
$session = new Session(new MockArraySessionStorage());
$request = Request::create('/');
$request->setSession($session);
$controller = array($this, 'controllerWithExtendingSession');
self::$resolver->getArguments($request, $controller);
}
/**
* @expectedException \RuntimeException
*/
public function testGetSessionMissMatchOnNull()
{
$request = Request::create('/');
$controller = array($this, 'controllerWithExtendingSession');
self::$resolver->getArguments($request, $controller);
}
public function __invoke($foo, $bar = null)
{
}
@ -268,6 +330,18 @@ class ArgumentResolverTest extends TestCase
protected function controllerWithExtendingRequest(ExtendingRequest $request)
{
}
protected function controllerWithSession(Session $session)
{
}
protected function controllerWithSessionInterface(SessionInterface $session)
{
}
protected function controllerWithExtendingSession(ExtendingSession $session)
{
}
}
function controller_function($foo, $foobar)

View File

@ -0,0 +1,18 @@
<?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\Tests\Fixtures\Controller;
use Symfony\Component\HttpFoundation\Session\Session;
class ExtendingSession extends Session
{
}