*/ private $driverPlatformMap = [ 'pdo_mysql' => 'Mysql', 'mysqli' => 'Mysql', ]; public function __construct( private Config $config, private InjectableFactory $injectableFactory, private MetadataDataProvider $metadataDataProvider, private EventDispatcher $eventDispatcher, private PDOFactoryFactory $pdoFactoryFactory ) {} public function create(): EntityManager { $entityFactory = $this->injectableFactory->create(EntityFactory::class); $repositoryFactory = $this->injectableFactory->createWithBinding( RepositoryFactory::class, BindingContainerBuilder::create() ->bindInstance(EntityFactoryInterface::class, $entityFactory) ->build() ); $databaseParams = $this->createDatabaseParams(); $metadata = new Metadata($this->metadataDataProvider, $this->eventDispatcher); $valueFactoryFactory = $this->injectableFactory->createWithBinding( ValueFactoryFactory::class, BindingContainerBuilder::create() ->bindInstance(Metadata::class, $metadata) ->build() ); $attributeExtractorFactory = $this->injectableFactory->createWithBinding( AttributeExtractorFactory::class, BindingContainerBuilder::create() ->bindInstance(Metadata::class, $metadata) ->build() ); $functionConverterFactory = $this->injectableFactory->createWithBinding( FunctionConverterFactory::class, BindingContainerBuilder::create() ->bindInstance(DatabaseParams::class, $databaseParams) ->build() ); $pdoFactory = $this->pdoFactoryFactory->create($databaseParams->getPlatform() ?? ''); $pdoProvider = $this->injectableFactory->createResolved( PDOProvider::class, BindingContainerBuilder::create() ->bindInstance(DatabaseParams::class, $databaseParams) ->bindInstance(PDOFactory::class, $pdoFactory) ->build() ); $queryComposerFactory = $this->injectableFactory->createWithBinding( QueryComposerFactory::class, BindingContainerBuilder::create() ->bindInstance(PDOProvider::class, $pdoProvider) ->bindInstance(Metadata::class, $metadata) ->bindInstance(EntityFactoryInterface::class, $entityFactory) ->bindInstance(FunctionConverterFactoryInterface::class, $functionConverterFactory) ->build() ); $binding = BindingContainerBuilder::create() ->bindInstance(DatabaseParams::class, $databaseParams) ->bindInstance(Metadata::class, $metadata) ->bindInstance(QueryComposerFactoryInterface::class, $queryComposerFactory) ->bindInstance(RepositoryFactoryInterface::class, $repositoryFactory) ->bindInstance(EntityFactoryInterface::class, $entityFactory) ->bindInstance(ValueFactoryFactoryInterface::class, $valueFactoryFactory) ->bindInstance(AttributeExtractorFactoryInterface::class, $attributeExtractorFactory) ->bindInstance(EventDispatcher::class, $this->eventDispatcher) ->bindInstance(PDOProvider::class, $pdoProvider) ->bindInstance(FunctionConverterFactoryInterface::class, $functionConverterFactory) ->build(); return $this->injectableFactory->createWithBinding(EntityManager::class, $binding); } private function createDatabaseParams(): DatabaseParams { $config = $this->config; $databaseParams = DatabaseParams::create() ->withHost($config->get('database.host')) ->withPort($config->get('database.port') ? (int) $config->get('database.port') : null) ->withName($config->get('database.dbname')) ->withUsername($config->get('database.user')) ->withPassword($config->get('database.password')) ->withCharset($config->get('database.charset') ?? 'utf8') ->withPlatform($config->get('database.platform')) ->withSslCa($config->get('database.sslCA')) ->withSslCert($config->get('database.sslCert')) ->withSslKey($config->get('database.sslKey')) ->withSslCaPath($config->get('database.sslCAPath')) ->withSslCipher($config->get('database.sslCipher')) ->withSslVerifyDisabled($config->get('database.sslVerifyDisabled') ?? false); if (!$databaseParams->getName()) { throw new RuntimeException('No database name specified.'); } if (!$databaseParams->getPlatform()) { $driver = $config->get('database.driver'); if (!$driver) { throw new RuntimeException('No database driver specified.'); } $platform = $this->driverPlatformMap[$driver] ?? null; if (!$platform) { throw new RuntimeException("Database driver '{$driver}' is not supported."); } $databaseParams = $databaseParams->withPlatform($platform); } return $databaseParams; } }