vendor/sensio/framework-extra-bundle/src/EventListener/ParamConverterListener.php line 47

Open in your IDE?
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Sensio\Bundle\FrameworkExtraBundle\EventListener;
  11. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  12. use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterManager;
  13. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpKernel\Event\KernelEvent;
  16. use Symfony\Component\HttpKernel\KernelEvents;
  17. /**
  18. * The ParamConverterListener handles the ParamConverter annotation.
  19. *
  20. * @author Fabien Potencier <fabien@symfony.com>
  21. */
  22. class ParamConverterListener implements EventSubscriberInterface
  23. {
  24. /**
  25. * @var ParamConverterManager
  26. */
  27. private $manager;
  28. private $autoConvert;
  29. /**
  30. * @param bool $autoConvert Auto convert non-configured objects
  31. */
  32. public function __construct(ParamConverterManager $manager, $autoConvert = true)
  33. {
  34. $this->manager = $manager;
  35. $this->autoConvert = $autoConvert;
  36. }
  37. /**
  38. * Modifies the ParamConverterManager instance.
  39. */
  40. public function onKernelController(KernelEvent $event)
  41. {
  42. $controller = $event->getController();
  43. $request = $event->getRequest();
  44. $configurations = [];
  45. if ($configuration = $request->attributes->get('_converters')) {
  46. foreach (\is_array($configuration) ? $configuration : [$configuration] as $configuration) {
  47. $configurations[$configuration->getName()] = $configuration;
  48. }
  49. }
  50. if (\is_array($controller)) {
  51. $r = new \ReflectionMethod($controller[0], $controller[1]);
  52. } elseif (\is_object($controller) && \is_callable([$controller, '__invoke'])) {
  53. $r = new \ReflectionMethod($controller, '__invoke');
  54. } else {
  55. $r = new \ReflectionFunction($controller);
  56. }
  57. // automatically apply conversion for non-configured objects
  58. if ($this->autoConvert) {
  59. $configurations = $this->autoConfigure($r, $request, $configurations);
  60. }
  61. $this->manager->apply($request, $configurations);
  62. }
  63. private function autoConfigure(\ReflectionFunctionAbstract $r, Request $request, $configurations)
  64. {
  65. foreach ($r->getParameters() as $param) {
  66. $type = $param->getType();
  67. $class = null !== $type && !$type->isBuiltin() ? $type->getName() : null;
  68. if (null !== $class && $request instanceof $class) {
  69. continue;
  70. }
  71. $name = $param->getName();
  72. if ($type) {
  73. if (!isset($configurations[$name])) {
  74. $configuration = new ParamConverter([]);
  75. $configuration->setName($name);
  76. $configurations[$name] = $configuration;
  77. }
  78. if (null !== $class && null === $configurations[$name]->getClass()) {
  79. $configurations[$name]->setClass($class);
  80. }
  81. }
  82. if (isset($configurations[$name])) {
  83. $configurations[$name]->setIsOptional($param->isOptional() || $param->isDefaultValueAvailable() || ($type && $type->allowsNull()));
  84. }
  85. }
  86. return $configurations;
  87. }
  88. /**
  89. * {@inheritdoc}
  90. */
  91. public static function getSubscribedEvents()
  92. {
  93. return [
  94. KernelEvents::CONTROLLER => 'onKernelController',
  95. ];
  96. }
  97. }