Skip to content

Commit

Permalink
Add support for Messenger & Cache schema subscribers in Symfony 5.1
Browse files Browse the repository at this point in the history
  • Loading branch information
weaverryan committed May 7, 2020
1 parent 98e038d commit e96d4e6
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 0 deletions.
44 changes: 44 additions & 0 deletions DependencyInjection/Compiler/CacheSchemaSubscriberPass.php
@@ -0,0 +1,44 @@
<?php

namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;

use Symfony\Bridge\Doctrine\SchemaListener\MessengerTransportDoctrineSchemaSubscriber;
use Symfony\Bridge\Doctrine\SchemaListener\PdoCacheAdapterDoctrineSchemaSubscriber;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

/**
* Injects PdoAdapter into its schema subscriber.
*
* Must be run later after ResolveChildDefinitionsPass.
*/
class CacheSchemaSubscriberPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*/
public function process(ContainerBuilder $container)
{
$subscriberId = 'doctrine.orm.listeners.pdo_cache_adapter_doctrine_schema_subscriber';

if (!$container->hasDefinition($subscriberId)) {
return;
}

$cacheAdaptersReferences = [];
foreach ($container->getDefinitions() as $id => $definition) {
if ($definition->isAbstract() || $definition->isSynthetic()) {
continue;
}

if ($definition->getClass() === PdoAdapter::class) {
$cacheAdaptersReferences[] = new Reference($id);
}
}

$container->getDefinition($subscriberId)
->replaceArgument(0, $cacheAdaptersReferences);
}
}
12 changes: 12 additions & 0 deletions DependencyInjection/DoctrineExtension.php
Expand Up @@ -3,6 +3,7 @@
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection;

use Doctrine\Bundle\DoctrineBundle\Dbal\RegexSchemaAssetFilter;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheSchemaSubscriberPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\Bundle\DoctrineBundle\EventSubscriber\EventSubscriberInterface;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepositoryInterface;
Expand All @@ -12,6 +13,7 @@
use Symfony\Bridge\Doctrine\Messenger\DoctrineClearEntityManagerWorkerSubscriber;
use Symfony\Bridge\Doctrine\Messenger\DoctrineTransactionMiddleware;
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
use Symfony\Bridge\Doctrine\SchemaListener\MessengerTransportDoctrineSchemaSubscriber;
use Symfony\Bridge\Doctrine\Validator\DoctrineLoader;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\DoctrineProvider;
Expand Down Expand Up @@ -339,6 +341,11 @@ protected function ormLoad(array $config, ContainerBuilder $container)
$container->getDefinition('form.type.entity')->addTag('kernel.reset', ['method' => 'reset']);
}

// available in Symfony 5.1 and higher
if (! class_exists(CacheSchemaSubscriberPass::class)) {
$container->removeDefinition('doctrine.orm.listeners.pdo_cache_adapter_doctrine_schema_subscriber');
}

$entityManagers = [];
foreach (array_keys($config['entity_managers']) as $name) {
$entityManagers[$name] = sprintf('doctrine.orm.%s_entity_manager', $name);
Expand Down Expand Up @@ -842,6 +849,11 @@ private function loadMessengerServices(ContainerBuilder $container) : void
$container->removeDefinition('doctrine.orm.messenger.event_subscriber.doctrine_clear_entity_manager');
}

// available in Symfony 5.1 and higher
if (! class_exists(MessengerTransportDoctrineSchemaSubscriber::class)) {
$container->removeDefinition('doctrine.orm.messenger.doctrine_schema_subscriber');
}

$transportFactoryDefinition = $container->getDefinition('messenger.transport.doctrine.factory');
if (! class_exists(DoctrineTransportFactory::class)) {
// If symfony/messenger < 5.1
Expand Down
3 changes: 3 additions & 0 deletions DoctrineBundle.php
Expand Up @@ -2,8 +2,10 @@

namespace Doctrine\Bundle\DoctrineBundle;

use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheSchemaSubscriberPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DbalSchemaFilterPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\EntityListenerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\SchemaSubscriberPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\WellKnownSchemaFilterPass;
use Doctrine\Common\Util\ClassUtils;
Expand Down Expand Up @@ -40,6 +42,7 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new ServiceRepositoryCompilerPass());
$container->addCompilerPass(new WellKnownSchemaFilterPass());
$container->addCompilerPass(new DbalSchemaFilterPass());
$container->addCompilerPass(new CacheSchemaSubscriberPass(), PassConfig::TYPE_OPTIMIZE, -10);
}

