'Mysql', 'mysqli' => 'Mysql', ]; public function __construct( Config $config, InjectableFactory $injectableFactory, MetadataDataProvider $metadataDataProvider, EventDispatcher $eventDispatcher ) { $this->config = $config; $this->injectableFactory = $injectableFactory; $this->metadataDataProvider = $metadataDataProvider; $this->eventDispatcher = $eventDispatcher; } public function create(): EntityManager { $entityFactory = $this->injectableFactory->create(EntityFactory::class); $repositoryFactory = $this->injectableFactory->createWithBinding( RepositoryFactory::class, BindingContainerBuilder::create() ->bindInstance(EntityFactoryInteface::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() ); $binding = BindingContainerBuilder::create() ->bindInstance(DatabaseParams::class, $databaseParams) ->bindInstance(Metadata::class, $metadata) ->bindInstance(RepositoryFactoryInterface::class, $repositoryFactory) ->bindInstance(EntityFactoryInteface::class, $entityFactory) ->bindInstance(ValueFactoryFactoryInteface::class, $valueFactoryFactory) ->bindInstance(AttributeExtractorFactoryInteface::class, $attributeExtractorFactory) ->bindInstance(EventDispatcher::class, $this->eventDispatcher) ->bindImplementation(PDOProvider::class, DefaultPDOProvider::class) ->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; } }