diff --git a/docs/Documentation.md b/docs/Documentation.md index aae9e77..6cb1dd4 100644 --- a/docs/Documentation.md +++ b/docs/Documentation.md @@ -90,10 +90,57 @@ mongo_db_bundle: client_name: ~ database_name: ~ + # Service reference to provide URI options - see example below + uriOptions: 'App\Services\UriOptionsProvider' # default null + # Service reference to provide driver options - see example below driverOptions: 'App\Services\DriverOptionsProvider' # default null ``` +### Uri options + +You might need to specify some URI options for constructing the `MongoDB\Client`. Read the [reference] for a complete +explanation of all the available options. + +Implement `UriOptionsInterface` and declare the class as a Symfony service. + +```php +namespace App\Services; + +use Facile\MongoDbBundle\Services\UriOptions\UriOptionsInterface; + +final class MyCustomUriOptionsProvider implements DriverOptionsInterface +{ + /** @var string */ + private $appname; + + public function __construct(string $appname) { + $this->appname = $appname; + } + + public function buildDriverOptions(array $clientConfiguration) : array { + $clientConfiguration['appname'] = $this->appname; + return $clientConfiguration; + } +} +``` + +```yaml +# config/services.yaml +App\Services\MyCustomUriOptionsProvider: + arguments: + $appname: 'APPNAME' +``` + +Then use its service id as value of `uriOptions` in the bundle configuration. + +```yml +# config/packages/facile_it_mongodb.yaml +mongo_db_bundle: + uriOptions: 'App\Services\MyCustomUriOptionsProvider' + # ... +``` + ### Driver options You might need to specify some driver options for constructing the `MongoDB\Client`. Read the [reference] for a complete diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index c690fb2..9da7883 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -26,6 +26,7 @@ public function getConfigTreeBuilder(): TreeBuilder $this->addDataCollection($rootBuilder->children()); $this->addClients($rootBuilder->children()); $this->addConnections($rootBuilder->children()); + $this->addUriOptions($rootBuilder->children()); $this->addDriversOption($rootBuilder->children()); return $treeBuilder; @@ -132,4 +133,17 @@ private function addConnections(NodeBuilder $builder): void ->isRequired() ->info('Database name'); } + + private function addUriOptions(NodeBuilder $builder): void + { + $uriOptionsBuilder = $builder + ->arrayNode('uriOptions') + ->info('Additional connection string options') + ->children(); + + $uriOptionsBuilder + ->variableNode('context') + ->defaultValue([]) + ->info('Overwrite any options with the same name in the uri parameter'); + } } diff --git a/src/DependencyInjection/MongoDbBundleExtension.php b/src/DependencyInjection/MongoDbBundleExtension.php index 8462061..9786e86 100644 --- a/src/DependencyInjection/MongoDbBundleExtension.php +++ b/src/DependencyInjection/MongoDbBundleExtension.php @@ -58,6 +58,7 @@ private function defineClientRegistry(array $config, bool $debug): void [ new Reference('facile_mongo_db.event_dispatcher'), $debug, + $this->defineUriOptionsFactory($config), $this->defineDriverOptionsFactory($config), ] ); @@ -111,6 +112,11 @@ private function attachDataCollectionListenerToEventManager(): void ); } + private function defineUriOptionsFactory(array $config): ?Reference + { + return isset($config['uriOptions']) ? new Reference($config['uriOptions']) : null; + } + private function defineDriverOptionsFactory(array $config): ?Reference { return isset($config['driverOptions']) ? new Reference($config['driverOptions']) : null; diff --git a/src/Services/ClientRegistry.php b/src/Services/ClientRegistry.php index 9ed6088..6600596 100644 --- a/src/Services/ClientRegistry.php +++ b/src/Services/ClientRegistry.php @@ -8,6 +8,7 @@ use Facile\MongoDbBundle\Event\ConnectionEvent; use Facile\MongoDbBundle\Models\ClientConfiguration; use Facile\MongoDbBundle\Services\DriverOptions\DriverOptionsInterface; +use Facile\MongoDbBundle\Services\UriOptions\UriOptionsInterface; use MongoDB\Client; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -28,16 +29,20 @@ final class ClientRegistry private EventDispatcherInterface $eventDispatcher; + private ?UriOptionsInterface $uriOptionsService; + private ?DriverOptionsInterface $driverOptionsService; public function __construct( EventDispatcherInterface $eventDispatcher, bool $debug, + ?UriOptionsInterface $uriOptionsService, ?DriverOptionsInterface $driverOptionsService ) { $this->debug = $debug; $this->eventDispatcher = $eventDispatcher; $this->driverOptionsService = $driverOptionsService; + $this->uriOptionsService = $uriOptionsService; } public function addClientsConfigurations(array $configurations): void @@ -53,6 +58,16 @@ private function buildClientConfiguration(array $conf): ClientConfiguration $conf['uri'] = $this->buildConnectionUri($conf['hosts']); } + $conf['uriOptions'] = [ + 'replicaSet' => $conf['replicaSet'], + 'ssl' => $conf['ssl'], + 'connectTimeoutMS' => $conf['connectTimeoutMS'], + 'readPreference' => $conf['readPreference'], + ]; + if ($this->uriOptionsService instanceof UriOptionsInterface) { + $conf['options'] = $this->uriOptionsService->buildUriOptions($conf['uriOptions']); + } + $conf['driverOptions'] = []; if ($this->driverOptionsService instanceof DriverOptionsInterface) { $conf['driverOptions'] = $this->driverOptionsService->buildDriverOptions($conf); @@ -63,12 +78,7 @@ private function buildClientConfiguration(array $conf): ClientConfiguration $conf['username'], $conf['password'], $conf['authSource'], - [ - 'replicaSet' => $conf['replicaSet'], - 'ssl' => $conf['ssl'], - 'connectTimeoutMS' => $conf['connectTimeoutMS'], - 'readPreference' => $conf['readPreference'], - ], + $conf['uriOptions'], $conf['driverOptions'] ); } diff --git a/src/Services/UriOptions/UriOptionsInterface.php b/src/Services/UriOptions/UriOptionsInterface.php new file mode 100644 index 0000000..731c0a8 --- /dev/null +++ b/src/Services/UriOptions/UriOptionsInterface.php @@ -0,0 +1,22 @@ +createEventDispatcherMock(), false, null); + $registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null); $testConf = [ 'test_client' => [ @@ -43,7 +43,7 @@ public function test_client_connection_url_provided_manually(): void public function test_client_connection_url_generation_singlehost(): void { - $registry = new ClientRegistry($this->createEventDispatcherMock(), false, null); + $registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null); $testConf = [ 'test_client' => [ @@ -71,7 +71,7 @@ public function test_client_connection_url_generation_singlehost(): void public function test_client_connection_url_generation_multihost(): void { - $registry = new ClientRegistry($this->createEventDispatcherMock(), false, null); + $registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null); $testConf = [ 'test_client' => [