/**
Expand Down
5 changes: 5 additions & 0 deletions Resources/config/messenger.xml
Expand Up @@ -40,5 +40,10 @@
<tag name="kernel.event_subscriber" />
<argument type="service" id="doctrine" />
</service>

<service id="doctrine.orm.messenger.doctrine_schema_subscriber" class="Symfony\Bridge\Doctrine\SchemaListener\MessengerTransportDoctrineSchemaSubscriber">
<argument type="tagged" tag="messenger.receiver" />
<tag name="doctrine.event_subscriber" />
</service>
</services>
</container>
4 changes: 4 additions & 0 deletions Resources/config/orm.xml
Expand Up @@ -133,6 +133,10 @@

<!-- listeners -->
<service id="doctrine.orm.listeners.resolve_target_entity" class="%doctrine.orm.listeners.resolve_target_entity.class%" public="false" />
<service id="doctrine.orm.listeners.pdo_cache_adapter_doctrine_schema_subscriber" class="Symfony\Bridge\Doctrine\SchemaListener\PdoCacheAdapterDoctrineSchemaSubscriber">
<argument type="collection" /> <!-- PdoAdapter instances -->
<tag name="doctrine.event_subscriber" />
</service>

<!-- naming strategy -->
<service id="doctrine.orm.naming_strategy.default" class="%doctrine.orm.naming_strategy.default.class%" public="false" />
Expand Down
69 changes: 69 additions & 0 deletions Tests/CacheSchemaSubscriberTest.php
@@ -0,0 +1,69 @@
<?php

namespace Doctrine\Bundle\DoctrineBundle\Tests;

use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\CacheSchemaSubscriberPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\ServiceRepositoryCompilerPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\DoctrineExtension;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Fixtures\Bundles\RepositoryServiceBundle\Entity\TestCustomClassRepoEntity;
use Fixtures\Bundles\RepositoryServiceBundle\Entity\TestCustomServiceRepoEntity;
use Fixtures\Bundles\RepositoryServiceBundle\Entity\TestDefaultRepoEntity;
use Fixtures\Bundles\RepositoryServiceBundle\Repository\TestCustomClassRepoRepository;
use Fixtures\Bundles\RepositoryServiceBundle\Repository\TestCustomServiceRepoRepository;
use Fixtures\Bundles\RepositoryServiceBundle\RepositoryServiceBundle;
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;

class CacheSchemaSubscriberTest extends TestCase
{
public function testSchemaSubscriberWiring() : void
{
$container = new ContainerBuilder(new ParameterBag([
'kernel.name' => 'app',
'kernel.debug' => false,
'kernel.bundles' => [],
'kernel.cache_dir' => sys_get_temp_dir(),
'kernel.environment' => 'test',
'kernel.root_dir' => __DIR__ . '/../../../../', // src dir
'kernel.project_dir' => __DIR__ . '/../../../../', // src dir
'kernel.bundles_metadata' => [],
'kernel.charset' => 'UTF-8',
'kernel.container_class' => ContainerBuilder::class,
'kernel.secret' => 'test',
'env(base64:default::SYMFONY_DECRYPTION_SECRET)' => 'foo',
]));

$extension = new FrameworkExtension();
$container->registerExtension($extension);
$extension->load(['framework' => ['cache' => [
'app' => 'cache.adapter.pdo'
]]], $container);

$extension = new DoctrineExtension();
$container->registerExtension($extension);
$extension->load([
[
'dbal' => [],
'orm' => [],
],
], $container);

$container->setAlias('test_alias', new Alias('doctrine.orm.listeners.pdo_cache_adapter_doctrine_schema_subscriber', true));
$container->addCompilerPass(new CacheSchemaSubscriberPass(), PassConfig::TYPE_OPTIMIZE, -10);
$container->compile();

// sanity check
$this->assertSame(PdoAdapter::class, $container->getDefinition('cache.app')->getClass());
// check that PdoAdapter service is injected as an argument
$definition = $container->findDefinition('test_alias');
$this->assertEquals([new Reference('cache.app')], $definition->getArgument(0));
}
}
8 changes: 8 additions & 0 deletions UPGRADE-2.1.md
@@ -1,6 +1,14 @@
UPGRADE FROM 2.0 to 2.1
=======================

Messenger
---------

With Symfony 5.1 or higher, the `messenger_messages` table is
no longer automatically ignored via the `schema_filter`. Instead,
a new `MessengerTransportDoctrineSchemaSubscriber` service is registered
which automatically adds the `messenger_messages` schema.

Commands
--------

Expand Down

0 comments on commit e96d4e6

Please sign in to comment.