Skip to content

Commit 124bb58

Browse files
authored
Merge branch 'master' into PHPLIB-881
2 parents a6b9d99 + bf36331 commit 124bb58

File tree

159 files changed

+1538
-1692
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

159 files changed

+1538
-1692
lines changed

.github/workflows/static-analysis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,6 @@ jobs:
6565

6666
- name: "Run Psalm"
6767
run: "vendor/bin/psalm --show-info=false --stats --output-format=github --threads=$(nproc)"
68+
69+
- name: "Run Rector"
70+
run: "vendor/bin/rector --ansi --dry-run"

CONTRIBUTING.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,17 @@ possible it can be added to the baseline using `set-baseline`:
151151
$ vendor/bin/psalm --set-baseline=psalm-baseline.xml
152152
```
153153

154+
## Automatic code refactoring
155+
156+
The library uses [rector](https://getrector.com/) to refactor the code for new features.
157+
To run automatic refactoring, use the `rector` command:
158+
159+
```
160+
$ vendor/bin/rector
161+
```
162+
163+
New rules can be added to the `rector.php` configuration file.
164+
154165
## Documentation
155166

156167
Documentation for the library lives in the `docs/` directory and is built with

composer.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@
1818
"symfony/polyfill-php80": "^1.27"
1919
},
2020
"require-dev": {
21-
"squizlabs/php_codesniffer": "^3.7",
2221
"doctrine/coding-standard": "^11.1",
22+
"rector/rector": "^0.16.0",
23+
"squizlabs/php_codesniffer": "^3.7",
2324
"symfony/phpunit-bridge": "^5.2",
2425
"vimeo/psalm": "^4.28"
2526
},
@@ -39,6 +40,7 @@
3940
"config": {
4041
"allow-plugins": {
4142
"dealerdirect/phpcodesniffer-composer-installer": true
42-
}
43+
},
44+
"sort-packages": true
4345
}
4446
}

examples/aggregate.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use function MongoDB\BSON\fromPHP;
1212
use function MongoDB\BSON\toRelaxedExtendedJSON;
1313
use function printf;
14-
use function rand;
14+
use function random_int;
1515

1616
require __DIR__ . '/../vendor/autoload.php';
1717

@@ -28,7 +28,7 @@ function toJSON(object $document): string
2828
$documents = [];
2929

3030
for ($i = 0; $i < 100; $i++) {
31-
$documents[] = ['randomValue' => rand(0, 1000)];
31+
$documents[] = ['randomValue' => random_int(0, 1000)];
3232
}
3333

3434
$collection->insertMany($documents);

phpcs.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
<file>examples</file>
1414
<file>tests</file>
1515
<file>tools</file>
16+
<file>rector.php</file>
1617

1718
<!-- Target minimum supported PHP version -->
1819
<config name="php_version" value="70200"/>

psalm-baseline.xml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,13 @@
274274
<MixedArgument occurrences="1">
275275
<code>$fieldName</code>
276276
</MixedArgument>
277-
<MixedAssignment occurrences="1">
277+
<MixedAssignment occurrences="2">
278278
<code>$fieldName</code>
279+
<code>$type</code>
279280
</MixedAssignment>
281+
<MixedOperand occurrences="1">
282+
<code>$type</code>
283+
</MixedOperand>
280284
<MixedReturnStatement occurrences="1">
281285
<code>$this-&gt;index['name']</code>
282286
</MixedReturnStatement>
@@ -774,10 +778,9 @@
774778
<code>$typeMap['fieldPaths'][$fieldPath]</code>
775779
<code>$typeMap['fieldPaths'][substr($fieldPath, 0, -2)]</code>
776780
</MixedArrayAssignment>
777-
<MixedAssignment occurrences="6">
781+
<MixedAssignment occurrences="5">
778782
<code>$element[$key]</code>
779783
<code>$type</code>
780-
<code>$type</code>
781784
<code>$typeMap['fieldPaths'][$fieldPath . '.' . $existingFieldPath]</code>
782785
<code>$typeMap['fieldPaths'][$fieldPath]</code>
783786
<code>$value</code>

rector.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
use Rector\Config\RectorConfig;
4+
use Rector\DeadCode\Rector\ClassLike\RemoveAnnotationRector;
5+
use Rector\Php56\Rector\FunctionLike\AddDefaultValueForUndefinedVariableRector;
6+
use Rector\Php71\Rector\FuncCall\RemoveExtraParametersRector;
7+
use Rector\Set\ValueObject\LevelSetList;
8+
9+
return static function (RectorConfig $rectorConfig): void {
10+
$rectorConfig->paths([
11+
__DIR__ . '/examples',
12+
__DIR__ . '/src',
13+
__DIR__ . '/tests',
14+
__DIR__ . '/tools',
15+
]);
16+
17+
// Modernize code
18+
$rectorConfig->sets([LevelSetList::UP_TO_PHP_72]);
19+
20+
$rectorConfig->skip([
21+
// Falsely detect unassigned variables in code paths stopped by PHPUnit\Framework\Assert::markTestSkipped()
22+
AddDefaultValueForUndefinedVariableRector::class => [
23+
__DIR__ . '/tests/',
24+
],
25+
// @see https://github.com/phpstan/phpstan-src/pull/2429
26+
RemoveExtraParametersRector::class => [
27+
__DIR__ . '/src/Operation/',
28+
],
29+
]);
30+
31+
// All classes are public API by default, unless marked with @internal.
32+
$rectorConfig->ruleWithConfiguration(RemoveAnnotationRector::class, ['api']);
33+
};

src/ChangeStream.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,10 @@
3333
/**
3434
* Iterator for a change stream.
3535
*
36-
* @psalm-type ResumeCallable = callable(array|object|null, bool): ChangeStreamIterator
37-
*
38-
* @api
3936
* @see \MongoDB\Collection::watch()
4037
* @see https://mongodb.com/docs/manual/reference/method/db.watch/#mongodb-method-db.watch
38+
*
39+
* @psalm-type ResumeCallable = callable(array|object|null, bool): ChangeStreamIterator
4140
*/
4241
class ChangeStream implements Iterator
4342
{

src/Collection.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ public function mapReduce(JavascriptInterface $map, JavascriptInterface $reduce,
968968

969969
// Check if the out option is inline because we will want to coerce a primary read preference if not
970970
if ($hasOutputCollection) {
971-
$options['readPreference'] = new ReadPreference(ReadPreference::RP_PRIMARY);
971+
$options['readPreference'] = new ReadPreference(ReadPreference::PRIMARY);
972972
}
973973

974974
$server = select_server($this->manager, $options);

src/Database.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ public function createCollection(string $collectionName, array $options = [])
313313
* @return array A tuple containing the command result document from creating the collection and the modified "encryptedFields" option
314314
* @throws InvalidArgumentException for parameter/option parsing errors
315315
* @throws CreateEncryptedCollectionException for any errors creating data keys or creating the collection
316+
* @throws UnsupportedException if Queryable Encryption is not supported by the selected server
316317
*/
317318
public function createEncryptedCollection(string $collectionName, ClientEncryption $clientEncryption, string $kmsProvider, ?array $masterKey, array $options): array
318319
{

src/GridFS/Bucket.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@
5959
/**
6060
* Bucket provides a public API for interacting with the GridFS files and chunks
6161
* collections.
62-
*
63-
* @api
6462
*/
6563
class Bucket
6664
{

src/GridFS/CollectionWrapper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ private function indexKeysMatch(array $expectedKeys, array $actualKeys): bool
359359
private function isFilesCollectionEmpty(): bool
360360
{
361361
return null === $this->filesCollection->findOne([], [
362-
'readPreference' => new ReadPreference(ReadPreference::RP_PRIMARY),
362+
'readPreference' => new ReadPreference(ReadPreference::PRIMARY),
363363
'projection' => ['_id' => 1],
364364
'typeMap' => [],
365365
]);

src/MapReduceResult.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
* output method (e.g. inline, collection) via the IteratorAggregate interface.
3232
* It also provides access to command statistics.
3333
*
34-
* @api
3534
* @see \MongoDB\Collection::mapReduce()
3635
* @see https://mongodb.com/docs/manual/reference/command/mapReduce/
3736
*/

src/Model/BSONArray.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131
*
3232
* The internal data will be filtered through array_values() during BSON
3333
* serialization to ensure that it becomes a BSON array.
34-
*
35-
* @api
3634
*/
3735
class BSONArray extends ArrayObject implements JsonSerializable, Serializable, Unserializable
3836
{

src/Model/BSONDocument.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
*
3131
* The internal data will be cast to an object during BSON serialization to
3232
* ensure that it becomes a BSON document.
33-
*
34-
* @api
3533
*/
3634
class BSONDocument extends ArrayObject implements JsonSerializable, Serializable, Unserializable
3735
{

src/Model/CollectionInfo.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
* command or, for legacy servers, queries on the "system.namespaces"
3131
* collection. It provides methods to access options for the collection.
3232
*
33-
* @api
3433
* @see \MongoDB\Database::listCollections()
3534
* @see https://github.com/mongodb/specifications/blob/master/source/enumerate-collections.rst
3635
*/

src/Model/CollectionInfoIterator.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
*
2626
* This iterator is used for enumerating collections in a database.
2727
*
28-
* @api
2928
* @see \MongoDB\Database::listCollections()
3029
*/
3130
interface CollectionInfoIterator extends Iterator

src/Model/DatabaseInfo.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
* This class models the database information returned by the listDatabases
3030
* command. It provides methods to access common database properties.
3131
*
32-
* @api
3332
* @see \MongoDB\Client::listDatabases()
3433
* @see https://mongodb.com/docs/manual/reference/command/listDatabases/
3534
*/

src/Model/DatabaseInfoIterator.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
*
2626
* This iterator is used for enumerating databases on a server.
2727
*
28-
* @api
2928
* @see \MongoDB\Client::listDatabases()
3029
*/
3130
interface DatabaseInfoIterator extends Iterator

src/Model/IndexInfo.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
* For information on keys and index options, see the referenced
3535
* db.collection.createIndex() documentation.
3636
*
37-
* @api
3837
* @see \MongoDB\Collection::listIndexes()
3938
* @see https://github.com/mongodb/specifications/blob/master/source/enumerate-indexes.rst
4039
* @see https://mongodb.com/docs/manual/reference/method/db.collection.createIndex/

src/Model/IndexInfoIterator.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
*
2626
* This iterator is used for enumerating indexes in a collection.
2727
*
28-
* @api
2928
* @see \MongoDB\Collection::listIndexes()
3029
*/
3130
interface IndexInfoIterator extends Iterator

src/Model/IndexInput.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
use function is_int;
2626
use function is_object;
2727
use function is_string;
28-
use function MongoDB\generate_index_name;
28+
use function MongoDB\document_to_array;
2929
use function sprintf;
3030

3131
/**
@@ -64,7 +64,7 @@ public function __construct(array $index)
6464
}
6565

6666
if (! isset($index['name'])) {
67-
$index['name'] = generate_index_name($index['key']);
67+
$index['name'] = $this->generateIndexName($index['key']);
6868
}
6969

7070
if (! is_string($index['name'])) {
@@ -92,4 +92,24 @@ public function bsonSerialize(): array
9292
{
9393
return $this->index;
9494
}
95+
96+
/**
97+
* Generate an index name from a key specification.
98+
*
99+
* @param array|object $document Document containing fields mapped to values,
100+
* which denote order or an index type
101+
* @throws InvalidArgumentException if $document is not an array or object
102+
*/
103+
private function generateIndexName($document): string
104+
{
105+
$document = document_to_array($document);
106+
107+
$name = '';
108+
109+
foreach ($document as $field => $type) {
110+
$name .= ($name !== '' ? '_' : '') . $field . '_' . $type;
111+
}
112+
113+
return $name;
114+
}
95115
}

src/Operation/Aggregate.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
/**
4545
* Operation for the aggregate command.
4646
*
47-
* @api
4847
* @see \MongoDB\Collection::aggregate()
4948
* @see https://mongodb.com/docs/manual/reference/command/aggregate/
5049
*/

src/Operation/BulkWrite.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
/**
4141
* Operation for executing multiple write operations.
4242
*
43-
* @api
4443
* @see \MongoDB\Collection::bulkWrite()
4544
*/
4645
class BulkWrite implements Executable

src/Operation/Count.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
/**
3838
* Operation for the count command.
3939
*
40-
* @api
4140
* @see \MongoDB\Collection::count()
4241
* @see https://mongodb.com/docs/manual/reference/command/count/
4342
*/

src/Operation/CountDocuments.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
/**
3737
* Operation for obtaining an exact count of documents in a collection
3838
*
39-
* @api
4039
* @see \MongoDB\Collection::countDocuments()
4140
* @see https://github.com/mongodb/specifications/blob/master/source/crud/crud.rst#countdocuments
4241
*/

src/Operation/CreateCollection.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
/**
3939
* Operation for the create command.
4040
*
41-
* @api
4241
* @see \MongoDB\Database::createCollection()
4342
* @see https://mongodb.com/docs/manual/reference/command/create/
4443
*/

src/Operation/CreateEncryptedCollection.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@
1717

1818
namespace MongoDB\Operation;
1919

20-
// phpcs:ignore SlevomatCodingStandard.Namespaces.UnusedUses.UnusedUse
2120
use MongoDB\BSON\Binary;
2221
use MongoDB\Driver\ClientEncryption;
2322
use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException;
2423
use MongoDB\Driver\Server;
2524
use MongoDB\Exception\InvalidArgumentException;
25+
use MongoDB\Exception\UnsupportedException;
2626

2727
use function array_key_exists;
2828
use function is_array;
2929
use function is_object;
30+
use function MongoDB\server_supports_feature;
3031

3132
/**
3233
* Create an encrypted collection.
@@ -45,6 +46,9 @@
4546
*/
4647
class CreateEncryptedCollection implements Executable
4748
{
49+
/** @var integer */
50+
private static $wireVersionForQueryableEncryptionV2 = 21;
51+
4852
/** @var CreateCollection */
4953
private $createCollection;
5054

@@ -82,13 +86,12 @@ public function __construct(string $databaseName, string $collectionName, array
8286

8387
$this->createCollection = new CreateCollection($databaseName, $collectionName, $options);
8488

85-
/** @psalm-var array{eccCollection?: ?string, ecocCollection?: ?string, escCollection?: ?string} */
89+
/** @psalm-var array{ecocCollection?: ?string, escCollection?: ?string} */
8690
$encryptedFields = (array) $options['encryptedFields'];
8791
$enxcolOptions = ['clusteredIndex' => ['key' => ['_id' => 1], 'unique' => true]];
8892

8993
$this->createMetadataCollections = [
9094
new CreateCollection($databaseName, $encryptedFields['escCollection'] ?? 'enxcol_.' . $collectionName . '.esc', $enxcolOptions),
91-
new CreateCollection($databaseName, $encryptedFields['eccCollection'] ?? 'enxcol_.' . $collectionName . '.ecc', $enxcolOptions),
9295
new CreateCollection($databaseName, $encryptedFields['ecocCollection'] ?? 'enxcol_.' . $collectionName . '.ecoc', $enxcolOptions),
9396
];
9497

@@ -151,9 +154,14 @@ public function createDataKeys(ClientEncryption $clientEncryption, string $kmsPr
151154
* @see Executable::execute()
152155
* @return array|object Command result document from creating the encrypted collection
153156
* @throws DriverRuntimeException for other driver errors (e.g. connection errors)
157+
* @throws UnsupportedException if the server does not support Queryable Encryption
154158
*/
155159
public function execute(Server $server)
156160
{
161+
if (! server_supports_feature($server, self::$wireVersionForQueryableEncryptionV2)) {
162+
throw new UnsupportedException('Driver support of Queryable Encryption is incompatible with server. Upgrade server to use Queryable Encryption.');
163+
}
164+
157165
foreach ($this->createMetadataCollections as $createMetadataCollection) {
158166
$createMetadataCollection->execute($server);
159167
}

0 commit comments

Comments
 (0)