diff --git a/DependencyInjection/Compiler/HandlerRegistryDecorationPass.php b/DependencyInjection/Compiler/HandlerRegistryDecorationPass.php new file mode 100644 index 000000000..94998c7fa --- /dev/null +++ b/DependencyInjection/Compiler/HandlerRegistryDecorationPass.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace FOS\RestBundle\DependencyInjection\Compiler; + +use FOS\RestBundle\Serializer\JMSHandlerRegistry; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Decorates the handler registry from JMSSerializerBundle. + * + * The logic is borrowed from the core Symfony DecoratorServicePass, but is implemented here to respect the fact that + * custom handlers are registered in JMSSerializerBundle in a compiler pass that is executed after decorated services + * have been resolved. + * + * @author Christian Flothmann + */ +class HandlerRegistryDecorationPass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container) + { + if (!$container->has('fos_rest.serializer.jms_handler_registry')) { + return; + } + + $jmsHandlerRegistry = $container->findDefinition('fos_rest.serializer.jms_handler_registry'); + $public = $jmsHandlerRegistry->isPublic(); + $jmsHandlerRegistry->setPublic(false); + $container->setDefinition('fos_rest.serializer.jms_handler_registry.inner', $jmsHandlerRegistry); + + $fosRestHandlerRegistry = $container->register('jms_serializer.handler_registry', JMSHandlerRegistry::class) + ->setPublic($public) + ->addArgument(new Reference('fos_rest.serializer.jms_handler_registry.inner')); + + // remap existing aliases (they have already been replaced with the actual definition by Symfony's ReplaceAliasByActualDefinitonPass) + foreach ($container->getDefinitions() as $id => $definition) { + if ('fos_rest.serializer.jms_handler_registry.inner' !== $id && $definition === $jmsHandlerRegistry) { + $container->setDefinition($id, $fosRestHandlerRegistry); + } + } + } +} diff --git a/DependencyInjection/Compiler/JMSHandlersPass.php b/DependencyInjection/Compiler/JMSHandlersPass.php index 3495db73d..06b681ff3 100644 --- a/DependencyInjection/Compiler/JMSHandlersPass.php +++ b/DependencyInjection/Compiler/JMSHandlersPass.php @@ -11,8 +11,7 @@ namespace FOS\RestBundle\DependencyInjection\Compiler; -use Symfony\Component\DependencyInjection\Reference; -use Symfony\Component\DependencyInjection\Definition; +use Symfony\Component\DependencyInjection\Alias; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; @@ -28,7 +27,8 @@ final class JMSHandlersPass implements CompilerPassInterface public function process(ContainerBuilder $container) { if ($container->has('jms_serializer.handler_registry')) { - $this->registerHandlerRegistry($container); + // the public alias prevents the handler registry definition from being removed + $container->setAlias('fos_rest.serializer.jms_handler_registry', new Alias('jms_serializer.handler_registry', true)); return; } @@ -37,19 +37,4 @@ public function process(ContainerBuilder $container) $container->removeDefinition('fos_rest.serializer.exception_normalizer.jms'); $container->getParameterBag()->remove('jms_serializer.form_error_handler.class'); } - - /** - * Inlined because {@link JMS\SerializerBundle\DependencyInjection\Compiler\CustomHandlersPass} - * must be executed before replacing jms_serializer.handler_registry. - */ - public function registerHandlerRegistry(ContainerBuilder $container) - { - $handlerRegistry = new Definition('FOS\RestBundle\Serializer\JMSHandlerRegistry', array(new Reference('fos_rest.serializer.jms_handler_registry'))); - - $oldRegistry = $container->getDefinition('jms_serializer.handler_registry'); - $oldRegistry->setPublic(false); - - $container->setDefinition('jms_serializer.handler_registry', $handlerRegistry); - $container->setDefinition('fos_rest.serializer.jms_handler_registry', $oldRegistry); - } } diff --git a/FOSRestBundle.php b/FOSRestBundle.php index 3ad54c8ba..af8626a03 100644 --- a/FOSRestBundle.php +++ b/FOSRestBundle.php @@ -12,6 +12,7 @@ namespace FOS\RestBundle; use FOS\RestBundle\DependencyInjection\Compiler\ConfigurationCheckPass; +use FOS\RestBundle\DependencyInjection\Compiler\HandlerRegistryDecorationPass; use FOS\RestBundle\DependencyInjection\Compiler\JMSFormErrorHandlerPass; use FOS\RestBundle\DependencyInjection\Compiler\JMSHandlersPass; use FOS\RestBundle\DependencyInjection\Compiler\FormatListenerRulesPass; @@ -40,5 +41,6 @@ public function build(ContainerBuilder $container) $container->addCompilerPass(new TwigExceptionPass()); $container->addCompilerPass(new JMSFormErrorHandlerPass()); $container->addCompilerPass(new JMSHandlersPass(), PassConfig::TYPE_BEFORE_REMOVING, -10); + $container->addCompilerPass(new HandlerRegistryDecorationPass(), PassConfig::TYPE_AFTER_REMOVING); } }