Skip to content

Commit

Permalink
[Messenger] Wire the transaction middleware factory when component is…
Browse files Browse the repository at this point in the history
… enabled
  • Loading branch information
ogizanagi committed May 11, 2018
1 parent 1f504e5 commit cf4d445
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 2 deletions.
25 changes: 25 additions & 0 deletions DependencyInjection/Compiler/MessengerPass.php
@@ -0,0 +1,25 @@
<?php

namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Messenger\MessageBusInterface;

/**
* Class for Symfony Messenger component integrations
*/
class MessengerPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
// Remove wired services if the Messenger component actually isn't enabled:
if (!$container->hasAlias('message_bus') || !is_subclass_of($container->findDefinition('message_bus')->getClass(), MessageBusInterface::class)) {
$container->removeDefinition('doctrine.orm.messenger.middleware_factory.transaction');
$container->removeDefinition('messenger.middleware.doctrine_transaction_middleware');
}
}
}
12 changes: 12 additions & 0 deletions DependencyInjection/DoctrineExtension.php
Expand Up @@ -9,6 +9,7 @@
use Doctrine\ORM\Version;
use Symfony\Bridge\Doctrine\DependencyInjection\AbstractDoctrineExtension;
use Symfony\Bridge\Doctrine\Form\Type\DoctrineType;
use Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddlewareFactory;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
Expand All @@ -20,6 +21,7 @@
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Messenger\MessageBus;

/**
* DoctrineExtension is an extension for the Doctrine DBAL and ORM library.
Expand Down Expand Up @@ -388,6 +390,16 @@ protected function ormLoad(array $config, ContainerBuilder $container)
->addTag(ServiceRepositoryCompilerPass::REPOSITORY_SERVICE_TAG);
}

// If the Messenger component is installed and the doctrine transaction middleware factory is available, wire it:
if (class_exists(MessageBus::class) && class_exists(DoctrineTransactionMiddlewareFactory::class)) {
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('messenger.xml');

$container->getDefinition('messenger.middleware.doctrine_transaction_middleware')
->replaceArgument(0, $config['default_entity_manager'])
;
}

/*
* Compatibility for Symfony 3.2 and lower: gives the service a default argument.
* When DoctrineBundle requires 3.3 or higher, this can be moved to an anonymous
Expand Down
2 changes: 2 additions & 0 deletions DoctrineBundle.php
Expand Up @@ -3,6 +3,7 @@
namespace Doctrine\Bundle\DoctrineBundle;

use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\MessengerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\ORM\Proxy\Autoloader;
Expand Down Expand Up @@ -38,6 +39,7 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new DoctrineValidationPass('orm'));
$container->addCompilerPass(new EntityListenerPass());
$container->addCompilerPass(new ServiceRepositoryCompilerPass());
$container->addCompilerPass(new MessengerPass());
}

/**
Expand Down
20 changes: 20 additions & 0 deletions Resources/config/messenger.xml
@@ -0,0 +1,20 @@
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="doctrine.orm.messenger.middleware_factory.transaction" class="Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddlewareFactory" public="false">
<argument type="service" id="doctrine" />
</service>

<!--
The following service isn't prefixed by the "doctrine.orm" namespace in order for end-users to just use
the "doctrine_transaction_middleware" shortcut in message buses middleware config
-->
<service id="messenger.middleware.doctrine_transaction_middleware" class="Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware" abstract="true" public="false">
<factory service="doctrine.orm.messenger.middleware_factory.transaction" method="createMiddleware" />
<argument /> <!-- default entity manager -->
</service>
</services>
</container>
58 changes: 58 additions & 0 deletions Tests/DependencyInjection/Compiler/MessengerPassTest.php
@@ -0,0 +1,58 @@
<?php

namespace DependencyInjection\Compiler;

use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\MessengerPass;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\Messenger\MessageBus;

class MessengerPassTest extends TestCase
{
public function testRemovesDefinitionsWhenMessengerComponentIsDisabled()
{
$pass = new MessengerPass();
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../../../Resources/config'));
$loader->load('messenger.xml');

$pass->process($container);

$this->assertFalse($container->hasDefinition('doctrine.orm.messenger.middleware_factory.transaction'));
$this->assertFalse($container->hasDefinition('messenger.middleware.doctrine_transaction_middleware'));
}

public function testRemoveDefinitionsWhenHasAliasButNotMessengerComponent()
{
$pass = new MessengerPass();
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../../../Resources/config'));
$loader->load('messenger.xml');

$container->register('some_other_bus', \stdClass::class);
$container->setAlias('message_bus', 'some_other_bus');

$pass->process($container);

$this->assertFalse($container->hasDefinition('doctrine.orm.messenger.middleware_factory.transaction'));
$this->assertFalse($container->hasDefinition('messenger.middleware.doctrine_transaction_middleware'));
}

public function testDoesNotRemoveDefinitionsWhenMessengerComponentIsEnabled()
{
$pass = new MessengerPass();
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../../../Resources/config'));
$loader->load('messenger.xml');

$container->register('messenger.bus.default', MessageBus::class);
$container->setAlias('message_bus', 'messenger.bus.default');

$pass->process($container);

$this->assertTrue($container->hasDefinition('doctrine.orm.messenger.middleware_factory.transaction'));
$this->assertTrue($container->hasDefinition('messenger.middleware.doctrine_transaction_middleware'));
}
}
21 changes: 21 additions & 0 deletions Tests/DependencyInjection/DoctrineExtensionTest.php
Expand Up @@ -676,6 +676,27 @@ public function testAnnotationsBundleMappingDetectionWithVendorNamespace()
$this->assertEquals('Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]);
}

public function testMessengerIntegration()
{
$container = $this->getContainer();
$extension = new DoctrineExtension();

$config = BundleConfigurationBuilder::createBuilder()
->addBaseConnection()
->addEntityManager([
'default_entity_manager' => 'default',
'entity_managers' => [
'default' => [],
],
])
->build();
$extension->load([$config], $container);

$this->assertNotNull($container->getDefinition('doctrine.orm.messenger.middleware_factory.transaction'));
$this->assertNotNull($middlewarePrototype = $container->getDefinition('messenger.middleware.doctrine_transaction_middleware'));
$this->assertSame('default', $middlewarePrototype->getArgument(0));
}

public function testCacheConfiguration()
{
$container = $this->getContainer();
Expand Down
6 changes: 4 additions & 2 deletions composer.json
Expand Up @@ -42,7 +42,8 @@
"twig/twig": "~1.26|~2.0",
"satooshi/php-coveralls": "^1.0",
"phpunit/phpunit": "^4.8.36|^5.7|^6.4",
"symfony/web-profiler-bundle": "~2.7|~3.0|~4.0"
"symfony/web-profiler-bundle": "~2.7|~3.0|~4.0",
"symfony/messenger": "~4.1-beta2"
},
"conflict": {
"symfony/http-foundation": "<2.6"
Expand All @@ -61,5 +62,6 @@
"branch-alias": {
"dev-master": "1.9.x-dev"
}
}
},
"minimum-stability": "dev"
}

0 comments on commit cf4d445

Please sign in to comment.