Skip to content

Commit

Permalink
bug #844 Fix compat with doctrine-bundle >=2.3 (nicolas-grekas)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
weaverryan committed Mar 22, 2021
2 parents a9ff8a8 + 2772485 commit 4021ece
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

/*
* This file is part of the Symfony MakerBundle package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class SetDoctrineAnnotatedPrefixesPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$annotatedPrefixes = null;

foreach ($container->findTaggedServiceIds('doctrine.orm.configuration') as $id => $tags) {
$metadataDriverImpl = null;
foreach ($container->getDefinition($id)->getMethodCalls() as [$method, $arguments]) {
if ('setMetadataDriverImpl' === $method) {
$metadataDriverImpl = $container->getDefinition($arguments[0]);
break;
}
}

if (null === $metadataDriverImpl || !preg_match('/^doctrine\.orm\.(.+)_configuration$/D', $id, $m)) {
continue;
}

$managerName = $m[1];

foreach ($metadataDriverImpl->getMethodCalls() as [$method, $arguments]) {
if ('addDriver' === $method) {
$isAnnotated = 'doctrine.orm.'.$managerName.'_annotation_metadata_driver' === (string) $arguments[0];
$annotatedPrefixes[$managerName][] = [
$arguments[1],
$isAnnotated ? new Reference($arguments[0]) : null,
];
}
}
}

if (null !== $annotatedPrefixes) {
$container->getDefinition('maker.doctrine_helper')->setArgument(2, $annotatedPrefixes);
}
}
}
73 changes: 48 additions & 25 deletions src/Doctrine/DoctrineHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use Doctrine\Common\Persistence\ManagerRegistry as LegacyManagerRegistry;
use Doctrine\Common\Persistence\Mapping\ClassMetadata as LegacyClassMetadata;
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver as LegacyMappingDriver;
use Doctrine\Common\Persistence\Mapping\MappingException as LegacyPersistenceMappingException;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;
Expand All @@ -24,7 +23,6 @@
use Doctrine\Persistence\Mapping\AbstractClassMetadataFactory;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\Driver\AnnotationDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
use Doctrine\Persistence\Mapping\MappingException as PersistenceMappingException;
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
Expand All @@ -48,13 +46,19 @@ final class DoctrineHelper
*/
private $registry;

/**
* @var array|null
*/
private $annotatedPrefixes;

/**
* @var ManagerRegistry|LegacyManagerRegistry
*/
public function __construct(string $entityNamespace, $registry = null)
public function __construct(string $entityNamespace, $registry = null, array $annotatedPrefixes = null)
{
$this->entityNamespace = trim($entityNamespace, '\\');
$this->registry = $registry;
$this->annotatedPrefixes = $annotatedPrefixes;
}

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

/**
* @return MappingDriver|LegacyMappingDriver|null
*
* @throws \Exception
*/
public function getMappingDriverForClass(string $className)
public function isClassAnnotated(string $className): bool
{
/** @var EntityManagerInterface $em */
$em = $this->getRegistry()->getManagerForClass($className);
Expand All @@ -95,19 +94,32 @@ public function getMappingDriverForClass(string $className)
throw new \InvalidArgumentException(sprintf('Cannot find the entity manager for class "%s"', $className));
}

$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
if (null === $this->annotatedPrefixes) {
// doctrine-bundle <= 2.2
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();

if (!$this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
return $metadataDriver instanceof AnnotationDriver;
}

if (!$this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
return $metadataDriver;
foreach ($metadataDriver->getDrivers() as $namespace => $driver) {
if (0 === strpos($className, $namespace)) {
return $driver instanceof AnnotationDriver;
}
}

return $metadataDriver->getDefaultDriver() instanceof AnnotationDriver;
}

foreach ($metadataDriver->getDrivers() as $namespace => $driver) {
if (0 === strpos($className, $namespace)) {
return $driver;
$managerName = array_search($em, $this->getRegistry()->getManagers(), true);

foreach ($this->annotatedPrefixes[$managerName] as [$prefix, $annotationDriver]) {
if (0 === strpos($className, $prefix)) {
return null !== $annotationDriver;
}
}

return $metadataDriver->getDefaultDriver();
return false;
}

public function getEntitiesForAutocomplete(): array
Expand All @@ -134,6 +146,18 @@ public function getEntitiesForAutocomplete(): array
*/
public function getMetadata(string $classOrNamespace = null, bool $disconnected = false)
{
$classNames = (new \ReflectionClass(AnnotationDriver::class))->getProperty('classNames');
$classNames->setAccessible(true);

// Invalidating the cached AnnotationDriver::$classNames to find new Entity classes
foreach ($this->annotatedPrefixes ?? [] as $managerName => $prefixes) {
foreach ($prefixes as [$prefix, $annotationDriver]) {
if (null !== $annotationDriver) {
$classNames->setValue($annotationDriver, null);
}
}
}

$metadata = [];

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

// Invalidating the cached AnnotationDriver::$classNames to find new Entity classes
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
if ($this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
foreach ($metadataDriver->getDrivers() as $driver) {
if ($this->isInstanceOf($driver, AnnotationDriver::class)) {
$classNames = (new \ReflectionObject($driver))->getProperty('classNames');
$classNames->setAccessible(true);
$classNames->setValue($driver, null);
$classNames->setAccessible(false);
if (null === $this->annotatedPrefixes) {
// Invalidating the cached AnnotationDriver::$classNames to find new Entity classes
$metadataDriver = $em->getConfiguration()->getMetadataDriverImpl();
if ($this->isInstanceOf($metadataDriver, MappingDriverChain::class)) {
foreach ($metadataDriver->getDrivers() as $driver) {
if ($this->isInstanceOf($driver, AnnotationDriver::class)) {
$classNames->setValue($driver, null);
}
}
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/Maker/MakeEntity.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Symfony\Bundle\MakerBundle\ConsoleStyle;
use Symfony\Bundle\MakerBundle\DependencyBuilder;
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
Expand Down Expand Up @@ -809,9 +808,7 @@ private function doesEntityUseAnnotationMapping(string $className): bool
$className = reset($otherClassMetadatas)->getName();
}

$driver = $this->doctrineHelper->getMappingDriverForClass($className);

return $driver instanceof AnnotationDriver;
return $this->doctrineHelper->isClassAnnotated($className);
}

private function getEntityNamespace(): string
Expand Down
2 changes: 2 additions & 0 deletions src/MakerBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\MakeCommandRegistrationPass;
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\RemoveMissingParametersPass;
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\SetDoctrineAnnotatedPrefixesPass;
use Symfony\Bundle\MakerBundle\DependencyInjection\CompilerPass\SetDoctrineManagerRegistryClassPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
Expand All @@ -30,5 +31,6 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new MakeCommandRegistrationPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 10);
$container->addCompilerPass(new RemoveMissingParametersPass());
$container->addCompilerPass(new SetDoctrineManagerRegistryClassPass());
$container->addCompilerPass(new SetDoctrineAnnotatedPrefixesPass());
}
}

0 comments on commit 4021ece

Please sign in to comment.