protected function processEntityManager($name, array $defaults)
{
$builder = $this->getContainerBuilder();
$config = $this->resolveConfig($defaults, $this->managerDefaults, $this->connectionDefaults);
if ($isDefault = !isset($builder->parameters[$this->name]['orm']['defaultEntityManager'])) {
$builder->parameters[$this->name]['orm']['defaultEntityManager'] = $name;
}
$metadataDriver = $builder->addDefinition($this->prefix($name . '.metadataDriver'))->setClass('Doctrine\\Common\\Persistence\\Mapping\\Driver\\MappingDriverChain')->setAutowired(FALSE)->setInject(FALSE);
/** @var Nette\DI\ServiceDefinition $metadataDriver */
Validators::assertField($config, 'metadata', 'array');
Validators::assertField($config, 'targetEntityMappings', 'array');
$config['targetEntityMappings'] = $this->normalizeTargetEntityMappings($config['targetEntityMappings']);
foreach ($this->compiler->getExtensions() as $extension) {
if ($extension instanceof IEntityProvider) {
$metadata = $extension->getEntityMappings();
Validators::assert($metadata, 'array');
$config['metadata'] = array_merge($config['metadata'], $metadata);
}
if ($extension instanceof ITargetEntityProvider) {
$targetEntities = $extension->getTargetEntityMappings();
Validators::assert($targetEntities, 'array');
$config['targetEntityMappings'] = Nette\Utils\Arrays::mergeTree($config['targetEntityMappings'], $this->normalizeTargetEntityMappings($targetEntities));
}
if ($extension instanceof IDatabaseTypeProvider) {
$providedTypes = $extension->getDatabaseTypes();
Validators::assert($providedTypes, 'array');
if (!isset($defaults['types'])) {
$defaults['types'] = [];
}
$defaults['types'] = array_merge($defaults['types'], $providedTypes);
}
}
foreach (self::natSortKeys($config['metadata']) as $namespace => $driver) {
$this->processMetadataDriver($metadataDriver, $namespace, $driver, $name);
}
$this->processMetadataDriver($metadataDriver, 'Kdyby\\Doctrine', __DIR__ . '/../Entities', $name);
if (empty($config['metadata'])) {
$metadataDriver->addSetup('setDefaultDriver', [new Statement($this->metadataDriverClasses[self::ANNOTATION_DRIVER], [[$builder->expand('%appDir%')], 2 => $this->prefix('@cache.' . $name . '.metadata')])]);
}
if ($config['repositoryFactoryClassName'] === 'default') {
$config['repositoryFactoryClassName'] = 'Doctrine\\ORM\\Repository\\DefaultRepositoryFactory';
}
$builder->addDefinition($this->prefix($name . '.repositoryFactory'))->setClass($config['repositoryFactoryClassName'])->setAutowired(FALSE);
Validators::assertField($config, 'namespaceAlias', 'array');
Validators::assertField($config, 'hydrators', 'array');
Validators::assertField($config, 'dql', 'array');
Validators::assertField($config['dql'], 'string', 'array');
Validators::assertField($config['dql'], 'numeric', 'array');
Validators::assertField($config['dql'], 'datetime', 'array');
Validators::assertField($config['dql'], 'hints', 'array');
$autoGenerateProxyClasses = is_bool($config['autoGenerateProxyClasses']) ? $config['autoGenerateProxyClasses'] ? AbstractProxyFactory::AUTOGENERATE_ALWAYS : AbstractProxyFactory::AUTOGENERATE_NEVER : $config['autoGenerateProxyClasses'];
$configuration = $builder->addDefinition($this->prefix($name . '.ormConfiguration'))->setClass('Kdyby\\Doctrine\\Configuration')->addSetup('setMetadataCacheImpl', [$this->processCache($config['metadataCache'], $name . '.metadata')])->addSetup('setQueryCacheImpl', [$this->processCache($config['queryCache'], $name . '.query')])->addSetup('setResultCacheImpl', [$this->processCache($config['resultCache'], $name . '.ormResult')])->addSetup('setHydrationCacheImpl', [$this->processCache($config['hydrationCache'], $name . '.hydration')])->addSetup('setMetadataDriverImpl', [$this->prefix('@' . $name . '.metadataDriver')])->addSetup('setClassMetadataFactoryName', [$config['classMetadataFactory']])->addSetup('setDefaultRepositoryClassName', [$config['defaultRepositoryClassName']])->addSetup('setQueryBuilderClassName', [$config['queryBuilderClassName']])->addSetup('setRepositoryFactory', [$this->prefix('@' . $name . '.repositoryFactory')])->addSetup('setProxyDir', [$config['proxyDir']])->addSetup('setProxyNamespace', [$config['proxyNamespace']])->addSetup('setAutoGenerateProxyClasses', [$autoGenerateProxyClasses])->addSetup('setEntityNamespaces', [$config['namespaceAlias']])->addSetup('setCustomHydrationModes', [$config['hydrators']])->addSetup('setCustomStringFunctions', [$config['dql']['string']])->addSetup('setCustomNumericFunctions', [$config['dql']['numeric']])->addSetup('setCustomDatetimeFunctions', [$config['dql']['datetime']])->addSetup('setDefaultQueryHints', [$config['dql']['hints']])->addSetup('setNamingStrategy', CacheHelpers::filterArgs($config['namingStrategy']))->addSetup('setQuoteStrategy', CacheHelpers::filterArgs($config['quoteStrategy']))->addSetup('setEntityListenerResolver', CacheHelpers::filterArgs($config['entityListenerResolver']))->setAutowired(FALSE)->setInject(FALSE);
/** @var Nette\DI\ServiceDefinition $configuration */
$this->proxyAutoloaders[$config['proxyNamespace']] = $config['proxyDir'];
$this->processSecondLevelCache($name, $config['secondLevelCache'], $isDefault);
Validators::assertField($config, 'filters', 'array');
foreach ($config['filters'] as $filterName => $filterClass) {
$configuration->addSetup('addFilter', [$filterName, $filterClass]);
}
if ($config['targetEntityMappings']) {
$configuration->addSetup('setTargetEntityMap', [array_map(function ($mapping) {
return $mapping['targetEntity'];
}, $config['targetEntityMappings'])]);
$this->targetEntityMappings = Nette\Utils\Arrays::mergeTree($this->targetEntityMappings, $config['targetEntityMappings']);
}
if ($this->isKdybyEventsPresent()) {
$builder->addDefinition($this->prefix($name . '.evm'))->setClass('Kdyby\\Events\\NamespacedEventManager', [Kdyby\Doctrine\Events::NS . '::'])->addSetup('$dispatchGlobalEvents', [TRUE])->setAutowired(FALSE);
} else {
$builder->addDefinition($this->prefix($name . '.evm'))->setClass('Doctrine\\Common\\EventManager')->setAutowired(FALSE);
}
// entity manager
$entityManager = $builder->addDefinition($managerServiceId = $this->prefix($name . '.entityManager'))->setClass('Kdyby\\Doctrine\\EntityManager')->setFactory('Kdyby\\Doctrine\\EntityManager::create', [$connectionService = $this->processConnection($name, $defaults, $isDefault), $this->prefix('@' . $name . '.ormConfiguration'), $this->prefix('@' . $name . '.evm')])->addTag(self::TAG_ENTITY_MANAGER)->addTag('kdyby.doctrine.entityManager')->setAutowired($isDefault)->setInject(FALSE);
if ($this->isTracyPresent()) {
$entityManager->addSetup('?->bindEntityManager(?)', [$this->prefix('@' . $name . '.diagnosticsPanel'), '@self']);
}
$builder->addDefinition($this->prefix('repositoryFactory.' . $name . '.defaultRepositoryFactory'))->setClass($config['defaultRepositoryClassName'])->setImplement('Kdyby\\Doctrine\\DI\\IRepositoryFactory')->setArguments([new Code\PhpLiteral('$entityManager'), new Code\PhpLiteral('$classMetadata')])->setParameters(['Doctrine\\ORM\\EntityManagerInterface entityManager', 'Doctrine\\ORM\\Mapping\\ClassMetadata classMetadata'])->setAutowired(FALSE);
$builder->addDefinition($this->prefix($name . '.schemaValidator'))->setClass('Doctrine\\ORM\\Tools\\SchemaValidator', ['@' . $managerServiceId])->setAutowired($isDefault);
$builder->addDefinition($this->prefix($name . '.schemaTool'))->setClass('Doctrine\\ORM\\Tools\\SchemaTool', ['@' . $managerServiceId])->setAutowired($isDefault);
$cacheCleaner = $builder->addDefinition($this->prefix($name . '.cacheCleaner'))->setClass('Kdyby\\Doctrine\\Tools\\CacheCleaner', ['@' . $managerServiceId])->setAutowired($isDefault);
$builder->addDefinition($this->prefix($name . '.schemaManager'))->setClass('Doctrine\\DBAL\\Schema\\AbstractSchemaManager')->setFactory('@Kdyby\\Doctrine\\Connection::getSchemaManager')->setAutowired($isDefault);
foreach ($this->compiler->getExtensions('Kdyby\\Annotations\\DI\\AnnotationsExtension') as $extension) {
/** @var Kdyby\Annotations\DI\AnnotationsExtension $extension */
$cacheCleaner->addSetup('addCacheStorage', [$extension->prefix('@cache.annotations')]);
}
if ($isDefault) {
$builder->addDefinition($this->prefix('helper.entityManager'))->setClass('Doctrine\\ORM\\Tools\\Console\\Helper\\EntityManagerHelper', ['@' . $managerServiceId])->addTag(Kdyby\Console\DI\ConsoleExtension::HELPER_TAG, 'em');
$builder->addDefinition($this->prefix('helper.connection'))->setClass('Doctrine\\DBAL\\Tools\\Console\\Helper\\ConnectionHelper', [$connectionService])->addTag(Kdyby\Console\DI\ConsoleExtension::HELPER_TAG, 'db');
$builder->addAlias($this->prefix('schemaValidator'), $this->prefix($name . '.schemaValidator'));
$builder->addAlias($this->prefix('schemaTool'), $this->prefix($name . '.schemaTool'));
$builder->addAlias($this->prefix('cacheCleaner'), $this->prefix($name . '.cacheCleaner'));
$builder->addAlias($this->prefix('schemaManager'), $this->prefix($name . '.schemaManager'));
}
$this->configuredManagers[$name] = $managerServiceId;
$this->managerConfigs[$name] = $config;
}