Skip to content

Commit 9fa37e7

Browse files
committed
Merge pull request #731
* phplib-516: PHPLIB-516: Append PHPLIB version information to handshake data
2 parents 68879de + c31f5d5 commit 9fa37e7

File tree

4 files changed

+102
-3
lines changed

4 files changed

+102
-3
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"php": "^7.0",
1414
"ext-hash": "*",
1515
"ext-json": "*",
16-
"ext-mongodb": "^1.8"
16+
"ext-mongodb": "^1.8",
17+
"jean85/pretty-package-versions": "^1.2"
1718
},
1819
"require-dev": {
1920
"phpunit/phpunit": "^6.4 || ^8.3",

docs/includes/apiargs-MongoDBClient-method-construct-driverOptions.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,34 @@ description: |
142142
For the ``keyVaultClient`` option, you may pass a :phpclass:`MongoDB\\Client`
143143
instance, which will be unwrapped to provide a :php:`MongoDB\\Driver\\Manager <class.mongodb-driver-manager>`
144144
to the extension.
145+
.. versionadded:: 1.6
146+
interface: phpmethod
147+
operation: ~
148+
optional: true
149+
---
150+
arg_name: option
151+
name: driver
152+
type: array
153+
description: |
154+
Additional driver metadata to be passed on to the server handshake. This is an
155+
array containing ``name``, ``version``, and ``platform`` fields:
156+
157+
.. code-block:: php
158+
159+
[
160+
'name' => 'my-driver',
161+
'version' => '1.2.3-dev',
162+
'platform' => 'some-platform',
163+
]
164+
165+
.. note::
166+
167+
This feature is primarily designed for custom drivers and ODMs, which may
168+
want to identify themselves to the server for diagnostic purposes.
169+
Applications should use the ``appName`` URI option instead of driver
170+
metadata.
171+
172+
.. versionadded:: 1.7
145173
interface: phpmethod
146174
operation: ~
147175
optional: true

src/Client.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace MongoDB;
1919

20+
use Jean85\PrettyVersions;
2021
use MongoDB\Driver\ClientEncryption;
2122
use MongoDB\Driver\Exception\InvalidArgumentException as DriverInvalidArgumentException;
2223
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
@@ -34,7 +35,9 @@
3435
use MongoDB\Operation\DropDatabase;
3536
use MongoDB\Operation\ListDatabases;
3637
use MongoDB\Operation\Watch;
38+
use Throwable;
3739
use function is_array;
40+
use function is_string;
3841

3942
class Client
4043
{
@@ -51,6 +54,12 @@ class Client
5154
/** @var integer */
5255
private static $wireVersionForWritableCommandWriteConcern = 5;
5356

57+
/** @var string */
58+
private static $handshakeSeparator = ' / ';
59+
60+
/** @var string|null */
61+
private static $version;
62+
5463
/** @var Manager */
5564
private $manager;
5665

@@ -108,6 +117,8 @@ public function __construct($uri = 'mongodb://127.0.0.1/', array $uriOptions = [
108117
}
109118
}
110119

120+
$driverOptions['driver'] = $this->mergeDriverInfo($driverOptions['driver'] ?? []);
121+
111122
$this->uri = (string) $uri;
112123
$this->typeMap = $driverOptions['typeMap'] ?? null;
113124

@@ -354,4 +365,47 @@ public function watch(array $pipeline = [], array $options = [])
354365

355366
return $operation->execute($server);
356367
}
368+
369+
private static function getVersion() : string
370+
{
371+
if (self::$version === null) {
372+
try {
373+
self::$version = PrettyVersions::getVersion('mongodb/mongodb')->getPrettyVersion();
374+
} catch (Throwable $t) {
375+
return 'unknown';
376+
}
377+
}
378+
379+
return self::$version;
380+
}
381+
382+
private function mergeDriverInfo(array $driver) : array
383+
{
384+
$mergedDriver = [
385+
'name' => 'PHPLIB',
386+
'version' => self::getVersion(),
387+
];
388+
389+
if (isset($driver['name'])) {
390+
if (! is_string($driver['name'])) {
391+
throw InvalidArgumentException::invalidType('"name" handshake option', $driver['name'], 'string');
392+
}
393+
394+
$mergedDriver['name'] .= self::$handshakeSeparator . $driver['name'];
395+
}
396+
397+
if (isset($driver['version'])) {
398+
if (! is_string($driver['version'])) {
399+
throw InvalidArgumentException::invalidType('"version" handshake option', $driver['version'], 'string');
400+
}
401+
402+
$mergedDriver['version'] .= self::$handshakeSeparator . $driver['version'];
403+
}
404+
405+
if (isset($driver['platform'])) {
406+
$mergedDriver['platform'] = $driver['platform'];
407+
}
408+
409+
return $mergedDriver;
410+
}
357411
}

tests/ClientTest.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use MongoDB\Client;
66
use MongoDB\Driver\ClientEncryption;
7+
use MongoDB\Driver\Exception\InvalidArgumentException as DriverInvalidArgumentException;
78
use MongoDB\Driver\ReadConcern;
89
use MongoDB\Driver\ReadPreference;
910
use MongoDB\Driver\WriteConcern;
@@ -38,9 +39,9 @@ public function testConstructorAutoEncryptionOpts()
3839
/**
3940
* @dataProvider provideInvalidConstructorDriverOptions
4041
*/
41-
public function testConstructorDriverOptionTypeChecks(array $driverOptions)
42+
public function testConstructorDriverOptionTypeChecks(array $driverOptions, string $exception = InvalidArgumentException::class)
4243
{
43-
$this->expectException(InvalidArgumentException::class);
44+
$this->expectException($exception);
4445
new Client(static::getUri(), [], $driverOptions);
4546
}
4647

@@ -54,6 +55,21 @@ public function provideInvalidConstructorDriverOptions()
5455

5556
$options[][] = ['autoEncryption' => ['keyVaultClient' => 'foo']];
5657

58+
foreach ($this->getInvalidStringValues() as $value) {
59+
$options[][] = ['driver' => ['name' => $value]];
60+
}
61+
62+
foreach ($this->getInvalidStringValues() as $value) {
63+
$options[][] = ['driver' => ['version' => $value]];
64+
}
65+
66+
foreach ($this->getInvalidStringValues() as $value) {
67+
$options[] = [
68+
'driverOptions' => ['driver' => ['platform' => $value]],
69+
'exception' => DriverInvalidArgumentException::class,
70+
];
71+
}
72+
5773
return $options;
5874
}
5975

0 commit comments

Comments
 (0)