Skip to content

Commit 4021ece

Browse files
committed
bug #844 Fix compat with doctrine-bundle >=2.3 (nicolas-grekas)
This PR was merged into the 1.0-dev branch. Discussion ---------- Fix compat with doctrine-bundle >=2.3 Fix #841 Commits ------- 2772485 Fix compat with doctrine-bundle >=2.3
2 parents a9ff8a8 + 2772485 commit 4021ece

File tree

4 files changed

+105
-29
lines changed

4 files changed

+105
-29
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony MakerBundle package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass;
13+
14+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Reference;
17+
18+
class SetDoctrineAnnotatedPrefixesPass implements CompilerPassInterface
19+
{
20+
public function process(ContainerBuilder $container)
21+
{
22+
$annotatedPrefixes = null;
23+
24+
foreach ($container->findTaggedServiceIds('doctrine.orm.configuration') as $id => $tags) {
25+
$metadataDriverImpl = null;
26+
foreach ($container->getDefinition($id)->getMethodCalls() as [$method, $arguments]) {
27+
if ('setMetadataDriverImpl' === $method) {
28+
$metadataDriverImpl = $container->getDefinition($arguments[0]);
29+
break;
30+
}
31+
}
32+
33+
if (null === $metadataDriverImpl || !preg_match('/^doctrine\.orm\.(.+)_configuration$/D', $id, $m)) {
34+
continue;
35+
}
36+
37+
$managerName = $m[1];
38+
39+
foreach ($metadataDriverImpl->getMethodCalls() as [$method, $arguments]) {
40+
if ('addDriver' === $method) {
41+
$isAnnotated = 'doctrine.orm.'.$managerName.'_annotation_metadata_driver' === (string) $arguments[0];
42+
$annotatedPrefixes[$managerName][] = [
43+
$arguments[1],
44+
$isAnnotated ? new Reference($arguments[0]) : null,
45+
];
46+
}
47+
}
48+
}
49+
50+
if (null !== $annotatedPrefixes) {
51+
$container->getDefinition('maker.doctrine_helper')->setArgument(2, $annotatedPrefixes);
52+
}
53+
}
54+
}

src/Doctrine/DoctrineHelper.php

+48-25
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use Doctrine\Common\Persistence\ManagerRegistry as LegacyManagerRegistry;
1515
use Doctrine\Common\Persistence\Mapping\ClassMetadata as LegacyClassMetadata;
16-
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver as LegacyMappingDriver;
1716
use Doctrine\Common\Persistence\Mapping\MappingException as LegacyPersistenceMappingException;
1817
use Doctrine\DBAL\Connection;
1918
use Doctrine\ORM\EntityManagerInterface;
@@ -24,7 +23,6 @@
2423
use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;
2524
use Doctrine\Persistence\Mapping\ClassMetadata;
2625
use Doctrine\Persistence\Mapping\Driver\AnnotationDriver;
27-
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
2826
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
2927
use Doctrine\Persistence\Mapping\MappingException as PersistenceMappingException;
3028
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
@@ -48,13 +46,19 @@ final class DoctrineHelper
4846
*/
4947
private $registry;
5048

49+
/**
50+
* @var array|null
51+
*/
52+
private $annotatedPrefixes;
53+
5154
/**
5255
* @var ManagerRegistry|LegacyManagerRegistry
5356
*/
54-
public function __construct(string $entityNamespace, $registry = null)
57+
public function __construct(string $entityNamespace, $registry = null, array $annotatedPrefixes = null)
5558
{
5659
$this->entityNamespace = trim($entityNamespace, '\\');
5760
$this->registry = $registry;
61+
$this->annotatedPrefixes = $annotatedPrefixes;
5862
}
5963

6064
/**
@@ -81,12 +85,7 @@ public function getEntityNamespace(): string
8185
return $this->entityNamespace;
8286
}
8387

84-
/**
85-
* @return MappingDriver|LegacyMappingDriver|null
86-
*
87-
* @throws \Exception
88-
*/
89-
public function getMappingDriverForClass(string $className)
88+
public function isClassAnnotated(string $className): bool
9089
{
9190
/** @var EntityManagerInterface $em */
9291
$em = $this->getRegistry()->getManagerForClass($className);
@@ -95,19 +94,32 @@ public function getMappingDriverForClass(string $className)
9594
throw new \InvalidArgumentException(sprintf('Cannot find the entity manager for class "%s"', $className));
9695
}
9796

