Skip to content

Commit

Permalink
Allow customizing URI options more
Browse files Browse the repository at this point in the history
  • Loading branch information
Daniele Scibilia committed Jun 1, 2023
1 parent 1cf9334 commit d15bc89
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 11 deletions.
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"facile-it/facile-coding-standard": "^0.4.0",
"phpstan/phpstan": "^0.12.88",
"phpstan/extension-installer": "^1.1",
"jangregor/phpstan-prophecy": "^0.8.1"
"jangregor/phpstan-prophecy": "^0.8.1",
"phpspec/prophecy": "~1.0"
},
"minimum-stability": "stable",
"suggest": {
Expand Down
47 changes: 47 additions & 0 deletions docs/Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 21 additions & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ parameters:
count: 1
path: src/Capsule/Collection.php

-
message: "#^Method Facile\\\\MongoDbBundle\\\\Capsule\\\\Collection\\:\\:distinct\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Capsule/Collection.php

-
message: "#^Method Facile\\\\MongoDbBundle\\\\Capsule\\\\Collection\\:\\:find\\(\\) has parameter \\$filter with no value type specified in iterable type array\\.$#"
count: 1
Expand Down Expand Up @@ -430,6 +435,11 @@ parameters:
count: 1
path: src/DependencyInjection/MongoDbBundleExtension.php

-
message: "#^Method Facile\\\\MongoDbBundle\\\\DependencyInjection\\\\MongoDbBundleExtension\\:\\:defineUriOptionsFactory\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#"
count: 1
path: src/DependencyInjection/MongoDbBundleExtension.php

-
message: "#^Method Facile\\\\MongoDbBundle\\\\DependencyInjection\\\\MongoDbBundleExtension\\:\\:load\\(\\) has no return typehint specified\\.$#"
count: 1
Expand All @@ -446,7 +456,7 @@ parameters:
path: src/DependencyInjection/MongoDbBundleExtension.php

-
message: "#^Parameter \\#2 \\$debug of method Facile\\\\MongoDbBundle\\\\DependencyInjection\\\\MongoDbBundleExtension\\:\\:defineClientRegistry\\(\\) expects bool, array\\|bool\\|float\\|int\\|string\\|null given\\.$#"
message: "#^Parameter \\#2 \\$debug of method Facile\\\\MongoDbBundle\\\\DependencyInjection\\\\MongoDbBundleExtension\\:\\:defineClientRegistry\\(\\) expects bool, array\\|bool\\|float\\|int\\|string\\|UnitEnum\\|null given\\.$#"
count: 1
path: src/DependencyInjection/MongoDbBundleExtension.php

Expand Down Expand Up @@ -780,6 +790,16 @@ parameters:
count: 1
path: src/Services/Loggers/MongoQueryLogger.php

-
message: "#^Method Facile\\\\MongoDbBundle\\\\Services\\\\UriOptions\\\\UriOptionsInterface\\:\\:buildUriOptions\\(\\) has parameter \\$clientConfiguration with no value type specified in iterable type array\\.$#"
count: 1
path: src/Services/UriOptions/UriOptionsInterface.php

-
message: "#^Method Facile\\\\MongoDbBundle\\\\Services\\\\UriOptions\\\\UriOptionsInterface\\:\\:buildUriOptions\\(\\) return type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Services/UriOptions/UriOptionsInterface.php

-
message: "#^Class Twig_Extension not found\\.$#"
count: 1
Expand Down
14 changes: 14 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function getConfigTreeBuilder(): TreeBuilder
self::addDataCollection($rootBuilder->children());
self::addClients($rootBuilder->children());
self::addConnections($rootBuilder->children());
self::addUriOptions($rootBuilder->children());
self::addDriversOption($rootBuilder->children());

return $treeBuilder;
Expand Down Expand Up @@ -134,4 +135,17 @@ private static function addConnections(NodeBuilder $builder): void
->isRequired()
->info('Database name');
}

private static 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');
}
}
6 changes: 6 additions & 0 deletions src/DependencyInjection/MongoDbBundleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ private function defineClientRegistry(array $config, bool $debug): void
[
new Reference('facile_mongo_db.event_dispatcher'),
$debug,
$this->defineUriOptionsFactory($config),
$this->defineDriverOptionsFactory($config),
]
);
Expand Down Expand Up @@ -114,6 +115,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;
Expand Down
22 changes: 16 additions & 6 deletions src/Services/ClientRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
use Symfony\Component\HttpKernel\Kernel;
Expand All @@ -31,19 +32,23 @@ final class ClientRegistry
/** @var EventDispatcherInterface */
private $eventDispatcher;

/** @var UriOptionsInterface */
private $uriOptionsService;
/** @var DriverOptionsInterface */
private $driverOptionsService;

public function __construct(
EventDispatcherInterface $eventDispatcher,
bool $debug,
?UriOptionsInterface $uriOptionsService,
?DriverOptionsInterface $driverOptionsService
) {
$this->clients = [];
$this->configurations = [];
$this->debug = $debug;
$this->eventDispatcher = $eventDispatcher;
$this->driverOptionsService = $driverOptionsService;
$this->uriOptionsService = $uriOptionsService;
}

public function addClientsConfigurations(array $configurations): void
Expand All @@ -64,6 +69,16 @@ private function buildClientConfiguration(array $conf): ClientConfiguration
$conf['uri'] = self::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);
Expand All @@ -74,12 +89,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']
);
}
Expand Down
22 changes: 22 additions & 0 deletions src/Services/UriOptions/UriOptionsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Facile\MongoDbBundle\Services\UriOptions;

use MongoDB\Client;

interface UriOptionsInterface
{
/**
* It creates an array of options for constructing a MongoDB\Client
*
* @param array $clientConfiguration client's bundle configuration for which the options are needed
*
* @return array Options for MongoDB\Client
*
* @see Client
* @see http://php.net/manual/en/mongodb-driver-manager.construct.php
*/
public function buildUriOptions(array $clientConfiguration): array;
}
6 changes: 3 additions & 3 deletions tests/Unit/Services/ClientRegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ClientRegistryTest extends TestCase
{
public function test_client_connection_url_provided_manually()
{
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null);
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null);

$testConf = [
'test_client' => [
Expand All @@ -41,7 +41,7 @@ public function test_client_connection_url_provided_manually()

public function test_client_connection_url_generation_singlehost()
{
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null);
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null);

$testConf = [
'test_client' => [
Expand Down Expand Up @@ -69,7 +69,7 @@ public function test_client_connection_url_generation_singlehost()

public function test_client_connection_url_generation_multihost()
{
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null);
$registry = new ClientRegistry($this->createEventDispatcherMock(), false, null, null);

$testConf = [
'test_client' => [
Expand Down

0 comments on commit d15bc89

Please sign in to comment.