welcome back to dyb-tech
This commit is contained in:
+125
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Doctrine\Common\Cache\Psr6\CacheAdapter;
|
||||
use Psr\Cache\CacheItemPoolInterface;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
use function array_keys;
|
||||
use function assert;
|
||||
use function in_array;
|
||||
use function is_a;
|
||||
use function trigger_deprecation;
|
||||
|
||||
/** @internal */
|
||||
final class CacheCompatibilityPass implements CompilerPassInterface
|
||||
{
|
||||
private const CONFIGURATION_TAG = 'doctrine.orm.configuration';
|
||||
private const CACHE_METHODS_PSR6_SUPPORT = [
|
||||
'setMetadataCache',
|
||||
'setQueryCache',
|
||||
'setResultCache',
|
||||
];
|
||||
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
foreach (array_keys($container->findTaggedServiceIds(self::CONFIGURATION_TAG)) as $id) {
|
||||
foreach ($container->getDefinition($id)->getMethodCalls() as $methodCall) {
|
||||
if ($methodCall[0] === 'setSecondLevelCacheConfiguration') {
|
||||
$this->updateSecondLevelCache($container, $methodCall[1][0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! in_array($methodCall[0], self::CACHE_METHODS_PSR6_SUPPORT, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$aliasId = (string) $methodCall[1][0];
|
||||
$definitionId = (string) $container->getAlias($aliasId);
|
||||
|
||||
$this->wrapIfNecessary($container, $aliasId, $definitionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function updateSecondLevelCache(ContainerBuilder $container, Definition $slcConfigDefinition): void
|
||||
{
|
||||
foreach ($slcConfigDefinition->getMethodCalls() as $methodCall) {
|
||||
if ($methodCall[0] !== 'setCacheFactory') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$factoryDefinition = $methodCall[1][0];
|
||||
assert($factoryDefinition instanceof Definition);
|
||||
$aliasId = (string) $factoryDefinition->getArgument(1);
|
||||
$this->wrapIfNecessary($container, $aliasId, (string) $container->getAlias($aliasId));
|
||||
foreach ($factoryDefinition->getMethodCalls() as $factoryMethodCall) {
|
||||
if ($factoryMethodCall[0] !== 'setRegion') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$regionDefinition = $container->getDefinition($factoryMethodCall[1][0]);
|
||||
|
||||
// Get inner service for FileLock
|
||||
if ($regionDefinition->getClass() === '%doctrine.orm.second_level_cache.filelock_region.class%') {
|
||||
$regionDefinition = $container->getDefinition($regionDefinition->getArgument(0));
|
||||
}
|
||||
|
||||
// We don't know how to adjust custom region classes
|
||||
if ($regionDefinition->getClass() !== '%doctrine.orm.second_level_cache.default_region.class%') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$driverId = (string) $regionDefinition->getArgument(1);
|
||||
if (! $container->hasAlias($driverId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->wrapIfNecessary($container, $driverId, (string) $container->getAlias($driverId));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function createCompatibilityLayerDefinition(ContainerBuilder $container, string $definitionId): ?Definition
|
||||
{
|
||||
$definition = $container->getDefinition($definitionId);
|
||||
|
||||
while (! $definition->getClass() && $definition instanceof ChildDefinition) {
|
||||
$definition = $container->findDefinition($definition->getParent());
|
||||
}
|
||||
|
||||
if (is_a($definition->getClass(), CacheItemPoolInterface::class, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
trigger_deprecation(
|
||||
'doctrine/doctrine-bundle',
|
||||
'2.4',
|
||||
'Configuring doctrine/cache is deprecated. Please update the cache service "%s" to use a PSR-6 cache.',
|
||||
$definitionId,
|
||||
);
|
||||
|
||||
return (new Definition(CacheItemPoolInterface::class))
|
||||
->setFactory([CacheAdapter::class, 'wrap'])
|
||||
->addArgument(new Reference($definitionId));
|
||||
}
|
||||
|
||||
private function wrapIfNecessary(ContainerBuilder $container, string $aliasId, string $definitionId): void
|
||||
{
|
||||
$compatibilityLayer = $this->createCompatibilityLayerDefinition($container, $definitionId);
|
||||
if ($compatibilityLayer === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$compatibilityLayerId = $definitionId . '.compatibility_layer';
|
||||
$container->setAlias($aliasId, $compatibilityLayerId);
|
||||
$container->setDefinition($compatibilityLayerId, $compatibilityLayer);
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\Cache\Adapter\DoctrineDbalAdapter;
|
||||
use Symfony\Component\Cache\Adapter\PdoAdapter;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Injects Doctrine DBAL and legacy PDO adapters into their schema subscribers.
|
||||
*
|
||||
* Must be run later after ResolveChildDefinitionsPass.
|
||||
*
|
||||
* @final since 2.9
|
||||
*/
|
||||
class CacheSchemaSubscriberPass implements CompilerPassInterface
|
||||
{
|
||||
/** @return void */
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
// deprecated in Symfony 6.3
|
||||
$this->injectAdapters($container, 'doctrine.orm.listeners.doctrine_dbal_cache_adapter_schema_subscriber', DoctrineDbalAdapter::class);
|
||||
|
||||
$this->injectAdapters($container, 'doctrine.orm.listeners.doctrine_dbal_cache_adapter_schema_listener', DoctrineDbalAdapter::class);
|
||||
|
||||
// available in Symfony 5.1 and up to Symfony 5.4 (deprecated)
|
||||
$this->injectAdapters($container, 'doctrine.orm.listeners.pdo_cache_adapter_doctrine_schema_subscriber', PdoAdapter::class);
|
||||
}
|
||||
|
||||
private function injectAdapters(ContainerBuilder $container, string $subscriberId, string $class)
|
||||
{
|
||||
if (! $container->hasDefinition($subscriberId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$subscriber = $container->getDefinition($subscriberId);
|
||||
|
||||
$cacheAdaptersReferences = [];
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isAbstract() || $definition->isSynthetic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($definition->getClass() !== $class) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$cacheAdaptersReferences[] = new Reference($id);
|
||||
}
|
||||
|
||||
$subscriber->replaceArgument(0, $cacheAdaptersReferences);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
/**
|
||||
* Processes the doctrine.dbal.schema_filter
|
||||
*
|
||||
* @final since 2.9
|
||||
*/
|
||||
class DbalSchemaFilterPass implements CompilerPassInterface
|
||||
{
|
||||
/** @return void */
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$filters = $container->findTaggedServiceIds('doctrine.dbal.schema_filter');
|
||||
|
||||
$connectionFilters = [];
|
||||
foreach ($filters as $id => $tagAttributes) {
|
||||
foreach ($tagAttributes as $attributes) {
|
||||
$name = $attributes['connection'] ?? $container->getParameter('doctrine.default_connection');
|
||||
|
||||
if (! isset($connectionFilters[$name])) {
|
||||
$connectionFilters[$name] = [];
|
||||
}
|
||||
|
||||
$connectionFilters[$name][] = new Reference($id);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($connectionFilters as $name => $references) {
|
||||
$configurationId = sprintf('doctrine.dbal.%s_connection.configuration', $name);
|
||||
|
||||
if (! $container->hasDefinition($configurationId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$definition = new ChildDefinition('doctrine.dbal.schema_asset_filter_manager');
|
||||
$definition->setArgument(0, $references);
|
||||
|
||||
$id = sprintf('doctrine.dbal.%s_schema_asset_filter_manager', $name);
|
||||
$container->setDefinition($id, $definition);
|
||||
$container->findDefinition($configurationId)
|
||||
->addMethodCall('setSchemaAssetsFilter', [new Reference($id)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
|
||||
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
|
||||
use Doctrine\ORM\Mapping\Driver\XmlDriver;
|
||||
use Doctrine\ORM\Mapping\Driver\YamlDriver;
|
||||
use Doctrine\Persistence\Mapping\Driver\PHPDriver;
|
||||
use Doctrine\Persistence\Mapping\Driver\StaticPHPDriver;
|
||||
use Doctrine\Persistence\Mapping\Driver\SymfonyFileLocator;
|
||||
use Symfony\Bridge\Doctrine\DependencyInjection\CompilerPass\RegisterMappingsPass;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Class for Symfony bundles to configure mappings for model classes not in the
|
||||
* auto-mapped folder.
|
||||
*
|
||||
* @final since 2.9
|
||||
*/
|
||||
class DoctrineOrmMappingsPass extends RegisterMappingsPass
|
||||
{
|
||||
/**
|
||||
* You should not directly instantiate this class but use one of the
|
||||
* factory methods.
|
||||
*
|
||||
* @param Definition|Reference $driver Driver DI definition or reference.
|
||||
* @param string[] $namespaces List of namespaces handled by $driver.
|
||||
* @param string[] $managerParameters Ordered list of container parameters that
|
||||
* could hold the manager name.
|
||||
* doctrine.default_entity_manager is appended
|
||||
* automatically.
|
||||
* @param string|false $enabledParameter If specified, the compiler pass only executes
|
||||
* if this parameter is defined in the service
|
||||
* container.
|
||||
* @param string[] $aliasMap Map of alias to namespace.
|
||||
*/
|
||||
public function __construct($driver, array $namespaces, array $managerParameters, $enabledParameter = false, array $aliasMap = [])
|
||||
{
|
||||
$managerParameters[] = 'doctrine.default_entity_manager';
|
||||
|
||||
parent::__construct(
|
||||
$driver,
|
||||
$namespaces,
|
||||
$managerParameters,
|
||||
'doctrine.orm.%s_metadata_driver',
|
||||
$enabledParameter,
|
||||
'doctrine.orm.%s_configuration',
|
||||
'addEntityNamespace',
|
||||
$aliasMap,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $namespaces Hashmap of directory path to namespace.
|
||||
* @param string[] $managerParameters List of parameters that could which object manager name
|
||||
* your bundle uses. This compiler pass will automatically
|
||||
* append the parameter name for the default entity manager
|
||||
* to this list.
|
||||
* @param string|false $enabledParameter Service container parameter that must be present to
|
||||
* enable the mapping. Set to false to not do any check,
|
||||
* optional.
|
||||
* @param string[] $aliasMap Map of alias to namespace.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function createXmlMappingDriver(array $namespaces, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [], bool $enableXsdValidation = false)
|
||||
{
|
||||
$locator = new Definition(SymfonyFileLocator::class, [$namespaces, '.orm.xml']);
|
||||
$driver = new Definition(XmlDriver::class, [$locator, null, $enableXsdValidation]);
|
||||
|
||||
return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $namespaces Hashmap of directory path to namespace
|
||||
* @param string[] $managerParameters List of parameters that could which object manager name
|
||||
* your bundle uses. This compiler pass will automatically
|
||||
* append the parameter name for the default entity manager
|
||||
* to this list.
|
||||
* @param string|false $enabledParameter Service container parameter that must be present to
|
||||
* enable the mapping. Set to false to not do any check,
|
||||
* optional.
|
||||
* @param string[] $aliasMap Map of alias to namespace.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function createYamlMappingDriver(array $namespaces, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [])
|
||||
{
|
||||
$locator = new Definition(SymfonyFileLocator::class, [$namespaces, '.orm.yml']);
|
||||
$driver = new Definition(YamlDriver::class, [$locator]);
|
||||
|
||||
return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $namespaces Hashmap of directory path to namespace
|
||||
* @param string[] $managerParameters List of parameters that could which object manager name
|
||||
* your bundle uses. This compiler pass will automatically
|
||||
* append the parameter name for the default entity manager
|
||||
* to this list.
|
||||
* @param string|false $enabledParameter Service container parameter that must be present to
|
||||
* enable the mapping. Set to false to not do any check,
|
||||
* optional.
|
||||
* @param string[] $aliasMap Map of alias to namespace.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function createPhpMappingDriver(array $namespaces, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [])
|
||||
{
|
||||
$locator = new Definition(SymfonyFileLocator::class, [$namespaces, '.php']);
|
||||
$driver = new Definition(PHPDriver::class, [$locator]);
|
||||
|
||||
return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $namespaces List of namespaces that are handled with annotation mapping
|
||||
* @param string[] $directories List of directories to look for annotated classes
|
||||
* @param string[] $managerParameters List of parameters that could which object manager name
|
||||
* your bundle uses. This compiler pass will automatically
|
||||
* append the parameter name for the default entity manager
|
||||
* to this list.
|
||||
* @param string|false $enabledParameter Service container parameter that must be present to
|
||||
* enable the mapping. Set to false to not do any check,
|
||||
* optional.
|
||||
* @param string[] $aliasMap Map of alias to namespace.
|
||||
* @param bool $reportFieldsWhereDeclared Will report fields for the classes where they are declared
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function createAnnotationMappingDriver(array $namespaces, array $directories, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [], bool $reportFieldsWhereDeclared = false)
|
||||
{
|
||||
$reader = new Reference('annotation_reader');
|
||||
$driver = new Definition(AnnotationDriver::class, [$reader, $directories, $reportFieldsWhereDeclared]);
|
||||
|
||||
return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $namespaces List of namespaces that are handled with attribute mapping
|
||||
* @param string[] $directories List of directories to look for classes with attributes
|
||||
* @param string[] $managerParameters List of parameters that could which object manager name
|
||||
* your bundle uses. This compiler pass will automatically
|
||||
* append the parameter name for the default entity manager
|
||||
* to this list.
|
||||
* @param string|false $enabledParameter Service container parameter that must be present to
|
||||
* enable the mapping. Set to false to not do any check,
|
||||
* optional.
|
||||
* @param string[] $aliasMap Map of alias to namespace.
|
||||
* @param bool $reportFieldsWhereDeclared Will report fields for the classes where they are declared
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function createAttributeMappingDriver(array $namespaces, array $directories, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [], bool $reportFieldsWhereDeclared = false)
|
||||
{
|
||||
$driver = new Definition(AttributeDriver::class, [$directories, $reportFieldsWhereDeclared]);
|
||||
|
||||
return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $namespaces List of namespaces that are handled with static php mapping
|
||||
* @param string[] $directories List of directories to look for static php mapping files
|
||||
* @param string[] $managerParameters List of parameters that could which object manager name
|
||||
* your bundle uses. This compiler pass will automatically
|
||||
* append the parameter name for the default entity manager
|
||||
* to this list.
|
||||
* @param string|false $enabledParameter Service container parameter that must be present to
|
||||
* enable the mapping. Set to false to not do any check,
|
||||
* optional.
|
||||
* @param string[] $aliasMap Map of alias to namespace.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function createStaticPhpMappingDriver(array $namespaces, array $directories, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [])
|
||||
{
|
||||
$driver = new Definition(StaticPHPDriver::class, [$directories]);
|
||||
|
||||
return new DoctrineOrmMappingsPass($driver, $namespaces, $managerParameters, $enabledParameter, $aliasMap);
|
||||
}
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Doctrine\Bundle\DoctrineBundle\Mapping\ContainerEntityListenerResolver;
|
||||
use Doctrine\Bundle\DoctrineBundle\Mapping\EntityListenerServiceResolver;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
use function is_a;
|
||||
use function method_exists;
|
||||
use function sprintf;
|
||||
use function substr;
|
||||
|
||||
/**
|
||||
* Class for Symfony bundles to register entity listeners
|
||||
*
|
||||
* @final since 2.9
|
||||
*/
|
||||
class EntityListenerPass implements CompilerPassInterface
|
||||
{
|
||||
use PriorityTaggedServiceTrait;
|
||||
|
||||
/** @return void */
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$resolvers = $this->findAndSortTaggedServices('doctrine.orm.entity_listener', $container);
|
||||
|
||||
$lazyServiceReferencesByResolver = [];
|
||||
|
||||
foreach ($resolvers as $reference) {
|
||||
$id = $reference->__toString();
|
||||
foreach ($container->getDefinition($id)->getTag('doctrine.orm.entity_listener') as $attributes) {
|
||||
$name = $attributes['entity_manager'] ?? $container->getParameter('doctrine.default_entity_manager');
|
||||
$entityManager = sprintf('doctrine.orm.%s_entity_manager', $name);
|
||||
|
||||
if (! $container->hasDefinition($entityManager)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resolverId = sprintf('doctrine.orm.%s_entity_listener_resolver', $name);
|
||||
|
||||
if (! $container->has($resolverId)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$resolver = $container->findDefinition($resolverId);
|
||||
$resolver->setPublic(true);
|
||||
|
||||
if (isset($attributes['entity'])) {
|
||||
$this->attachToListener($container, $name, $this->getConcreteDefinitionClass($container->findDefinition($id), $container, $id), $attributes);
|
||||
}
|
||||
|
||||
$resolverClass = $this->getResolverClass($resolver, $container, $resolverId);
|
||||
$resolverSupportsLazyListeners = is_a($resolverClass, EntityListenerServiceResolver::class, true);
|
||||
|
||||
$lazyByAttribute = isset($attributes['lazy']) && $attributes['lazy'];
|
||||
if ($lazyByAttribute && ! $resolverSupportsLazyListeners) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Lazy-loaded entity listeners can only be resolved by a resolver implementing %s.',
|
||||
EntityListenerServiceResolver::class,
|
||||
));
|
||||
}
|
||||
|
||||
if (! isset($attributes['lazy']) && $resolverSupportsLazyListeners || $lazyByAttribute) {
|
||||
$listener = $container->findDefinition($id);
|
||||
|
||||
$resolver->addMethodCall('registerService', [$this->getConcreteDefinitionClass($listener, $container, $id), $id]);
|
||||
|
||||
// if the resolver uses the default class we will use a service locator for all listeners
|
||||
if ($resolverClass === ContainerEntityListenerResolver::class) {
|
||||
if (! isset($lazyServiceReferencesByResolver[$resolverId])) {
|
||||
$lazyServiceReferencesByResolver[$resolverId] = [];
|
||||
}
|
||||
|
||||
$lazyServiceReferencesByResolver[$resolverId][$id] = new Reference($id);
|
||||
} else {
|
||||
$listener->setPublic(true);
|
||||
}
|
||||
} else {
|
||||
$resolver->addMethodCall('register', [new Reference($id)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($lazyServiceReferencesByResolver as $resolverId => $listenerReferences) {
|
||||
$container->findDefinition($resolverId)->setArgument(0, ServiceLocatorTagPass::register($container, $listenerReferences));
|
||||
}
|
||||
}
|
||||
|
||||
/** @param array{entity: class-string, event?: ?string, method?: string} $attributes */
|
||||
private function attachToListener(ContainerBuilder $container, string $name, string $class, array $attributes): void
|
||||
{
|
||||
$listenerId = sprintf('doctrine.orm.%s_listeners.attach_entity_listeners', $name);
|
||||
|
||||
if (! $container->has($listenerId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$args = [
|
||||
$attributes['entity'],
|
||||
$class,
|
||||
$attributes['event'] ?? null,
|
||||
];
|
||||
|
||||
if (isset($attributes['method'])) {
|
||||
$args[] = $attributes['method'];
|
||||
} elseif (isset($attributes['event']) && ! method_exists($class, $attributes['event']) && method_exists($class, '__invoke')) {
|
||||
$args[] = '__invoke';
|
||||
}
|
||||
|
||||
$container->findDefinition($listenerId)->addMethodCall('addEntityListener', $args);
|
||||
}
|
||||
|
||||
private function getResolverClass(Definition $resolver, ContainerBuilder $container, string $id): string
|
||||
{
|
||||
$resolverClass = $this->getConcreteDefinitionClass($resolver, $container, $id);
|
||||
|
||||
if (substr($resolverClass, 0, 1) === '%') {
|
||||
// resolve container parameter first
|
||||
$resolverClass = $container->getParameterBag()->resolveValue($resolverClass);
|
||||
}
|
||||
|
||||
return $resolverClass;
|
||||
}
|
||||
|
||||
private function getConcreteDefinitionClass(Definition $definition, ContainerBuilder $container, string $id): string
|
||||
{
|
||||
$class = $definition->getClass();
|
||||
if ($class) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
while ($definition instanceof ChildDefinition) {
|
||||
$definition = $container->findDefinition($definition->getParent());
|
||||
|
||||
$class = $definition->getClass();
|
||||
if ($class) {
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" must define its class.', $id));
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Doctrine\Bundle\DoctrineBundle\Mapping\ClassMetadataFactory;
|
||||
use Doctrine\Bundle\DoctrineBundle\Mapping\MappingDriver;
|
||||
use Doctrine\ORM\Mapping\ClassMetadataFactory as ORMClassMetadataFactory;
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
use function array_combine;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function sprintf;
|
||||
|
||||
final class IdGeneratorPass implements CompilerPassInterface
|
||||
{
|
||||
public const ID_GENERATOR_TAG = 'doctrine.id_generator';
|
||||
public const CONFIGURATION_TAG = 'doctrine.orm.configuration';
|
||||
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
$generatorIds = array_keys($container->findTaggedServiceIds(self::ID_GENERATOR_TAG));
|
||||
|
||||
// when ORM is not enabled
|
||||
if (! $container->hasDefinition('doctrine.orm.configuration') || ! $generatorIds) {
|
||||
return;
|
||||
}
|
||||
|
||||
$generatorRefs = array_map(static function ($id) {
|
||||
return new Reference($id);
|
||||
}, $generatorIds);
|
||||
|
||||
$ref = ServiceLocatorTagPass::register($container, array_combine($generatorIds, $generatorRefs));
|
||||
$container->setAlias('doctrine.id_generator_locator', new Alias((string) $ref, false));
|
||||
|
||||
foreach ($container->findTaggedServiceIds(self::CONFIGURATION_TAG) as $id => $tags) {
|
||||
$configurationDef = $container->getDefinition($id);
|
||||
$methodCalls = $configurationDef->getMethodCalls();
|
||||
$metadataDriverImpl = null;
|
||||
|
||||
foreach ($methodCalls as $i => [$method, $arguments]) {
|
||||
if ($method === 'setMetadataDriverImpl') {
|
||||
$metadataDriverImpl = (string) $arguments[0];
|
||||
}
|
||||
|
||||
if ($method !== 'setClassMetadataFactoryName') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($arguments[0] !== ORMClassMetadataFactory::class && $arguments[0] !== ClassMetadataFactory::class) {
|
||||
$class = $container->getReflectionClass($arguments[0]);
|
||||
|
||||
if ($class && $class->isSubclassOf(ClassMetadataFactory::class)) {
|
||||
break;
|
||||
}
|
||||
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$methodCalls[$i] = ['setClassMetadataFactoryName', [ClassMetadataFactory::class]];
|
||||
}
|
||||
|
||||
if ($metadataDriverImpl === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$configurationDef->setMethodCalls($methodCalls);
|
||||
$container->register('.' . $metadataDriverImpl, MappingDriver::class)
|
||||
->setDecoratedService($metadataDriverImpl)
|
||||
->setArguments([
|
||||
new Reference(sprintf('.%s.inner', $metadataDriverImpl)),
|
||||
new Reference('doctrine.id_generator_locator'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Doctrine\Bundle\DoctrineBundle\Middleware\ConnectionNameAwareInterface;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
use function array_key_exists;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
use function array_values;
|
||||
use function is_subclass_of;
|
||||
use function sprintf;
|
||||
use function uasort;
|
||||
|
||||
final class MiddlewaresPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
if (! $container->hasParameter('doctrine.connections')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$middlewareAbstractDefs = [];
|
||||
$middlewareConnections = [];
|
||||
$middlewarePriorities = [];
|
||||
foreach ($container->findTaggedServiceIds('doctrine.middleware') as $id => $tags) {
|
||||
$middlewareAbstractDefs[$id] = $container->getDefinition($id);
|
||||
// When a def has doctrine.middleware tags with connection attributes equal to connection names
|
||||
// registration of this middleware is limited to the connections with these names
|
||||
foreach ($tags as $tag) {
|
||||
if (! isset($tag['connection'])) {
|
||||
if (isset($tag['priority']) && ! isset($middlewarePriorities[$id])) {
|
||||
$middlewarePriorities[$id] = $tag['priority'];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$middlewareConnections[$id][$tag['connection']] = $tag['priority'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (array_keys($container->getParameter('doctrine.connections')) as $name) {
|
||||
$middlewareDefs = [];
|
||||
$i = 0;
|
||||
foreach ($middlewareAbstractDefs as $id => $abstractDef) {
|
||||
if (isset($middlewareConnections[$id]) && ! array_key_exists($name, $middlewareConnections[$id])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$middlewareDefs[$id] = [
|
||||
$childDef = $container->setDefinition(
|
||||
sprintf('%s.%s', $id, $name),
|
||||
new ChildDefinition($id),
|
||||
),
|
||||
++$i,
|
||||
];
|
||||
|
||||
if (! is_subclass_of($abstractDef->getClass(), ConnectionNameAwareInterface::class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$childDef->addMethodCall('setConnectionName', [$name]);
|
||||
}
|
||||
|
||||
$middlewareDefs = array_map(
|
||||
static fn ($id, $def) => [
|
||||
$middlewareConnections[$id][$name] ?? $middlewarePriorities[$id] ?? 0,
|
||||
$def[1],
|
||||
$def[0],
|
||||
],
|
||||
array_keys($middlewareDefs),
|
||||
array_values($middlewareDefs),
|
||||
);
|
||||
uasort($middlewareDefs, static fn ($a, $b) => $b[0] <=> $a[0] ?: $a[1] <=> $b[1]);
|
||||
$middlewareDefs = array_map(static fn ($value) => $value[2], $middlewareDefs);
|
||||
|
||||
$container
|
||||
->getDefinition(sprintf('doctrine.dbal.%s_connection.configuration', $name))
|
||||
->addMethodCall('setMiddlewares', [$middlewareDefs]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/** @internal */
|
||||
final class RemoveLoggingMiddlewarePass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
if ($container->has('logger')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container->removeDefinition('doctrine.dbal.logging_middleware');
|
||||
}
|
||||
}
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Doctrine\Bundle\DoctrineBundle\Controller\ProfilerController;
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/** @internal */
|
||||
final class RemoveProfilerControllerPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
if ($container->has('twig') && $container->has('profiler')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$container->removeDefinition(ProfilerController::class);
|
||||
}
|
||||
}
|
||||
Vendored
+36
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
use function array_combine;
|
||||
use function array_keys;
|
||||
use function array_map;
|
||||
|
||||
final class ServiceRepositoryCompilerPass implements CompilerPassInterface
|
||||
{
|
||||
public const REPOSITORY_SERVICE_TAG = 'doctrine.repository_service';
|
||||
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
// when ORM is not enabled
|
||||
if (! $container->hasDefinition('doctrine.orm.container_repository_factory')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$locatorDef = $container->getDefinition('doctrine.orm.container_repository_factory');
|
||||
|
||||
$repoServiceIds = array_keys($container->findTaggedServiceIds(self::REPOSITORY_SERVICE_TAG));
|
||||
|
||||
$repoReferences = array_map(static function ($id) {
|
||||
return new Reference($id);
|
||||
}, $repoServiceIds);
|
||||
|
||||
$ref = ServiceLocatorTagPass::register($container, array_combine($repoServiceIds, $repoReferences));
|
||||
$locatorDef->replaceArgument(0, $ref);
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler;
|
||||
|
||||
use function array_keys;
|
||||
use function method_exists;
|
||||
|
||||
/**
|
||||
* Blacklist tables used by well-known Symfony classes.
|
||||
*
|
||||
* @deprecated Implement your own include/exclude mechanism
|
||||
*
|
||||
* @final since 2.9
|
||||
*/
|
||||
class WellKnownSchemaFilterPass implements CompilerPassInterface
|
||||
{
|
||||
/** @return void */
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$blacklist = [];
|
||||
|
||||
foreach ($container->getDefinitions() as $definition) {
|
||||
if ($definition->isAbstract() || $definition->isSynthetic()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($definition->getClass() !== PdoSessionHandler::class) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$table = $definition->getArguments()[1]['db_table'] ?? 'sessions';
|
||||
|
||||
if (! method_exists($definition->getClass(), 'configureSchema')) {
|
||||
$blacklist[] = $table;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (! $blacklist) {
|
||||
return;
|
||||
}
|
||||
|
||||
$definition = $container->getDefinition('doctrine.dbal.well_known_schema_asset_filter');
|
||||
$definition->replaceArgument(0, $blacklist);
|
||||
|
||||
foreach (array_keys($container->getParameter('doctrine.connections')) as $name) {
|
||||
$definition->addTag('doctrine.dbal.schema_filter', ['connection' => $name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user