98-
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
97+
if (null === $this->annotatedPrefixes) {
98+
// doctrine-bundle <= 2.2
99+
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
100+
101+
if (!$this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
102+
return $metadataDriver instanceof AnnotationDriver;
103+
}
99104

100-
if (!$this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
101-
return $metadataDriver;
105+
foreach ($metadataDriver->getDrivers() as $namespace => $driver) {
106+
if (0 === strpos($className, $namespace)) {
107+
return $driver instanceof AnnotationDriver;
108+
}
109+
}
110+
111+
return $metadataDriver->getDefaultDriver() instanceof AnnotationDriver;
102112
}
103113

104-
foreach ($metadataDriver->getDrivers() as $namespace => $driver) {
105-
if (0 === strpos($className, $namespace)) {
106-
return $driver;
114+
$managerName = array_search($em, $this->getRegistry()->getManagers(), true);
115+
116+
foreach ($this->annotatedPrefixes[$managerName] as [$prefix, $annotationDriver]) {
117+
if (0 === strpos($className, $prefix)) {
118+
return null !== $annotationDriver;
107119
}
108120
}
109121

110-
return $metadataDriver->getDefaultDriver();
122+
return false;
111123
}
112124

113125
public function getEntitiesForAutocomplete(): array
@@ -134,6 +146,18 @@ public function getEntitiesForAutocomplete(): array
134146
*/
135147
public function getMetadata(string $classOrNamespace = null, bool $disconnected = false)
136148
{
149+
$classNames = (new \ReflectionClass(AnnotationDriver::class))->getProperty('classNames');
150+
$classNames->setAccessible(true);
151+
152+
// Invalidating the cached AnnotationDriver::$classNames to find new Entity classes
153+
foreach ($this->annotatedPrefixes ?? [] as $managerName => $prefixes) {
154+
foreach ($prefixes as [$prefix, $annotationDriver]) {
155+
if (null !== $annotationDriver) {
156+
$classNames->setValue($annotationDriver, null);
157+
}
158+
}
159+
}
160+
137161
$metadata = [];
138162

139163
/** @var EntityManagerInterface $em */
@@ -158,15 +182,14 @@ public function getMetadata(string $classOrNamespace = null, bool $disconnected
158182
$cmf->setMetadataFor($m->getName(), $m);
159183
}
160184

161-
// Invalidating the cached AnnotationDriver::$classNames to find new Entity classes
162-
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
163-
if ($this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
164-
foreach ($metadataDriver->getDrivers() as $driver) {
165-
if ($this->isInstanceOf($driver, AnnotationDriver::class)) {
166-
$classNames = (new \ReflectionObject($driver))->getProperty('classNames');
167-
$classNames->setAccessible(true);
168-
$classNames->setValue($driver, null);
169-
$classNames->setAccessible(false);
185+
if (null === $this->annotatedPrefixes) {
186+
// Invalidating the cached AnnotationDriver::$classNames to find new Entity classes
187+
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
188+
if ($this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
189+
foreach ($metadataDriver->getDrivers() as $driver) {
190+
if ($this->isInstanceOf($driver, AnnotationDriver::class)) {
191+
$classNames->setValue($driver, null);
192+
}
170193
}
171194
}
172195
}

src/Maker/MakeEntity.php

+1-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
use ApiPlatform\Core\Annotation\ApiResource;
1515
use Doctrine\DBAL\Types\Type;
16-
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
1716
use Symfony\Bundle\MakerBundle\ConsoleStyle;
1817
use Symfony\Bundle\MakerBundle\DependencyBuilder;
1918
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
@@ -809,9 +808,7 @@ private function doesEntityUseAnnotationMapping(string $className): bool
809808
$className = reset($otherClassMetadatas)->getName();
810809
}
811810

812-
$driver = $this->doctrineHelper->getMappingDriverForClass($className);
813-
814-
return $driver instanceof AnnotationDriver;
811+
return $this->doctrineHelper->isClassAnnotated($className);
815812
}
816813

817814
private function getEntityNamespace(): string

src/MakerBundle.php

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\MakeCommandRegistrationPass;
1515
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\RemoveMissingParametersPass;
16+
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\SetDoctrineAnnotatedPrefixesPass;
1617
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\SetDoctrineManagerRegistryClassPass;
1718
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
1819
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -30,5 +31,6 @@ public function build(ContainerBuilder $container)
3031
$container->addCompilerPass(new MakeCommandRegistrationPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 10);
3132
$container->addCompilerPass(new RemoveMissingParametersPass());
3233
$container->addCompilerPass(new SetDoctrineManagerRegistryClassPass());
34+
$container->addCompilerPass(new SetDoctrineAnnotatedPrefixesPass());
3335
}
3436
}

0 commit comments

Comments
 (0)