Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f15acf4
Disable use-next-minor-as-default-branch in release job (#2864)
GromNaN Oct 21, 2025
ae9ec3d
Cleanup group annotations in tests and useless test (#2865)
GromNaN Oct 22, 2025
63f6593
Add support for PHP 8.4 Lazy Objects with configuration flag (#2840)
GromNaN Oct 22, 2025
2116b3a
Move source files into src/ directory
GromNaN Oct 22, 2025
6f5fc0d
Bump doctrine/.github from 12.0.0 to 12.1.0 (#2869)
dependabot[bot] Oct 23, 2025
00b8df9
Update config files for new directory structure
GromNaN Oct 23, 2025
bbf9531
Merge pull request #2866 from GromNaN/directory-structure
GromNaN Oct 24, 2025
7c5dbc1
Fix binary UUID hydrator (#2868)
alcaeus Oct 24, 2025
7dda0b7
Improve detection of the type from a PHP variable (#2814)
GromNaN Oct 24, 2025
4d22016
Fix binary vector types and conversion in `$vectorSearch` stage (#2871)
GromNaN Oct 24, 2025
020b3a1
Merge remote-tracking branch 'upstream/2.14.x' into 2.13.x-merge-up-i…
GromNaN Oct 24, 2025
4a5a067
Merge release 2.13.1 into 2.14.x (#2872)
GromNaN Oct 24, 2025
383c999
Bump actions/upload-artifact from 4 to 5
dependabot[bot] Oct 27, 2025
3e178fa
Merge pull request #2876 from doctrine/dependabot/github_actions/acti…
greg0ire Oct 27, 2025
47e71e3
Avoid warning Undefined array key "type" in ClassMetadata (#2875)
GromNaN Oct 27, 2025
29d8212
Merge branch '2.14.x' into 2.13.x-merge-up-into-2.14.x_NNKby2Yo
GromNaN Oct 27, 2025
b49d449
Merge release 2.13.2 into 2.14.x (#2878)
GromNaN Oct 27, 2025
2150ce8
Make PHPUnit more strict and verbose, and fix issues (#2873)
GromNaN Oct 27, 2025
2f1298c
Update .doctrine-project.json for 2.14.0 (#2879)
GromNaN Oct 27, 2025
aa5df38
Merge branch '3.0.x' into 2.14.x-merge-up-into-3.0.x_ZzfE4Yq6
GromNaN Oct 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 9 additions & 4 deletions .doctrine-project.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,21 @@
"docsSlug": "doctrine-mongodb-odm",
"versions": [
{
"name": "2.14",
"branchName": "2.14.x",
"name": "2.15",
"branchName": "2.15.x",
"slug": "latest",
"upcoming": true
},
{
"name": "2.14",
"branchName": "2.14.x",
"slug": "2.14",
"current": true
},
{
"name": "2.13",
"branchName": "2.13.x",
"slug": "2.13",
"current": true
"maintained": false
},
{
"name": "2.12",
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/atlas-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,5 @@ jobs:
run: "vendor/bin/phpunit --group atlas"
env:
DOCTRINE_MONGODB_SERVER: "mongodb://127.0.0.1:27017/?directConnection=true"
USE_LAZY_GHOST_OBJECTS: ${{ matrix.proxy == 'lazy-ghost' && '1' || '0' }}
USE_LAZY_GHOST_OBJECT: ${{ matrix.proxy == 'lazy-ghost' && '1' || '0' }}
USE_NATIVE_LAZY_OBJECT: ${{ matrix.proxy == 'native' && '1' || '0' }}
2 changes: 1 addition & 1 deletion .github/workflows/coding-standards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ on:
jobs:
coding-standards:
name: "Coding Standards"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@12.0.0"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@12.1.0"
12 changes: 10 additions & 2 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,13 @@ jobs:
dependencies: "highest"
symfony-version: "stable"
proxy: "proxy-manager"
# Test with Native Lazy Objects
- php-version: "8.4"
mongodb-version: "8.0"
driver-version: "stable"
dependencies: "highest"
symfony-version: "stable"
proxy: "native"
# Test with extension 1.21
- topology: "server"
php-version: "8.2"
Expand Down Expand Up @@ -159,8 +166,9 @@ jobs:
topology: ${{ matrix.topology }}

- name: "Run PHPUnit"
run: "vendor/bin/phpunit --exclude-group=atlas"
run: "vendor/bin/phpunit --exclude-group=atlas ${{ matrix.dependencies == 'lowest' && '--do-not-fail-on-deprecation --do-not-fail-on-warning --do-not-fail-on-notice' || '' }}"
env:
DOCTRINE_MONGODB_SERVER: ${{ steps.setup-mongodb.outputs.cluster-uri }}
USE_LAZY_GHOST_OBJECTS: ${{ matrix.proxy == 'lazy-ghost' && '1' || '0' }}"
USE_LAZY_GHOST_OBJECT: ${{ matrix.proxy == 'lazy-ghost' && '1' || '0' }}
USE_NATIVE_LAZY_OBJECT: ${{ matrix.proxy == 'native' && '1' || '0' }}
CRYPT_SHARED_LIB_PATH: ${{ steps.setup-mongodb.outputs.crypt-shared-lib-path }}
2 changes: 1 addition & 1 deletion .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ on:
jobs:
documentation:
name: "Generate documentation"
uses: "doctrine/.github/.github/workflows/documentation.yml@12.0.0"
uses: "doctrine/.github/.github/workflows/documentation.yml@12.1.0"
2 changes: 1 addition & 1 deletion .github/workflows/performance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
uses: "ramsey/composer-install@v3"

- name: "Upload composer.lock as build artifact"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: composer.lock
path: composer.lock
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-on-milestone-closed.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
jobs:
release:
name: "Git tag, release & create merge-up PR"
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@12.0.0"
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@12.1.0"
with:
use-next-minor-as-default-branch: true
secrets:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/static-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
uses: "ramsey/composer-install@v3"

- name: "Upload composer.lock as build artifact"
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v5
with:
name: "composer-lock-static-analysis-phpstan"
path: composer.lock
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/website-schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ on:
jobs:
json-validate:
name: "Validate JSON schema"
uses: "doctrine/.github/.github/workflows/website-schema.yml@12.0.0"
uses: "doctrine/.github/.github/workflows/website-schema.yml@12.1.0"
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,17 @@
"ext-bcmath": "Decimal128 type support"
},
"autoload": {
"psr-4": { "Doctrine\\ODM\\MongoDB\\": "lib/Doctrine/ODM/MongoDB" }
"psr-4": { "Doctrine\\ODM\\MongoDB\\": "src" }
},
"autoload-dev": {
"psr-4": {
"Doctrine\\ODM\\MongoDB\\Benchmark\\": "benchmark",
"Doctrine\\ODM\\MongoDB\\Tests\\": "tests/Doctrine/ODM/MongoDB/Tests",
"Doctrine\\ODM\\MongoDB\\Tests\\": "tests/Tests",
"Documentation\\": "tests/Documentation",
"Documents\\": "tests/Documents",
"Documents84\\": "tests/Documents84",
"Stubs\\": "tests/Stubs",
"TestDocuments\\" :"tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures"
"TestDocuments\\" :"tests/Tests/Mapping/Driver/fixtures"
}
},
"config": {
Expand Down
85 changes: 85 additions & 0 deletions docs/en/reference/custom-mapping-types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ In order to create a new mapping type you need to subclass
``Doctrine\ODM\MongoDB\Types\Type`` and implement/override
the methods.

Date Example: Mapping DateTimeImmutable with Timezone
-----------------------------------------------------

The following example defines a custom type that stores ``DateTimeInterface``
instances as an embedded document containing a BSON date and accompanying
timezone string. Those same embedded documents are then be translated back into
Expand All @@ -32,6 +35,7 @@ a ``DateTimeImmutable`` when the data is read from the database.
// This trait provides default closureToPHP used during data hydration
use ClosureToPHP;

/** @param array{utc: UTCDateTime, tz: string} $value */
public function convertToPHPValue($value): DateTimeImmutable
{
if (!isset($value['utc'], $value['tz'])) {
Expand All @@ -46,6 +50,7 @@ a ``DateTimeImmutable`` when the data is read from the database.
return DateTimeImmutable::createFromMutable($dateTime);
}

/** @return array{utc: UTCDateTime, tz: string} */
public function convertToDatabaseValue($value): array
{
if (!$value instanceof DateTimeImmutable) {
Expand Down Expand Up @@ -115,5 +120,85 @@ specify a unique name for the mapping type and map that to the corresponding

<field field-name="field" type="date_with_timezone" />

Custom Type Example: Mapping a Money Value Object
-------------------------------------------------

You can create a custom mapping type for your own value objects or classes. For
example, to map a ``Money`` value object using the `moneyphp/money library`_, you can
implement a type that converts between this class and a BSON embedded document format.

This approach works for any custom class by adapting the conversion logic to your needs.

Example Implementation (using ``Money\Money``)::

.. code-block:: php

<?php

namespace App\MongoDB\Types;

use Doctrine\ODM\MongoDB\Types\ClosureToPHP;
use Doctrine\ODM\MongoDB\Types\Type;
use InvalidArgumentException;
use Money\Money;
use Money\Currency;

final class MoneyType extends Type
{
// This trait provides a default closureToPHP used during data hydration
use ClosureToPHP;

public function convertToPHPValue(mixed $value): ?Money
{
if (null === $value) {
return null;
}

if (is_array($value) && isset($value['amount'], $value['currency'])) {
return new Money($value['amount'], new Currency($value['currency']));
}

throw new InvalidArgumentException(sprintf('Could not convert database value from "%s" to %s', get_debug_type($value), Money::class));
}

public function convertToDatabaseValue(mixed $value): ?array
{
if (null === $value) {
return null;
}

if ($value instanceof Money) {
return [
'amount' => $value->getAmount(),
'currency' => $value->getCurrency()->getCode(),
];
}

throw new InvalidArgumentException(sprintf('Could not convert database value from "%s" to array', get_debug_type($value)));
}
}

Register the type in your bootstrap code::

.. code-block:: php

Type::addType(Money::class, App\MongoDB\Types\MoneyType::class);

By using the |FQCN| of the value object class as the type name, the type is
automatically used when encountering a property of that class. This means you
can omit the ``type`` option when defining the field mapping::

.. code-block:: php

#[Field]
public ?\Money\Money $price;

.. note::

This implementation of ``MoneyType`` is kept simple for illustration purposes
and does not handle all edge cases, but it should give you a good starting
point for implementing your own custom types.

.. _`moneyphp/money library`: https://github.com/moneyphp/money
.. |FQCN| raw:: html
<abbr title="Fully-Qualified Class Name">FQCN</abbr>
32 changes: 16 additions & 16 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<config name="php_version" value="80100"/>

<file>benchmark</file>
<file>lib</file>
<file>src</file>
<file>tests</file>
<file>tools</file>

Expand Down Expand Up @@ -50,46 +50,46 @@
</rule>

<rule ref="PSR1.Classes.ClassDeclaration.MissingNamespace">
<exclude-pattern>tests/Doctrine/ODM/MongoDB/Tests/Mapping/Documents/GlobalNamespaceDocument.php</exclude-pattern>
<exclude-pattern>tests/Tests/Mapping/Documents/GlobalNamespaceDocument.php</exclude-pattern>
</rule>

<rule ref="Squiz.Classes.ValidClassName.NotPascalCase">
<exclude-pattern>tests/Doctrine/ODM/MongoDB/Tests/Mapping/Documents/GlobalNamespaceDocument.php</exclude-pattern>
<exclude-pattern>tests/Tests/Mapping/Documents/GlobalNamespaceDocument.php</exclude-pattern>
</rule>

<rule ref="Squiz.NamingConventions.ValidVariableName.NotCamelCaps">
<exclude-pattern>tests/Doctrine/ODM/MongoDB/Tests/Functional/FunctionalTest.php</exclude-pattern>
<exclude-pattern>tests/Tests/Functional/FunctionalTest.php</exclude-pattern>
</rule>

<rule ref="Generic.NamingConventions.UpperCaseConstantName.ClassConstantNotUpperCase">
<exclude-pattern>lib/Doctrine/ODM/MongoDB/Events.php</exclude-pattern>
<exclude-pattern>src/Events.php</exclude-pattern>
</rule>

<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
<exclude-pattern>lib/Doctrine/ODM/MongoDB/Mapping/Driver/CompatibilityAnnotationDriver.php</exclude-pattern>
<exclude-pattern>lib/Doctrine/ODM/MongoDB/Tools/Console/Command/CommandCompatibility.php</exclude-pattern>
<exclude-pattern>lib/Doctrine/ODM/MongoDB/Tools/Console/Helper/DocumentManagerHelper.php</exclude-pattern>
<exclude-pattern>*/tests/*</exclude-pattern>
<exclude-pattern>src/Mapping/Driver/CompatibilityAnnotationDriver.php</exclude-pattern>
<exclude-pattern>src/Tools/Console/Command/CommandCompatibility.php</exclude-pattern>
<exclude-pattern>src/Tools/Console/Helper/DocumentManagerHelper.php</exclude-pattern>
<exclude-pattern>tests/*</exclude-pattern>
</rule>

<rule ref="Squiz.Classes.ClassFileName.NoMatch">
<exclude-pattern>lib/Doctrine/ODM/MongoDB/Tools/Console/Helper/DocumentManagerHelper.php</exclude-pattern>
<exclude-pattern>*/tests/*</exclude-pattern>
<exclude-pattern>src/Tools/Console/Helper/DocumentManagerHelper.php</exclude-pattern>
<exclude-pattern>tests/*</exclude-pattern>
</rule>

<!-- If forces to add "@inheritDoc" because the analysis is per file -->
<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingAnyTypeHint">
<exclude-pattern>*/lib/*</exclude-pattern>
<exclude-pattern>tests/Doctrine/ODM/MongoDB/Tests/Functional/DocumentPersisterTest.php</exclude-pattern>
<exclude-pattern>tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomTypeTest.php</exclude-pattern>
<exclude-pattern>src/*</exclude-pattern>
<exclude-pattern>tests/Tests/Functional/DocumentPersisterTest.php</exclude-pattern>
<exclude-pattern>tests/Tests/Functional/CustomTypeTest.php</exclude-pattern>
</rule>

<rule ref="SlevomatCodingStandard.TypeHints.ReturnTypeHint.MissingNativeTypeHint">
<!-- We do want to test generating collections without return types -->
<exclude-pattern>*/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/Coll*</exclude-pattern>
<exclude-pattern>tests/Tests/PersistentCollection/Coll*</exclude-pattern>
</rule>
<!-- It fails when using Nowdoc in method call -->
<rule ref="SlevomatCodingStandard.Functions.RequireTrailingCommaInCall.MissingTrailingComma">
<exclude-pattern>lib/Doctrine/ODM/MongoDB/Tools/Console/Command/*</exclude-pattern>
<exclude-pattern>src/Tools/Console/Command/*</exclude-pattern>
</rule>
</ruleset>
Loading