diff --git a/.github/workflows/composer-lint.yml b/.github/workflows/composer-lint.yml
index 08bbce8a..4c1dabd1 100644
--- a/.github/workflows/composer-lint.yml
+++ b/.github/workflows/composer-lint.yml
@@ -10,6 +10,7 @@ on:
push:
branches:
- "*.x"
+ - "feature/*"
paths:
- "composer.json"
diff --git a/config/command.php b/config/command.php
index 0a7e12d0..9b064fa3 100644
--- a/config/command.php
+++ b/config/command.php
@@ -6,6 +6,7 @@
use Doctrine\Bundle\MongoDBBundle\Command\ConnectionDiagnosticCommand;
use Doctrine\Bundle\MongoDBBundle\Command\CreateSchemaDoctrineODMCommand;
use Doctrine\Bundle\MongoDBBundle\Command\DropSchemaDoctrineODMCommand;
+use Doctrine\Bundle\MongoDBBundle\Command\DumpEncryptedFieldsMapCommand;
use Doctrine\Bundle\MongoDBBundle\Command\GenerateHydratorsDoctrineODMCommand;
use Doctrine\Bundle\MongoDBBundle\Command\GenerateProxiesDoctrineODMCommand;
use Doctrine\Bundle\MongoDBBundle\Command\InfoDoctrineODMCommand;
@@ -27,6 +28,10 @@
->tag('console.command', ['command' => 'doctrine:mongodb:connection:diagnostic'])
->args([tagged_locator('doctrine_mongodb.connection_diagnostic', 'name')])
+ ->set('doctrine_mongodb.odm.command.dump_encrypted_fields_map', DumpEncryptedFieldsMapCommand::class)
+ ->tag('console.command', ['command' => 'doctrine:mongodb:dump-encrypted-fields-map'])
+ ->args([tagged_locator('doctrine_mongodb.odm.document_manager', 'name')])
+
->set('doctrine_mongodb.odm.command.create_schema', CreateSchemaDoctrineODMCommand::class)
->tag('console.command', ['command' => 'doctrine:mongodb:schema:create'])
diff --git a/docs/encryption.rst b/docs/encryption.rst
index cbf4c47e..5be85afd 100644
--- a/docs/encryption.rst
+++ b/docs/encryption.rst
@@ -76,10 +76,23 @@ Example of configuration for AWS
key: "arn:aws:kms:eu-west-1:123456789012:key/abcd1234-12ab-34cd-56ef-1234567890ab"
-Queryable Encryption (QE)
--------------------------
+Encrypted Fields Map
+--------------------
-Queryable Encryption (QE) allows you to run queries on encrypted fields. To use QE, you may need to provide an ``encryptedFieldsMap`` or use a schema map, depending on your driver and use case.
+You can configure which fields are encrypted in each collection by specifying the
+``autoEncryption.encryptedFieldsMap`` option in the connection configuration.
+This setting is **recommended** for improved security and performance.
+
+- If the connection ``encryptedFieldsMap`` object contains a key for the specified
+ collection, the client uses that object to perform automatic Queryable Encryption,
+ rather than using the remote schema. At minimum, the local rules must encrypt
+ all fields that the remote schema does.
+
+- If the connection ``encryptedFieldsMap`` object doesn't contain a key for the
+ specified collection, the client downloads the server-side remote schema for
+ the collection and uses it instead.
+
+For more details, see the official MongoDB documentation: `Encrypted Fields and Enabled Queries `_.
.. tabs::
@@ -133,6 +146,51 @@ Queryable Encryption (QE) allows you to run queries on encrypted fields. To use
]);
};
+Automatic Encryption Shared Library
+-----------------------------------
+
+To use automatic encryption, the MongoDB PHP driver requires the `Automatic Encryption Shared Library`_.
+
+If the driver is not able to find the library, you can specify its path using the ``cryptSharedLibPath`` extra option in your connection configuration.
+
+.. tabs::
+
+ .. group-tab:: YAML
+
+ .. code-block:: yaml
+
+ doctrine_mongodb:
+ connections:
+ default:
+ autoEncryption:
+ extraOptions:
+ cryptSharedLibPath: '%kernel.project_dir%/bin/mongo_crypt_v1.so'
+
+ .. group-tab:: XML
+
+ .. code-block:: xml
+
+
+
+
+
+
+
+ .. group-tab:: PHP
+
+ .. code-block:: php
+
+ use Symfony\Config\DoctrineMongodbConfig;
+
+ return static function (DoctrineMongodbConfig $config): void {
+ $config->connection('default')
+ ->autoEncryption([
+ 'extraOptions' => [
+ 'cryptSharedLibPath' => '%kernel.project_dir%/bin/mongo_crypt_v1.so',
+ ],
+ ]);
+ };
+
TLS Options
-----------
@@ -221,3 +279,5 @@ Further Reading
- `MongoDB CSFLE documentation `_
- `MongoDB PHP driver Manager::__construct `_
- :doc:`config`
+
+.. _`Automatic Encryption Shared Library`: https://www.mongodb.com/docs/manual/core/queryable-encryption/install-library/
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index ef9043d8..8a0884eb 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -36,12 +36,6 @@ parameters:
count: 1
path: src/CacheWarmer/ProxyCacheWarmer.php
- -
- message: '#^Method Doctrine\\Bundle\\MongoDBBundle\\CacheWarmer\\ProxyCacheWarmer\:\:getClassesForProxyGeneration\(\) return type with generic class Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata does not specify its types\: T$#'
- identifier: missingType.generics
- count: 1
- path: src/CacheWarmer/ProxyCacheWarmer.php
-
-
message: '#^Parameter \#1 \$application of static method Doctrine\\Bundle\\MongoDBBundle\\Command\\DoctrineODMCommand\:\:setApplicationDocumentManager\(\) expects Symfony\\Bundle\\FrameworkBundle\\Console\\Application, Symfony\\Component\\Console\\Application\|null given\.$#'
identifier: argument.type
@@ -120,42 +114,12 @@ parameters:
count: 1
path: src/Command/UpdateSchemaDoctrineODMCommand.php
- -
- message: '#^Expression on left side of \?\? is not nullable\.$#'
- identifier: nullCoalesce.expr
- count: 1
- path: src/DataCollector/ConnectionDiagnostic.php
-
-
message: '#^Method Doctrine\\Bundle\\MongoDBBundle\\DataCollector\\ConnectionDiagnostic\:\:__construct\(\) has parameter \$driverOptions with no value type specified in iterable type array\.$#'
identifier: missingType.iterableValue
count: 1
path: src/DataCollector/ConnectionDiagnostic.php
- -
- message: '#^Method Doctrine\\Bundle\\MongoDBBundle\\DataCollector\\ConnectionDiagnostic\:\:getAutoEncryptionInfo\(\) return type has no value type specified in iterable type array\.$#'
- identifier: missingType.iterableValue
- count: 1
- path: src/DataCollector/ConnectionDiagnostic.php
-
- -
- message: '#^Method Doctrine\\Bundle\\MongoDBBundle\\DataCollector\\ConnectionDiagnostic\:\:getPhpExtensionInfo\(\) return type has no value type specified in iterable type array\.$#'
- identifier: missingType.iterableValue
- count: 1
- path: src/DataCollector/ConnectionDiagnostic.php
-
- -
- message: '#^Method Doctrine\\Bundle\\MongoDBBundle\\DataCollector\\ConnectionDiagnostic\:\:getServerInfo\(\) return type has no value type specified in iterable type array\.$#'
- identifier: missingType.iterableValue
- count: 1
- path: src/DataCollector/ConnectionDiagnostic.php
-
- -
- message: '#^Unreachable statement \- code above always terminates\.$#'
- identifier: deadCode.unreachable
- count: 1
- path: src/DataCollector/ConnectionDiagnostic.php
-
-
message: '#^Cannot cast array\|bool\|float\|int\|string\|UnitEnum\|null to string\.$#'
identifier: cast.string
@@ -372,12 +336,6 @@ parameters:
count: 1
path: src/Form/ChoiceList/MongoDBQueryBuilderLoader.php
- -
- message: '#^Method Doctrine\\Bundle\\MongoDBBundle\\Form\\DoctrineMongoDBTypeGuesser\:\:getMetadata\(\) return type with generic class Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata does not specify its types\: T$#'
- identifier: missingType.generics
- count: 1
- path: src/Form/DoctrineMongoDBTypeGuesser.php
-
-
message: '#^Method Doctrine\\Bundle\\MongoDBBundle\\Form\\DoctrineMongoDBTypeGuesser\:\:getMetadata\(\) should return array\{Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata, string\}\|null but returns array\{Doctrine\\Persistence\\Mapping\\ClassMetadata\