Added an ArgumentResolver with clean extension point
This commit is contained in:
parent
360fc5fc4b
commit
cfcf764d24
@ -65,10 +65,12 @@ HttpKernel
|
||||
* Passing objects as URI attributes to the ESI and SSI renderers has been
|
||||
deprecated and will be removed in Symfony 4.0. The inline fragment
|
||||
renderer should be used with object attributes.
|
||||
|
||||
* The `ControllerResolver::getArguments()` method is deprecated and will be
|
||||
removed in 4.0. If you have your own `ControllerResolverInterface`
|
||||
implementation, you should replace this method by implementing the
|
||||
`ArgumentResolverInterface` and injecting it in the HttpKernel.
|
||||
`ArgumentResolverInterface` and injecting it in the `HttpKernel`, or using
|
||||
the `ArgumentResolver` and injecting this in the `HttpKernel`.
|
||||
|
||||
Serializer
|
||||
----------
|
||||
|
@ -0,0 +1,65 @@
|
||||
<?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\Bundle\FrameworkBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Gathers and configures the argument value resolvers.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
class ControllerArgumentValueResolverPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
if (!$container->hasDefinition('argument_resolver')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition('argument_resolver');
|
||||
$argumentResolvers = $this->findAndSortTaggedServices('controller_argument.value_resolver', $container);
|
||||
$definition->replaceArgument(1, $argumentResolvers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all services with the given tag name and order them by their priority.
|
||||
*
|
||||
* @param string $tagName
|
||||
* @param ContainerBuilder $container
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function findAndSortTaggedServices($tagName, ContainerBuilder $container)
|
||||
{
|
||||
$services = $container->findTaggedServiceIds($tagName);
|
||||
|
||||
$sortedServices = array();
|
||||
foreach ($services as $serviceId => $tags) {
|
||||
foreach ($tags as $attributes) {
|
||||
$priority = isset($attributes['priority']) ? $attributes['priority'] : 0;
|
||||
$sortedServices[$priority][] = new Reference($serviceId);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($sortedServices)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
krsort($sortedServices);
|
||||
|
||||
// Flatten the array
|
||||
return call_user_func_array('array_merge', $sortedServices);
|
||||
}
|
||||
}
|
@ -171,6 +171,8 @@ class FrameworkExtension extends Extension
|
||||
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener',
|
||||
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver',
|
||||
'Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver',
|
||||
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata',
|
||||
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory',
|
||||
'Symfony\\Component\\HttpKernel\\Event\\KernelEvent',
|
||||
'Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent',
|
||||
'Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent',
|
||||
|
@ -14,6 +14,7 @@ namespace Symfony\Bundle\FrameworkBundle;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ControllerArgumentValueResolverPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass;
|
||||
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
|
||||
@ -87,6 +88,7 @@ class FrameworkBundle extends Bundle
|
||||
$container->addCompilerPass(new FragmentRendererPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||
$container->addCompilerPass(new SerializerPass());
|
||||
$container->addCompilerPass(new PropertyInfoPass());
|
||||
$container->addCompilerPass(new ControllerArgumentValueResolverPass());
|
||||
|
||||
if ($container->getParameter('kernel.debug')) {
|
||||
$container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING);
|
||||
|
@ -17,7 +17,28 @@
|
||||
<argument type="service" id="logger" on-invalid="ignore" />
|
||||
</service>
|
||||
|
||||
<service id="argument_resolver" class="Symfony\Component\HttpKernel\Controller\ArgumentResolver" public="false" />
|
||||
<service id="argument_resolver" class="Symfony\Component\HttpKernel\Controller\ArgumentResolver" public="false">
|
||||
<argument type="service" id="argument_metadata_factory" />
|
||||
<argument type="collection" />
|
||||
</service>
|
||||
|
||||
<service id="argument_metadata_factory" class="Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory" public="false" />
|
||||
|
||||
<service id="argument_value_resolver.argument_from_attribute" class="Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\ArgumentFromAttributeResolver" public="false">
|
||||
<tag name="controller_argument.value_resolver" priority="100" />
|
||||
</service>
|
||||
|
||||
<service id="argument_value_resolver.argument_is_request" class="Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\RequestResolver" public="false">
|
||||
<tag name="controller_argument.value_resolver" priority="50" />
|
||||
</service>
|
||||
|
||||
<service id="argument_value_resolver.default_argument_value" class="Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\DefaultArgumentValueResolver" public="false">
|
||||
<tag name="controller_argument.value_resolver" priority="-100" />
|
||||
</service>
|
||||
|
||||
<service id="argument_value_resolver.variadic_argument_from_attribute" class="Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\VariadicArgumentValueResolver" public="false">
|
||||
<tag name="controller_argument.value_resolver" priority="-150" />
|
||||
</service>
|
||||
|
||||
<service id="response_listener" class="Symfony\Component\HttpKernel\EventListener\ResponseListener">
|
||||
<tag name="kernel.event_subscriber" />
|
||||
|
@ -4,9 +4,10 @@ CHANGELOG
|
||||
3.1.0
|
||||
-----
|
||||
* deprecated passing objects as URI attributes to the ESI and SSI renderers
|
||||
* Added an `ArgumentResolver` with `getArguments()` and the respective interface `ArgumentResolverInterface`
|
||||
* Deprecated `ControllerResolver::getArguments()`, which uses the `ArgumentResolver` as BC layer by extending it
|
||||
* The `HttpKernel` now accepts an additional argument for an `ArgumentResolver`
|
||||
* Added a `LegacyArgumentResolver` with `getArguments()` and the corresponding interface `ArgumentResolverInterface`
|
||||
* Deprecated `ControllerResolver::getArguments()`, which uses the `LegacyArgumentResolver` as BC layer by extending it
|
||||
* The `HttpKernel` now accepts an additional argument for an `ArgumentResolverInterface`
|
||||
* Added the `ArgumentResolver` which features an extension point to resolve arguments in a more dynamic way
|
||||
|
||||
3.0.0
|
||||
-----
|
||||
|
@ -12,57 +12,64 @@
|
||||
namespace Symfony\Component\HttpKernel\Controller;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactoryInterface;
|
||||
|
||||
/**
|
||||
* Responsible for the creation of the action arguments.
|
||||
* Responsible for the resolving of arguments passed to an action.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
class ArgumentResolver implements ArgumentResolverInterface
|
||||
final class ArgumentResolver implements ArgumentResolverInterface
|
||||
{
|
||||
private $argumentMetadataFactory;
|
||||
|
||||
/**
|
||||
* @var ArgumentValueResolverInterface[]
|
||||
*/
|
||||
private $argumentValueResolvers;
|
||||
|
||||
public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, array $argumentValueResolvers = array())
|
||||
{
|
||||
$this->argumentMetadataFactory = $argumentMetadataFactory;
|
||||
$this->argumentValueResolvers = $argumentValueResolvers;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getArguments(Request $request, $controller)
|
||||
{
|
||||
if (is_array($controller)) {
|
||||
$r = new \ReflectionMethod($controller[0], $controller[1]);
|
||||
} elseif (is_object($controller) && !$controller instanceof \Closure) {
|
||||
$r = new \ReflectionObject($controller);
|
||||
$r = $r->getMethod('__invoke');
|
||||
} else {
|
||||
$r = new \ReflectionFunction($controller);
|
||||
}
|
||||
|
||||
return $this->doGetArguments($request, $controller, $r->getParameters());
|
||||
}
|
||||
|
||||
protected function doGetArguments(Request $request, $controller, array $parameters)
|
||||
{
|
||||
$attributes = $request->attributes->all();
|
||||
$arguments = array();
|
||||
foreach ($parameters as $param) {
|
||||
if (array_key_exists($param->name, $attributes)) {
|
||||
if (PHP_VERSION_ID >= 50600 && $param->isVariadic() && is_array($attributes[$param->name])) {
|
||||
$arguments = array_merge($arguments, array_values($attributes[$param->name]));
|
||||
} else {
|
||||
$arguments[] = $attributes[$param->name];
|
||||
}
|
||||
} elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
|
||||
$arguments[] = $request;
|
||||
} elseif ($param->isDefaultValueAvailable()) {
|
||||
$arguments[] = $param->getDefaultValue();
|
||||
} else {
|
||||
if (is_array($controller)) {
|
||||
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
|
||||
} elseif (is_object($controller)) {
|
||||
$repr = get_class($controller);
|
||||
} else {
|
||||
$repr = $controller;
|
||||
|
||||
foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller) as $metadata) {
|
||||
foreach ($this->argumentValueResolvers as $resolver) {
|
||||
if (!$resolver->supports($request, $metadata)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
|
||||
$resolved = $resolver->resolve($request, $metadata);
|
||||
|
||||
if (!$resolved instanceof \Generator) {
|
||||
throw new \InvalidArgumentException(sprintf('%s::resolve() must yield at least one value.', get_class($resolver)));
|
||||
}
|
||||
|
||||
foreach ($resolved as $append) {
|
||||
$arguments[] = $append;
|
||||
}
|
||||
|
||||
// continue to the next controller argument
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$representative = $controller;
|
||||
|
||||
if (is_array($representative)) {
|
||||
$representative = sprintf('%s::%s()', get_class($representative[0]), $representative[1]);
|
||||
} elseif (is_object($representative)) {
|
||||
$representative = get_class($representative);
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $representative, $metadata->getName()));
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
|
@ -24,8 +24,8 @@ interface ArgumentResolverInterface
|
||||
/**
|
||||
* Returns the arguments to pass to the controller.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param callable $controller A PHP callable
|
||||
* @param Request $request
|
||||
* @param callable $controller
|
||||
*
|
||||
* @return array An array of arguments to pass to the controller
|
||||
*
|
||||
|
@ -0,0 +1,40 @@
|
||||
<?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\ArgumentValueResolver;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
|
||||
/**
|
||||
* Grabs a non-variadic value from the request and returns it.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class ArgumentFromAttributeResolver implements ArgumentValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports(Request $request, ArgumentMetadata $argument)
|
||||
{
|
||||
return !$argument->isVariadic() && $request->attributes->has($argument->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument)
|
||||
{
|
||||
yield $request->attributes->get($argument->getName());
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?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\ArgumentValueResolver;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
|
||||
/**
|
||||
* Returns the default value defined in the action signature if present and no value has been given.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class DefaultArgumentValueResolver implements ArgumentValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports(Request $request, ArgumentMetadata $argument)
|
||||
{
|
||||
return $argument->hasDefaultValue() && !$request->attributes->has($argument->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument)
|
||||
{
|
||||
yield $argument->getDefaultValue();
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
<?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\ArgumentValueResolver;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
|
||||
/**
|
||||
* Supports the same instance as the request object passed along.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class RequestResolver implements ArgumentValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports(Request $request, ArgumentMetadata $argument)
|
||||
{
|
||||
return $argument->getType() === Request::class || is_subclass_of($request, $argument->getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument)
|
||||
{
|
||||
yield $request;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
<?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\ArgumentValueResolver;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
|
||||
/**
|
||||
* Grabs the variadic value from the request and returns it.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class VariadicArgumentValueResolver implements ArgumentValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports(Request $request, ArgumentMetadata $argument)
|
||||
{
|
||||
return $argument->isVariadic() && $request->attributes->has($argument->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument)
|
||||
{
|
||||
$values = $request->attributes->get($argument->getName());
|
||||
|
||||
if (!is_array($values)) {
|
||||
throw new \InvalidArgumentException(sprintf('The action argument "...$%1$s" is required to be an array, the request attribute "%1$s" contains a type of "%2$s" instead.', $argument->getName(), gettype($values)));
|
||||
}
|
||||
|
||||
foreach ($values as $value) {
|
||||
yield $value;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
<?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;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
|
||||
/**
|
||||
* Responsible for resolving the value of an argument based on its metadata.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
interface ArgumentValueResolverInterface
|
||||
{
|
||||
/**
|
||||
* Whether this resolver can resolve can resolve the value for the given ArgumentMetadata.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ArgumentMetadata $argument
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function supports(Request $request, ArgumentMetadata $argument);
|
||||
|
||||
/**
|
||||
* Yield the possible value(s).
|
||||
*
|
||||
* An implementation must yield at least one value.
|
||||
*
|
||||
* @param Request $request
|
||||
* @param ArgumentMetadata $argument
|
||||
*
|
||||
* @return \Generator
|
||||
*/
|
||||
public function resolve(Request $request, ArgumentMetadata $argument);
|
||||
}
|
@ -23,7 +23,7 @@ use Symfony\Component\HttpFoundation\Request;
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ControllerResolver extends ArgumentResolver implements ControllerResolverInterface
|
||||
class ControllerResolver extends LegacyArgumentResolver implements ControllerResolverInterface
|
||||
{
|
||||
private $logger;
|
||||
|
||||
@ -85,21 +85,21 @@ class ControllerResolver extends ArgumentResolver implements ControllerResolverI
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @deprecated this method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface or extend the ArgumentResolver instead.
|
||||
* @deprecated this method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface or extend the LegacyArgumentResolver instead.
|
||||
*/
|
||||
public function getArguments(Request $request, $controller)
|
||||
{
|
||||
@trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s or extend the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class, ArgumentResolver::class), E_USER_DEPRECATED);
|
||||
@trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s or extend the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class, LegacyArgumentResolver::class), E_USER_DEPRECATED);
|
||||
|
||||
return parent::getArguments($request, $controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated this method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface or extend the ArgumentResolver instead.
|
||||
* @deprecated this method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface or extend the LegacyArgumentResolver instead.
|
||||
*/
|
||||
protected function doGetArguments(Request $request, $controller, array $parameters)
|
||||
{
|
||||
@trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s or extend the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class, ArgumentResolver::class), E_USER_DEPRECATED);
|
||||
@trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s or extend the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class, LegacyArgumentResolver::class), E_USER_DEPRECATED);
|
||||
|
||||
return parent::doGetArguments($request, $controller, $parameters);
|
||||
}
|
||||
|
@ -0,0 +1,75 @@
|
||||
<?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;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
/**
|
||||
* Responsible for the creation of the action arguments.
|
||||
*
|
||||
* @deprecated This class is deprecated since 3.1 and will be removed in 4.0. Please use the ArgumentResolver::class instead.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class LegacyArgumentResolver implements ArgumentResolverInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getArguments(Request $request, $controller)
|
||||
{
|
||||
// only trigger the deprecation notice if actually used, the ControllerResolver still extends this for BC reasons
|
||||
@trigger_error(sprintf('The %s class is deprecated since 3.1 and will be removed in 4.0. Please use the %s instead.', __CLASS__, ArgumentResolver::class), E_USER_DEPRECATED);
|
||||
|
||||
if (is_array($controller)) {
|
||||
$r = new \ReflectionMethod($controller[0], $controller[1]);
|
||||
} elseif (is_object($controller) && !$controller instanceof \Closure) {
|
||||
$r = new \ReflectionObject($controller);
|
||||
$r = $r->getMethod('__invoke');
|
||||
} else {
|
||||
$r = new \ReflectionFunction($controller);
|
||||
}
|
||||
|
||||
return $this->doGetArguments($request, $controller, $r->getParameters());
|
||||
}
|
||||
|
||||
protected function doGetArguments(Request $request, $controller, array $parameters)
|
||||
{
|
||||
$attributes = $request->attributes->all();
|
||||
$arguments = array();
|
||||
foreach ($parameters as $param) {
|
||||
if (array_key_exists($param->name, $attributes)) {
|
||||
if (PHP_VERSION_ID >= 50600 && $param->isVariadic() && is_array($attributes[$param->name])) {
|
||||
$arguments = array_merge($arguments, array_values($attributes[$param->name]));
|
||||
} else {
|
||||
$arguments[] = $attributes[$param->name];
|
||||
}
|
||||
} elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
|
||||
$arguments[] = $request;
|
||||
} elseif ($param->isDefaultValueAvailable()) {
|
||||
$arguments[] = $param->getDefaultValue();
|
||||
} else {
|
||||
if (is_array($controller)) {
|
||||
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
|
||||
} elseif (is_object($controller)) {
|
||||
$repr = get_class($controller);
|
||||
} else {
|
||||
$repr = $controller;
|
||||
}
|
||||
|
||||
throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
}
|
@ -38,6 +38,7 @@ class TraceableControllerResolver implements ControllerResolverInterface, Argume
|
||||
$this->stopwatch = $stopwatch;
|
||||
$this->argumentResolver = $argumentResolver;
|
||||
|
||||
// required for BC reasons
|
||||
if (null === $this->argumentResolver) {
|
||||
$this->argumentResolver = $resolver;
|
||||
}
|
||||
|
@ -0,0 +1,98 @@
|
||||
<?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\ControllerMetadata;
|
||||
|
||||
/**
|
||||
* Responsible for storing metadata of an argument.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
class ArgumentMetadata
|
||||
{
|
||||
private $name;
|
||||
private $type;
|
||||
private $isVariadic;
|
||||
private $hasDefaultValue;
|
||||
private $defaultValue;
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $type
|
||||
* @param bool $isVariadic
|
||||
* @param bool $hasDefaultValue
|
||||
* @param mixed $defaultValue
|
||||
*/
|
||||
public function __construct($name, $type, $isVariadic, $hasDefaultValue, $defaultValue)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->type = $type;
|
||||
$this->isVariadic = $isVariadic;
|
||||
$this->hasDefaultValue = $hasDefaultValue;
|
||||
$this->defaultValue = $defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name as given in PHP, $foo would yield "foo".
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of the argument.
|
||||
*
|
||||
* The type is the PHP class in 5.5+ and additionally the basic type in PHP 7.0+.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the argument is defined as "...$variadic".
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVariadic()
|
||||
{
|
||||
return $this->isVariadic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the argument has a default value.
|
||||
*
|
||||
* Implies whether an argument is optional.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasDefaultValue()
|
||||
{
|
||||
return $this->hasDefaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default value of the argument.
|
||||
*
|
||||
* Make sure to call {@see self::hasDefaultValue()} first to see if a default value is possible.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getDefaultValue()
|
||||
{
|
||||
return $this->defaultValue;
|
||||
}
|
||||
}
|
@ -0,0 +1,109 @@
|
||||
<?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\ControllerMetadata;
|
||||
|
||||
/**
|
||||
* Builds {@see ArgumentMetadata} objects based on the given Controller.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function createArgumentMetadata($controller)
|
||||
{
|
||||
$arguments = array();
|
||||
|
||||
if (is_array($controller)) {
|
||||
$reflection = new \ReflectionMethod($controller[0], $controller[1]);
|
||||
} elseif (is_object($controller) && !$controller instanceof \Closure) {
|
||||
$reflection = (new \ReflectionObject($controller))->getMethod('__invoke');
|
||||
} else {
|
||||
$reflection = new \ReflectionFunction($controller);
|
||||
}
|
||||
|
||||
foreach ($reflection->getParameters() as $param) {
|
||||
$arguments[] = new ArgumentMetadata($param->getName(), $this->getType($param), $this->isVariadic($param), $this->hasDefaulValue($param), $this->getDefaulValue($param));
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an argument is variadic.
|
||||
*
|
||||
* @param \ReflectionParameter $parameter
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function isVariadic(\ReflectionParameter $parameter)
|
||||
{
|
||||
return PHP_VERSION_ID >= 50600 && $parameter->isVariadic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether an argument has a default value.
|
||||
*
|
||||
* @param \ReflectionParameter $parameter
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function hasDefaulValue(\ReflectionParameter $parameter)
|
||||
{
|
||||
return $parameter->isDefaultValueAvailable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a default value if available.
|
||||
*
|
||||
* @param \ReflectionParameter $parameter
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
private function getDefaulValue(\ReflectionParameter $parameter)
|
||||
{
|
||||
return $this->hasDefaulValue($parameter) ? $parameter->getDefaultValue() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an associated type to the given parameter if available.
|
||||
*
|
||||
* @param \ReflectionParameter $parameter
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function getType(\ReflectionParameter $parameter)
|
||||
{
|
||||
if (PHP_VERSION_ID >= 70000) {
|
||||
return $parameter->hasType() ? (string) $parameter->getType() : null;
|
||||
}
|
||||
|
||||
if ($parameter->isArray()) {
|
||||
return 'array';
|
||||
}
|
||||
|
||||
if ($parameter->isCallable()) {
|
||||
return 'callable';
|
||||
}
|
||||
|
||||
try {
|
||||
$refClass = $parameter->getClass();
|
||||
} catch (\ReflectionException $e) {
|
||||
// mandatory; extract it from the exception message
|
||||
return str_replace(['Class ', ' does not exist'], '', $e->getMessage());
|
||||
}
|
||||
|
||||
return $refClass ? $refClass->getName() : null;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?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\ControllerMetadata;
|
||||
|
||||
/**
|
||||
* Builds method argument data.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
interface ArgumentMetadataFactoryInterface
|
||||
{
|
||||
/**
|
||||
* @param mixed $controller The controller to resolve the arguments for.
|
||||
*
|
||||
* @return ArgumentMetadata[]
|
||||
*/
|
||||
public function createArgumentMetadata($controller);
|
||||
}
|
@ -11,7 +11,6 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
@ -40,14 +39,6 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
|
||||
protected $requestStack;
|
||||
private $argumentResolver;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
|
||||
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
||||
* @param RequestStack $requestStack A stack for master/sub requests
|
||||
* @param ArgumentResolverInterface $argumentResolver An ArgumentResolverInterface instance
|
||||
*/
|
||||
public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null, ArgumentResolverInterface $argumentResolver = null)
|
||||
{
|
||||
$this->dispatcher = $dispatcher;
|
||||
|
@ -12,18 +12,28 @@
|
||||
namespace Symfony\Component\HttpKernel\Tests\Controller;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\ArgumentFromAttributeResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\DefaultArgumentValueResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\RequestResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\VariadicArgumentValueResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory;
|
||||
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\VariadicController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class ArgumentResolverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testGetArguments()
|
||||
{
|
||||
$resolver = new ArgumentResolver();
|
||||
$factory = new ArgumentMetadataFactory();
|
||||
$argumentValueResolvers = array(
|
||||
new ArgumentFromAttributeResolver(),
|
||||
new VariadicArgumentValueResolver(),
|
||||
new RequestResolver(),
|
||||
new DefaultArgumentValueResolver(),
|
||||
);
|
||||
|
||||
$resolver = new ArgumentResolver($factory, $argumentValueResolvers);
|
||||
|
||||
$request = Request::create('/');
|
||||
$controller = array(new self(), 'testGetArguments');
|
||||
@ -62,7 +72,7 @@ class ArgumentResolverTest extends \PHPUnit_Framework_TestCase
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$request->attributes->set('foobar', 'foobar');
|
||||
$controller = 'Symfony\Component\HttpKernel\Tests\Controller\another_controller_function';
|
||||
$controller = 'Symfony\Component\HttpKernel\Tests\Controller\argument_resolver_controller_function';
|
||||
$this->assertEquals(array('foo', 'foobar'), $resolver->getArguments($request, $controller));
|
||||
|
||||
$request = Request::create('/');
|
||||
@ -84,11 +94,18 @@ class ArgumentResolverTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
* @group legacy
|
||||
*/
|
||||
public function testGetVariadicArguments()
|
||||
{
|
||||
$resolver = new ControllerResolver();
|
||||
$factory = new ArgumentMetadataFactory();
|
||||
$argumentValueResolvers = array(
|
||||
new ArgumentFromAttributeResolver(),
|
||||
new VariadicArgumentValueResolver(),
|
||||
new RequestResolver(),
|
||||
new DefaultArgumentValueResolver(),
|
||||
);
|
||||
|
||||
$resolver = new ArgumentResolver($factory, $argumentValueResolvers);
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
@ -97,14 +114,47 @@ class ArgumentResolverTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(array('foo', 'foo', 'bar'), $resolver->getArguments($request, $controller));
|
||||
}
|
||||
|
||||
public function testCreateControllerCanReturnAnyCallable()
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testGetVariadicArgumentsWithoutArrayInRequest()
|
||||
{
|
||||
$mock = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolver', array('createController'));
|
||||
$mock->expects($this->once())->method('createController')->will($this->returnValue('Symfony\Component\HttpKernel\Tests\Controller\another_controller_function'));
|
||||
$factory = new ArgumentMetadataFactory();
|
||||
$argumentValueResolvers = array(
|
||||
new ArgumentFromAttributeResolver(),
|
||||
new VariadicArgumentValueResolver(),
|
||||
new RequestResolver(),
|
||||
new DefaultArgumentValueResolver(),
|
||||
);
|
||||
|
||||
$resolver = new ArgumentResolver($factory, $argumentValueResolvers);
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('_controller', 'foobar');
|
||||
$mock->getController($request);
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$request->attributes->set('bar', 'foo');
|
||||
$controller = array(new VariadicController(), 'action');
|
||||
$resolver->getArguments($request, $controller);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testGetArgumentWithoutArray()
|
||||
{
|
||||
$factory = new ArgumentMetadataFactory();
|
||||
$valueResolver = $this->getMock(ArgumentValueResolverInterface::class);
|
||||
$resolver = new ArgumentResolver($factory, array($valueResolver));
|
||||
|
||||
$valueResolver->expects($this->any())->method('supports')->willReturn(true);
|
||||
$valueResolver->expects($this->any())->method('resolve')->willReturn('foo');
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$request->attributes->set('bar', 'foo');
|
||||
$controller = array($this, 'controllerMethod2');
|
||||
$resolver->getArguments($request, $controller);
|
||||
}
|
||||
|
||||
public function __invoke($foo, $bar = null)
|
||||
@ -132,6 +182,6 @@ class ArgumentResolverTest extends \PHPUnit_Framework_TestCase
|
||||
}
|
||||
}
|
||||
|
||||
function another_controller_function($foo, $foobar)
|
||||
function argument_resolver_controller_function($foo, $foobar)
|
||||
{
|
||||
}
|
||||
|
@ -0,0 +1,123 @@
|
||||
<?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\Controller;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\LegacyArgumentResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
|
||||
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\VariadicController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
||||
class LegacyArgumentResolverTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGetArguments()
|
||||
{
|
||||
$resolver = new LegacyArgumentResolver();
|
||||
|
||||
$request = Request::create('/');
|
||||
$controller = array(new self(), 'testGetArguments');
|
||||
$this->assertEquals(array(), $resolver->getArguments($request, $controller), '->getArguments() returns an empty array if the method takes no arguments');
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$controller = array(new self(), 'controllerMethod1');
|
||||
$this->assertEquals(array('foo'), $resolver->getArguments($request, $controller), '->getArguments() returns an array of arguments for the controller method');
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$controller = array(new self(), 'controllerMethod2');
|
||||
$this->assertEquals(array('foo', null), $resolver->getArguments($request, $controller), '->getArguments() uses default values if present');
|
||||
|
||||
$request->attributes->set('bar', 'bar');
|
||||
$this->assertEquals(array('foo', 'bar'), $resolver->getArguments($request, $controller), '->getArguments() overrides default values if provided in the request attributes');
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$controller = function ($foo) {};
|
||||
$this->assertEquals(array('foo'), $resolver->getArguments($request, $controller));
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$controller = function ($foo, $bar = 'bar') {};
|
||||
$this->assertEquals(array('foo', 'bar'), $resolver->getArguments($request, $controller));
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$controller = new self();
|
||||
$this->assertEquals(array('foo', null), $resolver->getArguments($request, $controller));
|
||||
$request->attributes->set('bar', 'bar');
|
||||
$this->assertEquals(array('foo', 'bar'), $resolver->getArguments($request, $controller));
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$request->attributes->set('foobar', 'foobar');
|
||||
$controller = 'Symfony\Component\HttpKernel\Tests\Controller\another_controller_function';
|
||||
$this->assertEquals(array('foo', 'foobar'), $resolver->getArguments($request, $controller));
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$request->attributes->set('foobar', 'foobar');
|
||||
$controller = array(new self(), 'controllerMethod3');
|
||||
|
||||
try {
|
||||
$resolver->getArguments($request, $controller);
|
||||
$this->fail('->getArguments() throws a \RuntimeException exception if it cannot determine the argument value');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertInstanceOf('\RuntimeException', $e, '->getArguments() throws a \RuntimeException exception if it cannot determine the argument value');
|
||||
}
|
||||
|
||||
$request = Request::create('/');
|
||||
$controller = array(new self(), 'controllerMethod5');
|
||||
$this->assertEquals(array($request), $resolver->getArguments($request, $controller), '->getArguments() injects the request');
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
*/
|
||||
public function testGetVariadicArguments()
|
||||
{
|
||||
$resolver = new ControllerResolver();
|
||||
|
||||
$request = Request::create('/');
|
||||
$request->attributes->set('foo', 'foo');
|
||||
$request->attributes->set('bar', array('foo', 'bar'));
|
||||
$controller = array(new VariadicController(), 'action');
|
||||
$this->assertEquals(array('foo', 'foo', 'bar'), $resolver->getArguments($request, $controller));
|
||||
}
|
||||
|
||||
public function __invoke($foo, $bar = null)
|
||||
{
|
||||
}
|
||||
|
||||
public function controllerMethod1($foo)
|
||||
{
|
||||
}
|
||||
|
||||
protected function controllerMethod2($foo, $bar = null)
|
||||
{
|
||||
}
|
||||
|
||||
protected function controllerMethod3($foo, $bar, $foobar)
|
||||
{
|
||||
}
|
||||
|
||||
protected static function controllerMethod4()
|
||||
{
|
||||
}
|
||||
|
||||
protected function controllerMethod5(Request $request)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function another_controller_function($foo, $foobar)
|
||||
{
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
<?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\ControllerMetadata;
|
||||
|
||||
use Fake\ImportedAndFake;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory;
|
||||
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\BasicTypesController;
|
||||
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\VariadicController;
|
||||
|
||||
class ArgumentMetadataFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
private $factory;
|
||||
|
||||
protected function setUp()
|
||||
{
|
||||
$this->factory = new ArgumentMetadataFactory();
|
||||
}
|
||||
|
||||
public function testSignature1()
|
||||
{
|
||||
$arguments = $this->factory->createArgumentMetadata([$this, 'signature1']);
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ArgumentMetadata('foo', self::class, false, false, null),
|
||||
new ArgumentMetadata('bar', 'array', false, false, null),
|
||||
new ArgumentMetadata('baz', 'callable', false, false, null),
|
||||
), $arguments);
|
||||
}
|
||||
|
||||
public function testSignature2()
|
||||
{
|
||||
$arguments = $this->factory->createArgumentMetadata([$this, 'signature2']);
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ArgumentMetadata('foo', self::class, false, true, null),
|
||||
new ArgumentMetadata('bar', __NAMESPACE__.'\FakeClassThatDoesNotExist', false, true, null),
|
||||
new ArgumentMetadata('baz', 'Fake\ImportedAndFake', false, true, null),
|
||||
), $arguments);
|
||||
}
|
||||
|
||||
public function testSignature3()
|
||||
{
|
||||
$arguments = $this->factory->createArgumentMetadata([$this, 'signature3']);
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ArgumentMetadata('bar', __NAMESPACE__.'\FakeClassThatDoesNotExist', false, false, null),
|
||||
new ArgumentMetadata('baz', 'Fake\ImportedAndFake', false, false, null),
|
||||
), $arguments);
|
||||
}
|
||||
|
||||
public function testSignature4()
|
||||
{
|
||||
$arguments = $this->factory->createArgumentMetadata([$this, 'signature4']);
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ArgumentMetadata('foo', null, false, true, 'default'),
|
||||
new ArgumentMetadata('bar', null, false, true, 500),
|
||||
new ArgumentMetadata('baz', null, false, true, []),
|
||||
), $arguments);
|
||||
}
|
||||
|
||||
public function testSignature5()
|
||||
{
|
||||
$arguments = $this->factory->createArgumentMetadata([$this, 'signature5']);
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ArgumentMetadata('foo', 'array', false, true, null),
|
||||
new ArgumentMetadata('bar', null, false, false, null),
|
||||
), $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 5.6
|
||||
*/
|
||||
public function testVariadicSignature()
|
||||
{
|
||||
$arguments = $this->factory->createArgumentMetadata([new VariadicController(), 'action']);
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ArgumentMetadata('foo', null, false, false, null),
|
||||
new ArgumentMetadata('bar', null, true, false, null),
|
||||
), $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* @requires PHP 7.0
|
||||
*/
|
||||
public function testBasicTypesSignature()
|
||||
{
|
||||
$arguments = $this->factory->createArgumentMetadata([new BasicTypesController(), 'action']);
|
||||
|
||||
$this->assertEquals(array(
|
||||
new ArgumentMetadata('foo', 'string', false, false, null),
|
||||
new ArgumentMetadata('bar', 'int', false, false, null),
|
||||
new ArgumentMetadata('baz', 'float', false, false, null),
|
||||
), $arguments);
|
||||
}
|
||||
|
||||
private function signature1(ArgumentMetadataFactoryTest $foo, array $bar, callable $baz)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private function signature2(ArgumentMetadataFactoryTest $foo = null, FakeClassThatDoesNotExist $bar = null, ImportedAndFake $baz = null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private function signature3(FakeClassThatDoesNotExist $bar, ImportedAndFake $baz)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private function signature4($foo = 'default', $bar = 500, $baz = [])
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private function signature5(array $foo = null, $bar)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Tests\DataCollector;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
|
||||
@ -191,7 +192,7 @@ class RequestDataCollectorTest extends \PHPUnit_Framework_TestCase
|
||||
protected function injectController($collector, $controller, $request)
|
||||
{
|
||||
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
|
||||
$httpKernel = new HttpKernel(new EventDispatcher(), $resolver);
|
||||
$httpKernel = new HttpKernel(new EventDispatcher(), $resolver, null, $this->getMock(ArgumentResolverInterface::class));
|
||||
$event = new FilterControllerEvent($httpKernel, $controller, $request, HttpKernelInterface::MASTER_REQUEST);
|
||||
$collector->onKernelController($event);
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Tests\Fixtures\Controller;
|
||||
|
||||
class BasicTypesController
|
||||
{
|
||||
public function action(string $foo, int $bar, float $baz)
|
||||
{
|
||||
}
|
||||
}
|
@ -13,7 +13,13 @@ namespace Symfony\Component\HttpKernel\Tests\Fragment;
|
||||
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\ArgumentFromAttributeResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\DefaultArgumentValueResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\RequestResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\VariadicArgumentValueResolver;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
||||
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory;
|
||||
use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
@ -51,7 +57,10 @@ class InlineFragmentRendererTest extends \PHPUnit_Framework_TestCase
|
||||
$strategy->render(new ControllerReference('main_controller', array('object' => $object), array()), Request::create('/'));
|
||||
}
|
||||
|
||||
public function testRenderWithObjectsAsAttributesPassedAsObjectsInTheController()
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testRenderWithObjectsAsAttributesPassedAsObjectsInTheControllerLegacy()
|
||||
{
|
||||
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver', array('getController'));
|
||||
$resolver
|
||||
@ -62,7 +71,34 @@ class InlineFragmentRendererTest extends \PHPUnit_Framework_TestCase
|
||||
}))
|
||||
;
|
||||
|
||||
$kernel = new HttpKernel(new EventDispatcher(), $resolver, new RequestStack(), new ArgumentResolver());
|
||||
$kernel = new HttpKernel(new EventDispatcher(), $resolver, new RequestStack());
|
||||
$renderer = new InlineFragmentRenderer($kernel);
|
||||
|
||||
$response = $renderer->render(new ControllerReference('main_controller', array('object' => new \stdClass(), 'object1' => new Bar()), array()), Request::create('/'));
|
||||
$this->assertEquals('bar', $response->getContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
*/
|
||||
public function testRenderWithObjectsAsAttributesPassedAsObjectsInTheController()
|
||||
{
|
||||
$resolver = $this->getMock(ControllerResolverInterface::class);
|
||||
$resolver
|
||||
->expects($this->once())
|
||||
->method('getController')
|
||||
->will($this->returnValue(function (\stdClass $object, Bar $object1) {
|
||||
return new Response($object1->getBar());
|
||||
}))
|
||||
;
|
||||
$argumentValueResolvers = array(
|
||||
new ArgumentFromAttributeResolver(),
|
||||
new VariadicArgumentValueResolver(),
|
||||
new RequestResolver(),
|
||||
new DefaultArgumentValueResolver(),
|
||||
);
|
||||
|
||||
$kernel = new HttpKernel(new EventDispatcher(), $resolver, new RequestStack(), new ArgumentResolver(new ArgumentMetadataFactory(), $argumentValueResolvers));
|
||||
$renderer = new InlineFragmentRenderer($kernel);
|
||||
|
||||
$response = $renderer->render(new ControllerReference('main_controller', array('object' => new \stdClass(), 'object1' => new Bar()), array()), Request::create('/'));
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Tests\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -18,7 +19,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
|
||||
class TestHttpKernel extends HttpKernel implements ControllerResolverInterface, ArgumentResolverInterface
|
||||
{
|
||||
protected $body;
|
||||
protected $status;
|
||||
@ -35,7 +36,7 @@ class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
|
||||
$this->headers = $headers;
|
||||
$this->customizer = $customizer;
|
||||
|
||||
parent::__construct(new EventDispatcher(), $this);
|
||||
parent::__construct(new EventDispatcher(), $this, null, $this);
|
||||
}
|
||||
|
||||
public function getBackendRequest()
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Tests\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
@ -18,7 +19,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInterface
|
||||
class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInterface, ArgumentResolverInterface
|
||||
{
|
||||
protected $bodies = array();
|
||||
protected $statuses = array();
|
||||
@ -34,7 +35,7 @@ class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInt
|
||||
$this->headers[] = $response['headers'];
|
||||
}
|
||||
|
||||
parent::__construct(new EventDispatcher(), $this);
|
||||
parent::__construct(new EventDispatcher(), $this, null, $this);
|
||||
}
|
||||
|
||||
public function getBackendRequest()
|
||||
|
@ -11,6 +11,10 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Tests;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
@ -28,7 +32,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testHandleWhenControllerThrowsAnExceptionAndCatchIsTrue()
|
||||
{
|
||||
$kernel = new HttpKernel(new EventDispatcher(), $this->getResolver(function () { throw new \RuntimeException(); }));
|
||||
$kernel = $this->getHttpKernel(new EventDispatcher(), function () { throw new \RuntimeException(); });
|
||||
|
||||
$kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, true);
|
||||
}
|
||||
@ -38,7 +42,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testHandleWhenControllerThrowsAnExceptionAndCatchIsFalseAndNoListenerIsRegistered()
|
||||
{
|
||||
$kernel = new HttpKernel(new EventDispatcher(), $this->getResolver(function () { throw new \RuntimeException(); }));
|
||||
$kernel = $this->getHttpKernel(new EventDispatcher(), function () { throw new \RuntimeException(); });
|
||||
|
||||
$kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, false);
|
||||
}
|
||||
@ -50,7 +54,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$event->setResponse(new Response($event->getException()->getMessage()));
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new \RuntimeException('foo'); }));
|
||||
$kernel = $this->getHttpKernel($dispatcher, function () { throw new \RuntimeException('foo'); });
|
||||
$response = $kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, true);
|
||||
|
||||
$this->assertEquals('500', $response->getStatusCode());
|
||||
@ -66,7 +70,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
// should set a response, but does not
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () use ($exception) { throw $exception; }));
|
||||
$kernel = $this->getHttpKernel($dispatcher, function () use ($exception) { throw $exception; });
|
||||
|
||||
try {
|
||||
$kernel->handle(new Request(), HttpKernelInterface::MASTER_REQUEST, true);
|
||||
@ -83,7 +87,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$event->setResponse(new RedirectResponse('/login', 301));
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new AccessDeniedHttpException(); }));
|
||||
$kernel = $this->getHttpKernel($dispatcher, function () { throw new AccessDeniedHttpException(); });
|
||||
$response = $kernel->handle(new Request());
|
||||
|
||||
$this->assertEquals('301', $response->getStatusCode());
|
||||
@ -97,7 +101,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$event->setResponse(new Response($event->getException()->getMessage()));
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new MethodNotAllowedHttpException(array('POST')); }));
|
||||
$kernel = $this->getHttpKernel($dispatcher, function () { throw new MethodNotAllowedHttpException(array('POST')); });
|
||||
$response = $kernel->handle(new Request());
|
||||
|
||||
$this->assertEquals('405', $response->getStatusCode());
|
||||
@ -114,7 +118,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$event->setResponse(new Response('', $responseStatusCode, array('X-Status-Code' => $expectedStatusCode)));
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { throw new \RuntimeException(); }));
|
||||
$kernel = $this->getHttpKernel($dispatcher, function () { throw new \RuntimeException(); });
|
||||
$response = $kernel->handle(new Request());
|
||||
|
||||
$this->assertEquals($expectedStatusCode, $response->getStatusCode());
|
||||
@ -138,7 +142,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$event->setResponse(new Response('hello'));
|
||||
});
|
||||
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver());
|
||||
$kernel = $this->getHttpKernel($dispatcher);
|
||||
|
||||
$this->assertEquals('hello', $kernel->handle(new Request())->getContent());
|
||||
}
|
||||
@ -149,7 +153,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
public function testHandleWhenNoControllerIsFound()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(false));
|
||||
$kernel = $this->getHttpKernel($dispatcher, false);
|
||||
|
||||
$kernel->handle(new Request());
|
||||
}
|
||||
@ -158,7 +162,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
$response = new Response('foo');
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () use ($response) { return $response; }));
|
||||
$kernel = $this->getHttpKernel($dispatcher, function () use ($response) { return $response; });
|
||||
|
||||
$this->assertSame($response, $kernel->handle(new Request()));
|
||||
}
|
||||
@ -166,7 +170,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
public function testHandleWhenTheControllerIsAnObjectWithInvoke()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(new Controller()));
|
||||
$kernel = $this->getHttpKernel($dispatcher, new Controller());
|
||||
|
||||
$this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
|
||||
}
|
||||
@ -174,7 +178,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
public function testHandleWhenTheControllerIsAFunction()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver('Symfony\Component\HttpKernel\Tests\controller_func'));
|
||||
$kernel = $this->getHttpKernel($dispatcher, 'Symfony\Component\HttpKernel\Tests\controller_func');
|
||||
|
||||
$this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
|
||||
}
|
||||
@ -182,7 +186,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
public function testHandleWhenTheControllerIsAnArray()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(array(new Controller(), 'controller')));
|
||||
$kernel = $this->getHttpKernel($dispatcher, array(new Controller(), 'controller'));
|
||||
|
||||
$this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
|
||||
}
|
||||
@ -190,7 +194,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
public function testHandleWhenTheControllerIsAStaticArray()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(array('Symfony\Component\HttpKernel\Tests\Controller', 'staticcontroller')));
|
||||
$kernel = $this->getHttpKernel($dispatcher, array('Symfony\Component\HttpKernel\Tests\Controller', 'staticcontroller'));
|
||||
|
||||
$this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
|
||||
}
|
||||
@ -201,7 +205,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
public function testHandleWhenTheControllerDoesNotReturnAResponse()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { return 'foo'; }));
|
||||
$kernel = $this->getHttpKernel($dispatcher, function () { return 'foo'; });
|
||||
|
||||
$kernel->handle(new Request());
|
||||
}
|
||||
@ -212,7 +216,8 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$dispatcher->addListener(KernelEvents::VIEW, function ($event) {
|
||||
$event->setResponse(new Response($event->getControllerResult()));
|
||||
});
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(function () { return 'foo'; }));
|
||||
|
||||
$kernel = $this->getHttpKernel($dispatcher, function () { return 'foo'; });
|
||||
|
||||
$this->assertEquals('foo', $kernel->handle(new Request())->getContent());
|
||||
}
|
||||
@ -223,7 +228,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$dispatcher->addListener(KernelEvents::RESPONSE, function ($event) {
|
||||
$event->setResponse(new Response('foo'));
|
||||
});
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver());
|
||||
$kernel = $this->getHttpKernel($dispatcher);
|
||||
|
||||
$this->assertEquals('foo', $kernel->handle(new Request())->getContent());
|
||||
}
|
||||
@ -231,7 +236,7 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
public function testTerminate()
|
||||
{
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver());
|
||||
$kernel = $this->getHttpKernel($dispatcher);
|
||||
$dispatcher->addListener(KernelEvents::TERMINATE, function ($event) use (&$called, &$capturedKernel, &$capturedRequest, &$capturedResponse) {
|
||||
$called = true;
|
||||
$capturedKernel = $event->getKernel();
|
||||
@ -255,29 +260,33 @@ class HttpKernelTest extends \PHPUnit_Framework_TestCase
|
||||
$stack->expects($this->at(1))->method('pop');
|
||||
|
||||
$dispatcher = new EventDispatcher();
|
||||
$kernel = new HttpKernel($dispatcher, $this->getResolver(), $stack);
|
||||
$kernel = $this->getHttpKernel($dispatcher, null, $stack);
|
||||
|
||||
$kernel->handle($request, HttpKernelInterface::MASTER_REQUEST);
|
||||
}
|
||||
|
||||
protected function getResolver($controller = null)
|
||||
private function getHttpKernel(EventDispatcherInterface $eventDispatcher, $controller = null, RequestStack $requestStack = null)
|
||||
{
|
||||
if (null === $controller) {
|
||||
$controller = function () { return new Response('Hello'); };
|
||||
}
|
||||
|
||||
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
|
||||
$resolver->expects($this->any())
|
||||
$controllerResolver = $this->getMock(ControllerResolverInterface::class);
|
||||
$controllerResolver
|
||||
->expects($this->any())
|
||||
->method('getController')
|
||||
->will($this->returnValue($controller));
|
||||
$resolver->expects($this->any())
|
||||
|
||||
$argumentResolver = $this->getMock(ArgumentResolverInterface::class);
|
||||
$argumentResolver
|
||||
->expects($this->any())
|
||||
->method('getArguments')
|
||||
->will($this->returnValue(array()));
|
||||
|
||||
return $resolver;
|
||||
return new HttpKernel($eventDispatcher, $controllerResolver, $requestStack, $argumentResolver);
|
||||
}
|
||||
|
||||
protected function assertResponseEquals(Response $expected, Response $actual)
|
||||
private function assertResponseEquals(Response $expected, Response $actual)
|
||||
{
|
||||
$expected->setDate($actual->getDate());
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
@ -11,17 +11,18 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\Tests;
|
||||
|
||||
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
|
||||
use Symfony\Component\HttpKernel\HttpKernel;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||
|
||||
class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
|
||||
class TestHttpKernel extends HttpKernel implements ControllerResolverInterface, ArgumentResolverInterface
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(new EventDispatcher(), $this);
|
||||
parent::__construct(new EventDispatcher(), $this, null, $this);
|
||||
}
|
||||
|
||||
public function getController(Request $request)
|
||||
|
Reference in New Issue
Block a user