diff --git a/.doctrine-project.json b/.doctrine-project.json index dfb3923004..8d01fc56da 100644 --- a/.doctrine-project.json +++ b/.doctrine-project.json @@ -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", diff --git a/.github/workflows/atlas-ci.yml b/.github/workflows/atlas-ci.yml index e113452fd0..ff9225f9a8 100644 --- a/.github/workflows/atlas-ci.yml +++ b/.github/workflows/atlas-ci.yml @@ -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' }} diff --git a/.github/workflows/coding-standards.yml b/.github/workflows/coding-standards.yml index 31983556ce..987911bd87 100644 --- a/.github/workflows/coding-standards.yml +++ b/.github/workflows/coding-standards.yml @@ -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" diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 16407bfd99..c837bf2cb7 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -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" @@ -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 }} diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 1e87083d83..374fde8ed0 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -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" diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 7dce4fee8a..7ebbf01f3c 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -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 diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index 07f079fd34..f89a2bb26c 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -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: diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index acd9c56664..3f7fc5d213 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -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 diff --git a/.github/workflows/website-schema.yml b/.github/workflows/website-schema.yml index 66202e2005..f56b7241a2 100644 --- a/.github/workflows/website-schema.yml +++ b/.github/workflows/website-schema.yml @@ -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" diff --git a/composer.json b/composer.json index 306fcc3ead..d276e63220 100644 --- a/composer.json +++ b/composer.json @@ -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": { diff --git a/docs/en/reference/custom-mapping-types.rst b/docs/en/reference/custom-mapping-types.rst index 2e18807193..cd47aa7573 100644 --- a/docs/en/reference/custom-mapping-types.rst +++ b/docs/en/reference/custom-mapping-types.rst @@ -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 @@ -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'])) { @@ -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) { @@ -115,5 +120,85 @@ specify a unique name for the mapping type and map that to the corresponding +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 + + $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 FQCN diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 3a44845f46..4b7df00be3 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -12,7 +12,7 @@ benchmark - lib + src tests tools @@ -50,46 +50,46 @@ - tests/Doctrine/ODM/MongoDB/Tests/Mapping/Documents/GlobalNamespaceDocument.php + tests/Tests/Mapping/Documents/GlobalNamespaceDocument.php - tests/Doctrine/ODM/MongoDB/Tests/Mapping/Documents/GlobalNamespaceDocument.php + tests/Tests/Mapping/Documents/GlobalNamespaceDocument.php - tests/Doctrine/ODM/MongoDB/Tests/Functional/FunctionalTest.php + tests/Tests/Functional/FunctionalTest.php - lib/Doctrine/ODM/MongoDB/Events.php + src/Events.php - lib/Doctrine/ODM/MongoDB/Mapping/Driver/CompatibilityAnnotationDriver.php - lib/Doctrine/ODM/MongoDB/Tools/Console/Command/CommandCompatibility.php - lib/Doctrine/ODM/MongoDB/Tools/Console/Helper/DocumentManagerHelper.php - */tests/* + src/Mapping/Driver/CompatibilityAnnotationDriver.php + src/Tools/Console/Command/CommandCompatibility.php + src/Tools/Console/Helper/DocumentManagerHelper.php + tests/* - lib/Doctrine/ODM/MongoDB/Tools/Console/Helper/DocumentManagerHelper.php - */tests/* + src/Tools/Console/Helper/DocumentManagerHelper.php + tests/* - */lib/* - tests/Doctrine/ODM/MongoDB/Tests/Functional/DocumentPersisterTest.php - tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomTypeTest.php + src/* + tests/Tests/Functional/DocumentPersisterTest.php + tests/Tests/Functional/CustomTypeTest.php - */tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/Coll* + tests/Tests/PersistentCollection/Coll* - lib/Doctrine/ODM/MongoDB/Tools/Console/Command/* + src/Tools/Console/Command/* diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index b123bec670..d2f4c2db11 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -4,1237 +4,1237 @@ parameters: message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Aggregation\:\:execute\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Aggregation.php + path: src/Aggregation/Aggregation.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Aggregation\:\:getIterator\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Aggregation.php + path: src/Aggregation/Aggregation.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Aggregation\:\:prepareIterator\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Aggregation.php + path: src/Aggregation/Aggregation.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Builder\:\:execute\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php + path: src/Aggregation/Builder.php - message: '#^PHPDoc tag @param references unknown parameter\: \$applyFilters$#' identifier: parameter.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php + path: src/Aggregation/Builder.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\:\:execute\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage.php + path: src/Aggregation/Stage.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Bucket\\AbstractOutput\:\:avg\(\) has parameter \$expressions with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php + path: src/Aggregation/Stage/Bucket/AbstractOutput.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Bucket\\AbstractOutput\:\:max\(\) has parameter \$expressions with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php + path: src/Aggregation/Stage/Bucket/AbstractOutput.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Bucket\\AbstractOutput\:\:mergeObjects\(\) has parameter \$expressions with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php + path: src/Aggregation/Stage/Bucket/AbstractOutput.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Bucket\\AbstractOutput\:\:min\(\) has parameter \$expressions with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php + path: src/Aggregation/Stage/Bucket/AbstractOutput.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Bucket\\AbstractOutput\:\:stdDevPop\(\) has parameter \$expressions with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php + path: src/Aggregation/Stage/Bucket/AbstractOutput.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Bucket\\AbstractOutput\:\:stdDevSamp\(\) has parameter \$expressions with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php + path: src/Aggregation/Stage/Bucket/AbstractOutput.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Bucket\\AbstractOutput\:\:sum\(\) has parameter \$expressions with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php + path: src/Aggregation/Stage/Bucket/AbstractOutput.php - message: '#^Class Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Fill has type alias FillStageExpression with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Fill.php + path: src/Aggregation/Stage/Fill.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\GraphLookup\:\:\$from \(string\|null\) is never assigned null so it can be removed from the property type\.$#' identifier: property.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GraphLookup.php + path: src/Aggregation/Stage/GraphLookup.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\GraphLookup\:\:\$startWith \(array\\|Doctrine\\ODM\\MongoDB\\Aggregation\\Expr\|string\|null\) is never assigned null so it can be removed from the property type\.$#' identifier: property.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GraphLookup.php + path: src/Aggregation/Stage/GraphLookup.php - message: '#^Unable to resolve the template type T in call to method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getClassMetadata\(\)$#' identifier: argument.templateType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GraphLookup.php + path: src/Aggregation/Stage/GraphLookup.php - message: '#^Unable to resolve the template type T in call to method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getClassMetadata\(\)$#' identifier: argument.templateType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Lookup.php + path: src/Aggregation/Stage/Lookup.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Merge\:\:\$whenMatched \(''fail''\|''keepExisting''\|''merge''\|''replace''\|Doctrine\\ODM\\MongoDB\\Aggregation\\Builder\|Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\|list\\>\|null\) is never assigned Doctrine\\ODM\\MongoDB\\Aggregation\\Stage so it can be removed from the property type\.$#' identifier: property.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Merge.php + path: src/Aggregation/Stage/Merge.php - message: '#^Unable to resolve the template type T in call to method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getClassMetadata\(\)$#' identifier: argument.templateType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Merge.php + path: src/Aggregation/Stage/Merge.php - message: '#^Unable to resolve the template type T in call to method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getClassMetadata\(\)$#' identifier: argument.templateType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Out.php + path: src/Aggregation/Stage/Out.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedAutocomplete\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedAutocomplete.php + path: src/Aggregation/Stage/Search/Compound/CompoundedAutocomplete.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedEmbeddedDocument\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedEmbeddedDocument.php + path: src/Aggregation/Stage/Search/Compound/CompoundedEmbeddedDocument.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedEquals\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedEquals.php + path: src/Aggregation/Stage/Search/Compound/CompoundedEquals.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedExists\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedExists.php + path: src/Aggregation/Stage/Search/Compound/CompoundedExists.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedGeoShape\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedGeoShape.php + path: src/Aggregation/Stage/Search/Compound/CompoundedGeoShape.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedGeoWithin\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedGeoWithin.php + path: src/Aggregation/Stage/Search/Compound/CompoundedGeoWithin.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedMoreLikeThis\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedMoreLikeThis.php + path: src/Aggregation/Stage/Search/Compound/CompoundedMoreLikeThis.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedNear\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedNear.php + path: src/Aggregation/Stage/Search/Compound/CompoundedNear.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedPhrase\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedPhrase.php + path: src/Aggregation/Stage/Search/Compound/CompoundedPhrase.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedQueryString\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedQueryString.php + path: src/Aggregation/Stage/Search/Compound/CompoundedQueryString.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedRange\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedRange.php + path: src/Aggregation/Stage/Search/Compound/CompoundedRange.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedRegex\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedRegex.php + path: src/Aggregation/Stage/Search/Compound/CompoundedRegex.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedText\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedText.php + path: src/Aggregation/Stage/Search/Compound/CompoundedText.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Compound\\CompoundedWildcard\:\:__construct\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedWildcard.php + path: src/Aggregation/Stage/Search/Compound/CompoundedWildcard.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoShape\:\:__construct\(\) has parameter \$geometry with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoShape.php + path: src/Aggregation/Stage/Search/GeoShape.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoShape\:\:geometry\(\) has parameter \$geometry with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoShape.php + path: src/Aggregation/Stage/Search/GeoShape.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoShape\:\:\$geometry type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoShape.php + path: src/Aggregation/Stage/Search/GeoShape.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoWithin\:\:box\(\) has parameter \$bottomLeft with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php + path: src/Aggregation/Stage/Search/GeoWithin.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoWithin\:\:box\(\) has parameter \$topRight with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php + path: src/Aggregation/Stage/Search/GeoWithin.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoWithin\:\:circle\(\) has parameter \$center with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php + path: src/Aggregation/Stage/Search/GeoWithin.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoWithin\:\:convertGeometry\(\) has parameter \$geometry with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php + path: src/Aggregation/Stage/Search/GeoWithin.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoWithin\:\:convertGeometry\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php + path: src/Aggregation/Stage/Search/GeoWithin.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoWithin\:\:geometry\(\) has parameter \$geometry with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php + path: src/Aggregation/Stage/Search/GeoWithin.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoWithin\:\:\$geometry type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php + path: src/Aggregation/Stage/Search/GeoWithin.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\GeoWithin\:\:\$relation is never read, only written\.$#' identifier: property.onlyWritten count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php + path: src/Aggregation/Stage/Search/GeoWithin.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Near\:\:__construct\(\) has parameter \$origin with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Near.php + path: src/Aggregation/Stage/Search/Near.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Near\:\:origin\(\) has parameter \$origin with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Near.php + path: src/Aggregation/Stage/Search/Near.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Near\:\:\$origin type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Near.php + path: src/Aggregation/Stage/Search/Near.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Search\\Range\:\:\$includeUpperBound is never read, only written\.$#' identifier: property.onlyWritten count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Range.php + path: src/Aggregation/Stage/Search/Range.php - message: '#^Class Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\UnionWith has type alias PipelineParamType with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnionWith.php + path: src/Aggregation/Stage/UnionWith.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\UnionWith\:\:pipeline\(\) has parameter \$pipeline with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnionWith.php + path: src/Aggregation/Stage/UnionWith.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\UnionWith\:\:\$pipeline \(array\|Doctrine\\ODM\\MongoDB\\Aggregation\\Builder\|Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\|null\) is never assigned Doctrine\\ODM\\MongoDB\\Aggregation\\Stage so it can be removed from the property type\.$#' identifier: property.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnionWith.php + path: src/Aggregation/Stage/UnionWith.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\UnionWith\:\:\$pipeline type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnionWith.php + path: src/Aggregation/Stage/UnionWith.php - message: '#^Unable to resolve the template type T in call to method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getClassMetadata\(\)$#' identifier: argument.templateType count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnionWith.php + path: src/Aggregation/Stage/UnionWith.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\VectorSearch\:\:\$filter type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Aggregation/Stage/VectorSearch.php + path: src/Aggregation/Stage/VectorSearch.php - message: '#^Return type \(Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactoryInterface\) of method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getMetadataFactory\(\) should be compatible with return type \(Doctrine\\Persistence\\Mapping\\ClassMetadataFactory\\>\) of method Doctrine\\Persistence\\ObjectManager\:\:getMetadataFactory\(\)$#' identifier: method.childReturnType count: 1 - path: lib/Doctrine/ODM/MongoDB/DocumentManager.php + path: src/DocumentManager.php - message: '#^Unsafe usage of new static\(\)\.$#' identifier: new.static count: 1 - path: lib/Doctrine/ODM/MongoDB/DocumentManager.php + path: src/DocumentManager.php - message: '#^Method Doctrine\\Persistence\\Event\\OnClearEventArgs\\:\:__construct\(\) invoked with 2 parameters, 1 required\.$#' identifier: arguments.count count: 1 - path: lib/Doctrine/ODM/MongoDB/Event/OnClearEventArgs.php + path: src/Event/OnClearEventArgs.php - message: '#^Parameter \#1 \$initializer of method ProxyManager\\Proxy\\GhostObjectInterface\\:\:setProxyInitializer\(\) expects \(Closure\(ProxyManager\\Proxy\\GhostObjectInterface\\=, string\=, array\\=, Closure\|null\=, array\\=\)\: bool\)\|null, Closure\(ProxyManager\\Proxy\\GhostObjectInterface, string, array, mixed, array\)\: true given\.$#' identifier: argument.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php + path: src/Hydrator/HydratorFactory.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Hydrator\\HydratorFactory\:\:\$hydratorNamespace \(string\|null\) is never assigned null so it can be removed from the property type\.$#' identifier: property.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php + path: src/Hydrator/HydratorFactory.php - message: '#^Interface Doctrine\\ODM\\MongoDB\\Iterator\\IterableResult extends generic interface IteratorAggregate but does not specify its types\: TKey, TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Iterator/IterableResult.php + path: src/Iterator/IterableResult.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Iterator\\IterableResult\:\:getIterator\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Iterator/IterableResult.php + path: src/Iterator/IterableResult.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\Annotations\\SearchIndex\:\:__construct\(\) has parameter \$fields with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/Annotations/SearchIndex.php - - - - message: '#^Call to function assert\(\) with true will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php - - - - message: '#^Instanceof between Doctrine\\Persistence\\Reflection\\RuntimeReflectionProperty and ReflectionProperty will always evaluate to true\.$#' - identifier: instanceof.alwaysTrue - count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/Annotations/SearchIndex.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\:\:addInheritedAssociationMapping\(\) has Doctrine\\ODM\\MongoDB\\Mapping\\MappingException in PHPDoc @throws tag but it''s not thrown\.$#' identifier: throws.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\:\:getBucketName\(\) never returns null so it can be removed from the return type\.$#' identifier: return.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\:\:mapField\(\) should return array\{type\: string, fieldName\: string, name\: string, isCascadeRemove\: bool, isCascadePersist\: bool, isCascadeRefresh\: bool, isCascadeMerge\: bool, isCascadeDetach\: bool, \.\.\.\} but returns array\{type\?\: string, fieldName\?\: string, name\?\: string, strategy\?\: string, association\?\: int, id\?\: bool, isOwningSide\?\: bool, collectionClass\?\: class\-string, \.\.\.\}\.$#' identifier: return.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Parameter \#1 \$mapping of method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\\:\:checkDuplicateMapping\(\) expects array\{type\: string, fieldName\: string, name\: string, isCascadeRemove\: bool, isCascadePersist\: bool, isCascadeRefresh\: bool, isCascadeMerge\: bool, isCascadeDetach\: bool, \.\.\.\}, array\{type\?\: string, fieldName\?\: string, name\?\: string, strategy\?\: string, association\?\: int, id\?\: bool, isOwningSide\?\: bool, collectionClass\?\: class\-string, \.\.\.\} given\.$#' identifier: argument.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Parameter \#1 \$mapping of method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\\:\:setVersionMapping\(\) expects array\{type\: string, fieldName\: string, name\: string, isCascadeRemove\: bool, isCascadePersist\: bool, isCascadeRefresh\: bool, isCascadeMerge\: bool, isCascadeDetach\: bool, \.\.\.\}, array\{type\: string, fieldName\: string, name\: string, strategy\?\: string, association\?\: int, id\?\: bool, isOwningSide\?\: bool, collectionClass\?\: class\-string, \.\.\.\} given\.$#' identifier: argument.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Parameter \#1 \$mapping of method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\\:\:typeRequirementsAreMet\(\) expects array\{type\: string, fieldName\: string, name\: string, isCascadeRemove\: bool, isCascadePersist\: bool, isCascadeRefresh\: bool, isCascadeMerge\: bool, isCascadeDetach\: bool, \.\.\.\}, array\{type\?\: string, fieldName\?\: string, name\?\: string, strategy\?\: string, association\?\: int, id\?\: bool, isOwningSide\?\: bool, collectionClass\?\: class\-string, \.\.\.\} given\.$#' identifier: argument.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\:\:\$rootClass \(class\-string\|null\) is never assigned null so it can be removed from the property type\.$#' identifier: property.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Template type T is declared as covariant, but occurs in invariant position in property Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\:\:\$name\.$#' identifier: generics.variance count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Template type T is declared as covariant, but occurs in invariant position in property Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\:\:\$reflClass\.$#' identifier: generics.variance count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Template type T is declared as covariant, but occurs in invariant position in return type of method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\:\:getReflectionClass\(\)\.$#' identifier: generics.variance count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php + path: src/Mapping/ClassMetadata.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\Driver\\AttributeDriver\:\:getClassAttributes\(\) has parameter \$class with generic class ReflectionClass but does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeDriver.php + path: src/Mapping/Driver/AttributeDriver.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\Driver\\AttributeReader\:\:getClassAttributes\(\) has parameter \$class with generic class ReflectionClass but does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeReader.php + path: src/Mapping/Driver/AttributeReader.php - message: '#^Match expression does not handle remaining value\: string$#' identifier: match.unhandled count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php + path: src/Mapping/Driver/XmlDriver.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Mapping\\Driver\\XmlDriver\:\:getSearchIndexFieldDefinition\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php + path: src/Mapping/Driver/XmlDriver.php - message: '#^Parameter \#2 \$mapping of method Doctrine\\ODM\\MongoDB\\Mapping\\Driver\\XmlDriver\:\:addFieldMapping\(\) expects array\{type\?\: string, fieldName\?\: string, name\?\: string, strategy\?\: string, association\?\: int, id\?\: bool, isOwningSide\?\: bool, collectionClass\?\: class\-string, \.\.\.\}, array\, Doctrine\\ODM\\MongoDB\\Mapping\\Annotations\\EncryptQuery\|float\|int\|MongoDB\\BSON\\Decimal128\|MongoDB\\BSON\\Int64\|MongoDB\\BSON\\UTCDateTime\|string\|null\>\|bool\|string\> given\.$#' identifier: argument.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php + path: src/Mapping/Driver/XmlDriver.php - message: '#^Parameter \#2 \$mapping of method Doctrine\\ODM\\MongoDB\\Mapping\\Driver\\XmlDriver\:\:addFieldMapping\(\) expects array\{type\?\: string, fieldName\?\: string, name\?\: string, strategy\?\: string, association\?\: int, id\?\: bool, isOwningSide\?\: bool, collectionClass\?\: class\-string, \.\.\.\}, non\-empty\-array\\|string\|true\> given\.$#' identifier: argument.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php + path: src/Mapping/Driver/XmlDriver.php - message: '#^Parameter \#2 \$options of method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadata\\:\:addIndex\(\) expects array\{background\?\: bool, bits\?\: int, default_language\?\: string, expireAfterSeconds\?\: int, language_override\?\: string, min\?\: float, max\?\: float, name\?\: string, \.\.\.\}, array\\|string, mixed\>\|bool\|float\|int\|string\|null\>\|bool\|float\|int\|string\|null\> given\.$#' identifier: argument.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php + path: src/Mapping/Driver/XmlDriver.php + + - + message: '#^Parameter \#1 \$initializer of method ProxyManager\\Proxy\\GhostObjectInterface\\:\:setProxyInitializer\(\) expects \(Closure\(ProxyManager\\Proxy\\GhostObjectInterface\\=, string\=, array\\=, Closure\|null\=, array\\=\)\: bool\)\|null, \(Closure\(ProxyManager\\Proxy\\GhostObjectInterface\\=, string, array\\=, Closure\|null\=, array\\=\)\: bool\)\|null given\.$#' + identifier: argument.type + count: 1 + path: src/Mapping/PropertyAccessors/ObjectCastPropertyAccessor.php + + - + message: '#^Parameter \#1 \$initializer of method ProxyManager\\Proxy\\GhostObjectInterface\\:\:setProxyInitializer\(\) expects \(Closure\(ProxyManager\\Proxy\\GhostObjectInterface\\=, string\=, array\\=, Closure\|null\=, array\\=\)\: bool\)\|null, \(Closure\(ProxyManager\\Proxy\\GhostObjectInterface\\=, string, array\\=, Closure\|null\=, array\\=\)\: bool\)\|null given\.$#' + identifier: argument.type + count: 1 + path: src/Mapping/PropertyAccessors/RawValuePropertyAccessor.php - message: '#^Call to function is_object\(\) with Doctrine\\Common\\Collections\\Collection will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Call to function method_exists\(\) with Doctrine\\Common\\Collections\\Collection and ''findFirst'' will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Call to function method_exists\(\) with Doctrine\\Common\\Collections\\Collection and ''reduce'' will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Method Doctrine\\ODM\\MongoDB\\PersistentCollection\:\:add\(\) with return type void returns true but should not return anything\.$#' identifier: return.void count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^PHPDoc tag @var for property Doctrine\\ODM\\MongoDB\\PersistentCollection\:\:\$hints with type Doctrine\\ODM\\MongoDB\\PersistentCollection\\Hints is incompatible with native type array\.$#' identifier: property.phpDocType count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^PHPDoc tag @var for property Doctrine\\ODM\\MongoDB\\PersistentCollection\:\:\$mapping with type Doctrine\\ODM\\MongoDB\\PersistentCollection\\FieldMapping\|null is not subtype of native type array\|null\.$#' identifier: property.phpDocType count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Property Doctrine\\ODM\\MongoDB\\PersistentCollection\:\:\$hints has unknown class Doctrine\\ODM\\MongoDB\\PersistentCollection\\Hints as its type\.$#' identifier: class.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Property Doctrine\\ODM\\MongoDB\\PersistentCollection\:\:\$hints type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Property Doctrine\\ODM\\MongoDB\\PersistentCollection\:\:\$mapping has unknown class Doctrine\\ODM\\MongoDB\\PersistentCollection\\FieldMapping as its type\.$#' identifier: class.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Property Doctrine\\ODM\\MongoDB\\PersistentCollection\:\:\$mapping type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Unable to resolve the template type T in call to method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getClassMetadata\(\)$#' identifier: argument.templateType count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection.php + path: src/PersistentCollection.php - message: '#^Method Doctrine\\ODM\\MongoDB\\PersistentCollection\\AbstractPersistentCollectionFactory\:\:createCollectionClass\(\) return type with generic interface Doctrine\\Common\\Collections\\Collection does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection/AbstractPersistentCollectionFactory.php + path: src/PersistentCollection/AbstractPersistentCollectionFactory.php - message: '#^Method Doctrine\\ODM\\MongoDB\\PersistentCollection\\DefaultPersistentCollectionFactory\:\:createCollectionClass\(\) return type with generic interface Doctrine\\Common\\Collections\\Collection does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionFactory.php + path: src/PersistentCollection/DefaultPersistentCollectionFactory.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\CollectionPersister\:\:delete\(\) has parameter \$collections with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\CollectionPersister\:\:deleteElements\(\) has parameter \$collections with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\CollectionPersister\:\:getPathAndParent\(\) has parameter \$coll with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\CollectionPersister\:\:getValuePrepareCallback\(\) has parameter \$coll with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\CollectionPersister\:\:insertElements\(\) has parameter \$collections with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\CollectionPersister\:\:setCollections\(\) has parameter \$collections with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\CollectionPersister\:\:update\(\) has parameter \$collections with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^PHPDoc tag @var for variable \$addToSetColls contains generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^PHPDoc tag @var for variable \$pushAllColls contains generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^PHPDoc tag @var for variable \$setColls contains generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php + path: src/Persisters/CollectionPersister.php - message: '#^Call to function is_array\(\) with array will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:createReferenceManyInverseSideQuery\(\) has parameter \$collection with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:createReferenceManyWithRepositoryMethodCursor\(\) has parameter \$collection with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:createReferenceManyWithRepositoryMethodCursor\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:isInTransaction\(\) has parameter \$options with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:loadAll\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:loadCollection\(\) has parameter \$collection with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:loadEmbedManyCollection\(\) has parameter \$collection with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:loadReferenceManyCollectionInverseSide\(\) has parameter \$collection with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:loadReferenceManyCollectionOwningSide\(\) has parameter \$collection with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:loadReferenceManyWithRepositoryMethod\(\) has parameter \$collection with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface but does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\DocumentPersister\:\:wrapCursor\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Parameter \#1 \$array \(non\-empty\-list\) of array_values is already a list, call has no effect\.$#' identifier: arrayValues.list count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php + path: src/Persisters/DocumentPersister.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\PersistenceBuilder\:\:preparePersistentCollection\(\) has parameter \$mapping with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/PersistenceBuilder.php + path: src/Persisters/PersistenceBuilder.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Persisters\\PersistenceBuilder\:\:preparePersistentCollection\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\PersistentCollection\\PersistentCollectionInterface does not specify its types\: TKey, T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Persisters/PersistenceBuilder.php + path: src/Persisters/PersistenceBuilder.php - message: '#^Call to an undefined static method Doctrine\\ODM\\MongoDB\\Proxy\\Factory\\LazyGhostProxyFactory\:\:createLazyGhost\(\)\.$#' identifier: staticMethod.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Proxy/Factory/LazyGhostProxyFactory.php + path: src/Proxy/Factory/LazyGhostProxyFactory.php - message: '#^Call to function is_scalar\(\) with int\\|int\<5, max\> will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Proxy/Factory/LazyGhostProxyFactory.php + path: src/Proxy/Factory/LazyGhostProxyFactory.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Proxy\\Factory\\LazyGhostProxyFactory\:\:createLazyInitializer\(\) has Doctrine\\ODM\\MongoDB\\DocumentNotFoundException in PHPDoc @throws tag but it''s not thrown\.$#' identifier: throws.unusedType count: 1 - path: lib/Doctrine/ODM/MongoDB/Proxy/Factory/LazyGhostProxyFactory.php + path: src/Proxy/Factory/LazyGhostProxyFactory.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Proxy\\Factory\\LazyGhostProxyFactory\:\:createLazyInitializer\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Proxy\\InternalProxy does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Proxy/Factory/LazyGhostProxyFactory.php + path: src/Proxy/Factory/LazyGhostProxyFactory.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Proxy\\Factory\\LazyGhostProxyFactory\:\:getProxy\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Proxy\\InternalProxy does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Proxy/Factory/LazyGhostProxyFactory.php + path: src/Proxy/Factory/LazyGhostProxyFactory.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Proxy\\Factory\\StaticProxyFactory\:\:createInitializer\(\) should return Closure\(ProxyManager\\Proxy\\GhostObjectInterface\&TDocument\=, string\=, array\\=, Closure\|null\=, array\\=\)\: bool but returns Closure\(ProxyManager\\Proxy\\GhostObjectInterface, string, array, mixed, array\)\: true\.$#' identifier: return.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Proxy/Factory/StaticProxyFactory.php + path: src/Proxy/Factory/StaticProxyFactory.php - message: '#^Unsafe call to private method Doctrine\\ODM\\MongoDB\\Query\\Expr\:\:convertExpression\(\) through static\:\:\.$#' identifier: staticClassAccess.privateMethod count: 3 - path: lib/Doctrine/ODM/MongoDB/Query/Expr.php + path: src/Query/Expr.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Query\\Query\:\:getIterator\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Query/Query.php + path: src/Query/Query.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Query\\Query\:\:makeIterator\(\) return type with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Query/Query.php + path: src/Query/Query.php - message: '#^Property Doctrine\\ODM\\MongoDB\\Query\\Query\:\:\$iterator with generic interface Doctrine\\ODM\\MongoDB\\Iterator\\Iterator does not specify its types\: TValue$#' identifier: missingType.generics count: 1 - path: lib/Doctrine/ODM/MongoDB/Query/Query.php + path: src/Query/Query.php - message: '#^Strict comparison using \!\=\= between array\\|bool\|int\|MongoDB\\Driver\\ReadPreference\|string and null will always evaluate to true\.$#' identifier: notIdentical.alwaysTrue count: 1 - path: lib/Doctrine/ODM/MongoDB/Query/Query.php + path: src/Query/Query.php - message: '#^Parameter &\$groupedIds by\-ref type of method Doctrine\\ODM\\MongoDB\\Query\\ReferencePrimer\:\:addManyReferences\(\) expects array\\>, array\\> given\.$#' identifier: parameterByRef.type count: 1 - path: lib/Doctrine/ODM/MongoDB/Query/ReferencePrimer.php + path: src/Query/ReferencePrimer.php - message: '#^Call to an undefined method Symfony\\Component\\Console\\Helper\\HelperInterface\:\:getDocumentManager\(\)\.$#' identifier: method.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/ClearCache/MetadataCommand.php + path: src/Tools/Console/Command/ClearCache/MetadataCommand.php - message: '#^Call to an undefined method Symfony\\Component\\Console\\Helper\\HelperInterface\:\:getDocumentManager\(\)\.$#' identifier: method.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateHydratorsCommand.php + path: src/Tools/Console/Command/GenerateHydratorsCommand.php - message: '#^Call to an undefined method Symfony\\Component\\Console\\Helper\\HelperInterface\:\:getDocumentManager\(\)\.$#' identifier: method.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GeneratePersistentCollectionsCommand.php + path: src/Tools/Console/Command/GeneratePersistentCollectionsCommand.php - message: '#^Call to an undefined method Symfony\\Component\\Console\\Helper\\HelperInterface\:\:getDocumentManager\(\)\.$#' identifier: method.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateProxiesCommand.php + path: src/Tools/Console/Command/GenerateProxiesCommand.php - message: '#^Call to an undefined method Symfony\\Component\\Console\\Helper\\HelperInterface\:\:getDocumentManager\(\)\.$#' identifier: method.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/QueryCommand.php + path: src/Tools/Console/Command/QueryCommand.php - message: '#^Call to an undefined method Symfony\\Component\\Console\\Helper\\HelperInterface\:\:getDocumentManager\(\)\.$#' identifier: method.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/AbstractCommand.php + path: src/Tools/Console/Command/Schema/AbstractCommand.php - message: '#^Match expression does not handle remaining value\: string$#' identifier: match.unhandled count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/CreateCommand.php + path: src/Tools/Console/Command/Schema/CreateCommand.php - message: '#^Match expression does not handle remaining value\: string$#' identifier: match.unhandled count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/DropCommand.php + path: src/Tools/Console/Command/Schema/DropCommand.php - message: '#^Call to an undefined method Symfony\\Component\\Console\\Helper\\HelperInterface\:\:getDocumentManager\(\)\.$#' identifier: method.notFound count: 1 - path: lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/ValidateCommand.php + path: src/Tools/Console/Command/Schema/ValidateCommand.php - message: '#^Unreachable statement \- code above always terminates\.$#' identifier: deadCode.unreachable count: 1 - path: lib/Doctrine/ODM/MongoDB/Types/DateImmutableType.php + path: src/Types/DateImmutableType.php - message: '#^Unsafe call to private method Doctrine\\ODM\\MongoDB\\Types\\DateType\:\:craftDateTime\(\) through static\:\:\.$#' identifier: staticClassAccess.privateMethod count: 1 - path: lib/Doctrine/ODM/MongoDB/Types/DateType.php + path: src/Types/DateType.php - message: '#^Method Doctrine\\ODM\\MongoDB\\UnitOfWork\:\:getTransactionOptions\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/UnitOfWork.php + path: src/UnitOfWork.php - message: '#^Method Doctrine\\ODM\\MongoDB\\UnitOfWork\:\:stripTransactionOptions\(\) has parameter \$options with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/UnitOfWork.php + path: src/UnitOfWork.php - message: '#^Method Doctrine\\ODM\\MongoDB\\UnitOfWork\:\:stripTransactionOptions\(\) return type has no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/UnitOfWork.php + path: src/UnitOfWork.php - message: '#^Method Doctrine\\ODM\\MongoDB\\UnitOfWork\:\:withTransaction\(\) has parameter \$transactionOptions with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: lib/Doctrine/ODM/MongoDB/UnitOfWork.php + path: src/UnitOfWork.php - message: '#^Unable to resolve the template type T in call to method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getClassMetadata\(\)$#' identifier: argument.templateType count: 1 - path: lib/Doctrine/ODM/MongoDB/UnitOfWork.php + path: src/UnitOfWork.php - message: '#^Unable to resolve the template type T in call to method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getClassMetadata\(\)$#' identifier: argument.templateType count: 3 - path: lib/Doctrine/ODM/MongoDB/Utility/LifecycleEventManager.php + path: src/Utility/LifecycleEventManager.php - message: '#^Parameter \#1 \$builder of method Doctrine\\ODM\\MongoDB\\Aggregation\\Stage\\Facet\:\:pipeline\(\) expects Doctrine\\ODM\\MongoDB\\Aggregation\\Builder\|Doctrine\\ODM\\MongoDB\\Aggregation\\Stage, stdClass given\.$#' identifier: argument.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/FacetTest.php + path: tests/Tests/Aggregation/Stage/FacetTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\ProjectTest\:\:testAccumulatorsWithMultipleArguments\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/ProjectTest.php + path: tests/Tests/Aggregation/Stage/ProjectTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\ProjectTest\:\:testAccumulatorsWithMultipleArguments\(\) has parameter \$expected with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/ProjectTest.php + path: tests/Tests/Aggregation/Stage/ProjectTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\SearchTest\:\:testSearchCompoundOperators\(\) has parameter \$expectedOperator with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SearchTest.php + path: tests/Tests/Aggregation/Stage/SearchTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\SearchTest\:\:testSearchEmbeddedDocumentOperators\(\) has parameter \$expectedOperator with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SearchTest.php + path: tests/Tests/Aggregation/Stage/SearchTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\SearchTest\:\:testSearchOperators\(\) has parameter \$expectedOperator with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SearchTest.php + path: tests/Tests/Aggregation/Stage/SearchTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\SearchTest\:\:testSearchOperatorsWithSearchAfter\(\) has parameter \$expectedOperator with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SearchTest.php + path: tests/Tests/Aggregation/Stage/SearchTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\SearchTest\:\:testSearchOperatorsWithSearchBefore\(\) has parameter \$expectedOperator with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SearchTest.php + path: tests/Tests/Aggregation/Stage/SearchTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\SearchTest\:\:testSearchOperatorsWithSort\(\) has parameter \$expectedOperator with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SearchTest.php + path: tests/Tests/Aggregation/Stage/SearchTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\SetWindowFieldsTest\:\:testOperators\(\) has parameter \$args with no type specified\.$#' identifier: missingType.parameter count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SetWindowFieldsTest.php + path: tests/Tests/Aggregation/Stage/SetWindowFieldsTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Aggregation\\Stage\\SetWindowFieldsTest\:\:testOperators\(\) has parameter \$expected with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SetWindowFieldsTest.php + path: tests/Tests/Aggregation/Stage/SetWindowFieldsTest.php - message: '#^Constant DOCTRINE_MONGODB_SERVER not found\.$#' identifier: constant.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/BaseTestCase.php + path: tests/Tests/BaseTestCase.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\BaseTestCase\:\:assertArraySubset\(\) has parameter \$array with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/BaseTestCase.php + path: tests/Tests/BaseTestCase.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\BaseTestCase\:\:assertArraySubset\(\) has parameter \$subset with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/BaseTestCase.php + path: tests/Tests/BaseTestCase.php - message: '#^Used constant DOCTRINE_MONGODB_SERVER not found\.$#' identifier: constant.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/BaseTestCase.php + path: tests/Tests/BaseTestCase.php - message: '#^Parameter \#2 \$referenceMapping of method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:createReference\(\) expects array\{type\: string, fieldName\: string, name\: string, isCascadeRemove\: bool, isCascadePersist\: bool, isCascadeRefresh\: bool, isCascadeMerge\: bool, isCascadeDetach\: bool, \.\.\.\}, array\{storeAs\: ''dbRef''\} given\.$#' identifier: argument.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/DocumentManagerTest.php + path: tests/Tests/DocumentManagerTest.php - message: '#^Parameter \#2 \$projects of class Documents\\Developer constructor expects Doctrine\\Common\\Collections\\Collection\\|null, Doctrine\\Common\\Collections\\ArrayCollection\ given\.$#' identifier: argument.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/DocumentRepositoryTest.php + path: tests/Tests/DocumentRepositoryTest.php - message: '#^Parameter \#2 \$collections of method Doctrine\\ODM\\MongoDB\\Persisters\\CollectionPersister\:\:delete\(\) expects array\, array\\|Doctrine\\Common\\Collections\\Collection\\> given\.$#' identifier: argument.type count: 3 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/CollectionPersisterTest.php + path: tests/Tests/Functional/CollectionPersisterTest.php - message: '#^PHPDoc type Doctrine\\Common\\Collections\\Collection\ of property Doctrine\\ODM\\MongoDB\\Tests\\Functional\\ParentDocumentWithDiscriminator\:\:\$embeddedChildren is not covariant with PHPDoc type array\\|Doctrine\\Common\\Collections\\Collection\ of overridden property Doctrine\\ODM\\MongoDB\\Tests\\Functional\\ParentDocument\:\:\$embeddedChildren\.$#' identifier: property.phpDocType count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/DiscriminatorsDefaultValueTest.php + path: tests/Tests/Functional/DiscriminatorsDefaultValueTest.php - message: '#^PHPDoc type array\\|Doctrine\\Common\\Collections\\Collection\ of property Doctrine\\ODM\\MongoDB\\Tests\\Functional\\ParentDocumentWithDiscriminator\:\:\$referencedChildren is not covariant with PHPDoc type array\\|Doctrine\\Common\\Collections\\Collection\ of overridden property Doctrine\\ODM\\MongoDB\\Tests\\Functional\\ParentDocument\:\:\$referencedChildren\.$#' identifier: property.phpDocType count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/DiscriminatorsDefaultValueTest.php + path: tests/Tests/Functional/DiscriminatorsDefaultValueTest.php - message: '#^PHPDoc type array\\|Doctrine\\Common\\Collections\\Collection\ of property Doctrine\\ODM\\MongoDB\\Tests\\Functional\\ParentDocumentWithoutDiscriminator\:\:\$embeddedChildren is not covariant with PHPDoc type array\\|Doctrine\\Common\\Collections\\Collection\ of overridden property Doctrine\\ODM\\MongoDB\\Tests\\Functional\\ParentDocument\:\:\$embeddedChildren\.$#' identifier: property.phpDocType count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/DiscriminatorsDefaultValueTest.php + path: tests/Tests/Functional/DiscriminatorsDefaultValueTest.php - message: '#^PHPDoc type array\\|Doctrine\\Common\\Collections\\Collection\ of property Doctrine\\ODM\\MongoDB\\Tests\\Functional\\ParentDocumentWithoutDiscriminator\:\:\$referencedChildren is not covariant with PHPDoc type array\\|Doctrine\\Common\\Collections\\Collection\ of overridden property Doctrine\\ODM\\MongoDB\\Tests\\Functional\\ParentDocument\:\:\$referencedChildren\.$#' identifier: property.phpDocType count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/DiscriminatorsDefaultValueTest.php + path: tests/Tests/Functional/DiscriminatorsDefaultValueTest.php - message: '#^Expression "\$groups\[0\]" on a separate line does not do anything\.$#' identifier: expr.resultUnused count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/FunctionalTest.php + path: tests/Tests/Functional/FunctionalTest.php - message: '#^Access to an undefined property MongoDB\\Model\\BSONDocument\:\:\$patientId\.$#' identifier: property.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryableEncryptionTest.php + path: tests/Tests/Functional/QueryableEncryptionTest.php - message: '#^Access to an undefined property MongoDB\\Model\\BSONDocument\:\:\$patientName\.$#' identifier: property.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryableEncryptionTest.php + path: tests/Tests/Functional/QueryableEncryptionTest.php - message: '#^Access to an undefined property MongoDB\\Model\\BSONDocument\:\:\$patientRecord\.$#' identifier: property.notFound count: 6 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryableEncryptionTest.php + path: tests/Tests/Functional/QueryableEncryptionTest.php - message: '#^Parameter \$discriminatorMap of attribute class Doctrine\\ODM\\MongoDB\\Mapping\\Annotations\\ReferenceOne constructor expects array\\|null, array\ given\.$#' identifier: argument.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/TargetDocumentTest.php + path: tests/Tests/Functional/TargetDocumentTest.php - message: '#^Parameter \$targetDocument of attribute class Doctrine\\ODM\\MongoDB\\Mapping\\Annotations\\ReferenceOne constructor expects class\-string\|null, string given\.$#' identifier: argument.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Functional/TargetDocumentTest.php + path: tests/Tests/Functional/TargetDocumentTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Mapping\\ClassMetadataTest\:\:testEmptyVectorSearchIndexDefinition\(\) has parameter \$definition with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php + path: tests/Tests/Mapping/ClassMetadataTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Mapping\\ClassMetadataTest\:\:testSearchIndexDefinition\(\) has parameter \$definition with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php + path: tests/Tests/Mapping/ClassMetadataTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Query\\BuilderTest\:\:testExclude\(\) has parameter \$expected with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Query/BuilderTest.php + path: tests/Tests/Query/BuilderTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\Query\\BuilderTest\:\:testSelect\(\) has parameter \$expected with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Query/BuilderTest.php + path: tests/Tests/Query/BuilderTest.php - message: '#^Parameter \#1 \$primer of method Doctrine\\ODM\\MongoDB\\Query\\Builder\:\:prime\(\) expects bool\|\(callable\(\)\: mixed\), 1 given\.$#' identifier: argument.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Query/BuilderTest.php + path: tests/Tests/Query/BuilderTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\QueryTest\:\:createCursorMock\(\) return type has no value type specified in iterable type Traversable\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/QueryTest.php + path: tests/Tests/QueryTest.php - message: '#^Parameter \#4 \$query of class Doctrine\\ODM\\MongoDB\\Query\\Query constructor expects array\{distinct\?\: string, hint\?\: array\\|string, limit\?\: int, maxTimeMS\?\: int, multiple\?\: bool, new\?\: bool, newObj\?\: array\, query\?\: array\, \.\.\.\}, array\{type\: \-1\} given\.$#' identifier: argument.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/QueryTest.php + path: tests/Tests/QueryTest.php - message: '#^Instantiated class MongoDB\\Model\\CollectionInfoCommandIterator not found\.$#' identifier: class.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php + path: tests/Tests/SchemaManagerTest.php - message: '#^Instantiated class MongoDB\\Model\\IndexInfoIteratorIterator not found\.$#' identifier: class.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php + path: tests/Tests/SchemaManagerTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\SchemaManagerTest\:\:createCollectionIterator\(\) has parameter \$collections with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php + path: tests/Tests/SchemaManagerTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\SchemaManagerTest\:\:createCollectionIterator\(\) should return Iterator but returns MongoDB\\Model\\CollectionInfoCommandIterator\.$#' identifier: return.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php + path: tests/Tests/SchemaManagerTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\SchemaManagerTest\:\:createIndexIterator\(\) has parameter \$indexes with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php + path: tests/Tests/SchemaManagerTest.php - message: '#^Method Doctrine\\ODM\\MongoDB\\Tests\\SchemaManagerTest\:\:createIndexIterator\(\) should return Iterator but returns MongoDB\\Model\\IndexInfoIteratorIterator\.$#' identifier: return.type count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php + path: tests/Tests/SchemaManagerTest.php - message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactoryInterface\:\:doLoadMetadata\(\)\.$#' identifier: method.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactoryInterface\:\:getDriver\(\)\.$#' identifier: method.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactoryInterface\:\:initializeReflection\(\)\.$#' identifier: method.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactoryInterface\:\:isEntity\(\)\.$#' identifier: method.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactoryInterface\:\:newClassMetadataInstance\(\)\.$#' identifier: method.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactoryInterface\:\:wakeupReflection\(\)\.$#' identifier: method.notFound count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - - message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:__construct\(\) has parameter \$classNames with no value type specified in iterable type array\.$#' + message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:__construct\(\) has parameter \$classNames with no value type specified in iterable type array\.$#' identifier: missingType.iterableValue count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - - message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:doLoadMetadata\(\) has parameter \$class with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' + message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:doLoadMetadata\(\) has parameter \$class with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - - message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:doLoadMetadata\(\) has parameter \$parent with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' + message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:doLoadMetadata\(\) has parameter \$parent with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - - message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:getAllMetadata\(\) return type with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata does not specify its types\: T$#' + message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:getAllMetadata\(\) return type with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - - message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:initializeReflection\(\) has parameter \$class with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' + message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:initializeReflection\(\) has parameter \$class with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - - message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:isEntity\(\) has parameter \$class with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' + message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:isEntity\(\) has parameter \$class with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - - message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:wakeupReflection\(\) has parameter \$class with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' + message: '#^Method Doctrine\\Persistence\\Mapping\\AbstractClassMetadataFactory@anonymous/tests/Tests/Tools/EncryptedFieldsMapGeneratorTest\.php\:212\:\:wakeupReflection\(\) has parameter \$class with generic interface Doctrine\\Persistence\\Mapping\\ClassMetadata but does not specify its types\: T$#' identifier: missingType.generics count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php + path: tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php - message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertSame\(\) with arguments MongoDB\\BSON\\Binary, null and ''Binary UUIDs are…'' will always evaluate to false\.$#' identifier: staticMethod.impossibleType count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Types/BinaryUuidTypeTest.php + path: tests/Tests/Types/BinaryUuidTypeTest.php - message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertSame\(\) with arguments Symfony\\Component\\Uid\\UuidV4, null and ''Uuid objects are…'' will always evaluate to false\.$#' identifier: staticMethod.impossibleType count: 1 - path: tests/Doctrine/ODM/MongoDB/Tests/Types/BinaryUuidTypeTest.php + path: tests/Tests/Types/BinaryUuidTypeTest.php - message: '#^Method Documents\\Encryption\\Client\:\:__construct\(\) has parameter \$clientCards with generic interface Doctrine\\Common\\Collections\\Collection but does not specify its types\: TKey, T$#' diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f5f3707fbe..a6f7ff93e1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -6,10 +6,10 @@ parameters: level: 5 paths: - benchmark - - lib + - src - tests excludePaths: - - tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/User.php + - tests/Tests/Mapping/Driver/fixtures/User.php - tests/Hydrators/ - tests/PersistentCollections/ (?) - tests/Proxies/ @@ -20,11 +20,11 @@ parameters: # Ignore circular references in Psalm types - message: '#^Circular definition detected in type alias#' - path: lib/Doctrine/ODM/MongoDB/Aggregation/ + path: src/Aggregation/ # Keep type assertions even when type is declared - identifier: staticMethod.alreadyNarrowedType - path: tests/Doctrine/ + path: tests/Tests/ - message: '#generic class Doctrine\\ODM\\MongoDB\\(Mapping\\ClassMetadata|Persisters\\DocumentPersister) (but )?does not specify its types\: T$#' identifier: missingType.generics diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 3860390bdc..4451e15bc1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,23 +1,27 @@ - ./tests/Doctrine/ + ./tests/Tests/ - ./lib/Doctrine/ODM/MongoDB + ./src @@ -29,6 +33,7 @@ - + + diff --git a/lib/Doctrine/ODM/MongoDB/APM/Command.php b/src/APM/Command.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/APM/Command.php rename to src/APM/Command.php diff --git a/lib/Doctrine/ODM/MongoDB/APM/CommandLogger.php b/src/APM/CommandLogger.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/APM/CommandLogger.php rename to src/APM/CommandLogger.php diff --git a/lib/Doctrine/ODM/MongoDB/APM/CommandLoggerInterface.php b/src/APM/CommandLoggerInterface.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/APM/CommandLoggerInterface.php rename to src/APM/CommandLoggerInterface.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Aggregation.php b/src/Aggregation/Aggregation.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Aggregation.php rename to src/Aggregation/Aggregation.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php b/src/Aggregation/Builder.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php rename to src/Aggregation/Builder.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Expr.php b/src/Aggregation/Expr.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Expr.php rename to src/Aggregation/Expr.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/AccumulatorOperators.php b/src/Aggregation/Operator/AccumulatorOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/AccumulatorOperators.php rename to src/Aggregation/Operator/AccumulatorOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ArithmeticOperators.php b/src/Aggregation/Operator/ArithmeticOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ArithmeticOperators.php rename to src/Aggregation/Operator/ArithmeticOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ArrayOperators.php b/src/Aggregation/Operator/ArrayOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ArrayOperators.php rename to src/Aggregation/Operator/ArrayOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/BooleanOperators.php b/src/Aggregation/Operator/BooleanOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/BooleanOperators.php rename to src/Aggregation/Operator/BooleanOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ComparisonOperators.php b/src/Aggregation/Operator/ComparisonOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ComparisonOperators.php rename to src/Aggregation/Operator/ComparisonOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ConditionalOperators.php b/src/Aggregation/Operator/ConditionalOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ConditionalOperators.php rename to src/Aggregation/Operator/ConditionalOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/CustomOperators.php b/src/Aggregation/Operator/CustomOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/CustomOperators.php rename to src/Aggregation/Operator/CustomOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/DataSizeOperators.php b/src/Aggregation/Operator/DataSizeOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/DataSizeOperators.php rename to src/Aggregation/Operator/DataSizeOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/DateOperators.php b/src/Aggregation/Operator/DateOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/DateOperators.php rename to src/Aggregation/Operator/DateOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/GroupAccumulatorOperators.php b/src/Aggregation/Operator/GroupAccumulatorOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/GroupAccumulatorOperators.php rename to src/Aggregation/Operator/GroupAccumulatorOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/MiscOperators.php b/src/Aggregation/Operator/MiscOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/MiscOperators.php rename to src/Aggregation/Operator/MiscOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ObjectOperators.php b/src/Aggregation/Operator/ObjectOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ObjectOperators.php rename to src/Aggregation/Operator/ObjectOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ProvidesGroupAccumulatorOperators.php b/src/Aggregation/Operator/ProvidesGroupAccumulatorOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ProvidesGroupAccumulatorOperators.php rename to src/Aggregation/Operator/ProvidesGroupAccumulatorOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ProvidesWindowOperators.php b/src/Aggregation/Operator/ProvidesWindowOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/ProvidesWindowOperators.php rename to src/Aggregation/Operator/ProvidesWindowOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/SetOperators.php b/src/Aggregation/Operator/SetOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/SetOperators.php rename to src/Aggregation/Operator/SetOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/StringOperators.php b/src/Aggregation/Operator/StringOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/StringOperators.php rename to src/Aggregation/Operator/StringOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/TimestampOperators.php b/src/Aggregation/Operator/TimestampOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/TimestampOperators.php rename to src/Aggregation/Operator/TimestampOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/TrigonometryOperators.php b/src/Aggregation/Operator/TrigonometryOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/TrigonometryOperators.php rename to src/Aggregation/Operator/TrigonometryOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/TypeOperators.php b/src/Aggregation/Operator/TypeOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/TypeOperators.php rename to src/Aggregation/Operator/TypeOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Operator/WindowOperators.php b/src/Aggregation/Operator/WindowOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Operator/WindowOperators.php rename to src/Aggregation/Operator/WindowOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage.php b/src/Aggregation/Stage.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage.php rename to src/Aggregation/Stage.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/AbstractBucket.php b/src/Aggregation/Stage/AbstractBucket.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/AbstractBucket.php rename to src/Aggregation/Stage/AbstractBucket.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/AbstractReplace.php b/src/Aggregation/Stage/AbstractReplace.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/AbstractReplace.php rename to src/Aggregation/Stage/AbstractReplace.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/AddFields.php b/src/Aggregation/Stage/AddFields.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/AddFields.php rename to src/Aggregation/Stage/AddFields.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket.php b/src/Aggregation/Stage/Bucket.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket.php rename to src/Aggregation/Stage/Bucket.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php b/src/Aggregation/Stage/Bucket/AbstractOutput.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/AbstractOutput.php rename to src/Aggregation/Stage/Bucket/AbstractOutput.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/BucketAutoOutput.php b/src/Aggregation/Stage/Bucket/BucketAutoOutput.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/BucketAutoOutput.php rename to src/Aggregation/Stage/Bucket/BucketAutoOutput.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/BucketOutput.php b/src/Aggregation/Stage/Bucket/BucketOutput.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Bucket/BucketOutput.php rename to src/Aggregation/Stage/Bucket/BucketOutput.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/BucketAuto.php b/src/Aggregation/Stage/BucketAuto.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/BucketAuto.php rename to src/Aggregation/Stage/BucketAuto.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/CollStats.php b/src/Aggregation/Stage/CollStats.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/CollStats.php rename to src/Aggregation/Stage/CollStats.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Count.php b/src/Aggregation/Stage/Count.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Count.php rename to src/Aggregation/Stage/Count.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Densify.php b/src/Aggregation/Stage/Densify.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Densify.php rename to src/Aggregation/Stage/Densify.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Facet.php b/src/Aggregation/Stage/Facet.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Facet.php rename to src/Aggregation/Stage/Facet.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Fill.php b/src/Aggregation/Stage/Fill.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Fill.php rename to src/Aggregation/Stage/Fill.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Fill/Output.php b/src/Aggregation/Stage/Fill/Output.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Fill/Output.php rename to src/Aggregation/Stage/Fill/Output.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GeoNear.php b/src/Aggregation/Stage/GeoNear.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GeoNear.php rename to src/Aggregation/Stage/GeoNear.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GraphLookup.php b/src/Aggregation/Stage/GraphLookup.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GraphLookup.php rename to src/Aggregation/Stage/GraphLookup.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GraphLookup/MatchStage.php b/src/Aggregation/Stage/GraphLookup/MatchStage.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/GraphLookup/MatchStage.php rename to src/Aggregation/Stage/GraphLookup/MatchStage.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Group.php b/src/Aggregation/Stage/Group.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Group.php rename to src/Aggregation/Stage/Group.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/IndexStats.php b/src/Aggregation/Stage/IndexStats.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/IndexStats.php rename to src/Aggregation/Stage/IndexStats.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Limit.php b/src/Aggregation/Stage/Limit.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Limit.php rename to src/Aggregation/Stage/Limit.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Lookup.php b/src/Aggregation/Stage/Lookup.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Lookup.php rename to src/Aggregation/Stage/Lookup.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/MatchStage.php b/src/Aggregation/Stage/MatchStage.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/MatchStage.php rename to src/Aggregation/Stage/MatchStage.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Merge.php b/src/Aggregation/Stage/Merge.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Merge.php rename to src/Aggregation/Stage/Merge.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Operator.php b/src/Aggregation/Stage/Operator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Operator.php rename to src/Aggregation/Stage/Operator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Out.php b/src/Aggregation/Stage/Out.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Out.php rename to src/Aggregation/Stage/Out.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Project.php b/src/Aggregation/Stage/Project.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Project.php rename to src/Aggregation/Stage/Project.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Redact.php b/src/Aggregation/Stage/Redact.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Redact.php rename to src/Aggregation/Stage/Redact.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/ReplaceRoot.php b/src/Aggregation/Stage/ReplaceRoot.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/ReplaceRoot.php rename to src/Aggregation/Stage/ReplaceRoot.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/ReplaceWith.php b/src/Aggregation/Stage/ReplaceWith.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/ReplaceWith.php rename to src/Aggregation/Stage/ReplaceWith.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Sample.php b/src/Aggregation/Stage/Sample.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Sample.php rename to src/Aggregation/Stage/Sample.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search.php b/src/Aggregation/Stage/Search.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search.php rename to src/Aggregation/Stage/Search.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/AbstractSearchOperator.php b/src/Aggregation/Stage/Search/AbstractSearchOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/AbstractSearchOperator.php rename to src/Aggregation/Stage/Search/AbstractSearchOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Autocomplete.php b/src/Aggregation/Stage/Search/Autocomplete.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Autocomplete.php rename to src/Aggregation/Stage/Search/Autocomplete.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound.php b/src/Aggregation/Stage/Search/Compound.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound.php rename to src/Aggregation/Stage/Search/Compound.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedAutocomplete.php b/src/Aggregation/Stage/Search/Compound/CompoundedAutocomplete.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedAutocomplete.php rename to src/Aggregation/Stage/Search/Compound/CompoundedAutocomplete.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedEmbeddedDocument.php b/src/Aggregation/Stage/Search/Compound/CompoundedEmbeddedDocument.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedEmbeddedDocument.php rename to src/Aggregation/Stage/Search/Compound/CompoundedEmbeddedDocument.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedEquals.php b/src/Aggregation/Stage/Search/Compound/CompoundedEquals.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedEquals.php rename to src/Aggregation/Stage/Search/Compound/CompoundedEquals.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedExists.php b/src/Aggregation/Stage/Search/Compound/CompoundedExists.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedExists.php rename to src/Aggregation/Stage/Search/Compound/CompoundedExists.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedGeoShape.php b/src/Aggregation/Stage/Search/Compound/CompoundedGeoShape.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedGeoShape.php rename to src/Aggregation/Stage/Search/Compound/CompoundedGeoShape.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedGeoWithin.php b/src/Aggregation/Stage/Search/Compound/CompoundedGeoWithin.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedGeoWithin.php rename to src/Aggregation/Stage/Search/Compound/CompoundedGeoWithin.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedMoreLikeThis.php b/src/Aggregation/Stage/Search/Compound/CompoundedMoreLikeThis.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedMoreLikeThis.php rename to src/Aggregation/Stage/Search/Compound/CompoundedMoreLikeThis.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedNear.php b/src/Aggregation/Stage/Search/Compound/CompoundedNear.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedNear.php rename to src/Aggregation/Stage/Search/Compound/CompoundedNear.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedPhrase.php b/src/Aggregation/Stage/Search/Compound/CompoundedPhrase.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedPhrase.php rename to src/Aggregation/Stage/Search/Compound/CompoundedPhrase.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedQueryString.php b/src/Aggregation/Stage/Search/Compound/CompoundedQueryString.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedQueryString.php rename to src/Aggregation/Stage/Search/Compound/CompoundedQueryString.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedRange.php b/src/Aggregation/Stage/Search/Compound/CompoundedRange.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedRange.php rename to src/Aggregation/Stage/Search/Compound/CompoundedRange.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedRegex.php b/src/Aggregation/Stage/Search/Compound/CompoundedRegex.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedRegex.php rename to src/Aggregation/Stage/Search/Compound/CompoundedRegex.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedText.php b/src/Aggregation/Stage/Search/Compound/CompoundedText.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedText.php rename to src/Aggregation/Stage/Search/Compound/CompoundedText.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedWildcard.php b/src/Aggregation/Stage/Search/Compound/CompoundedWildcard.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Compound/CompoundedWildcard.php rename to src/Aggregation/Stage/Search/Compound/CompoundedWildcard.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/CompoundSearchOperatorInterface.php b/src/Aggregation/Stage/Search/CompoundSearchOperatorInterface.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/CompoundSearchOperatorInterface.php rename to src/Aggregation/Stage/Search/CompoundSearchOperatorInterface.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/CompoundedSearchOperatorTrait.php b/src/Aggregation/Stage/Search/CompoundedSearchOperatorTrait.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/CompoundedSearchOperatorTrait.php rename to src/Aggregation/Stage/Search/CompoundedSearchOperatorTrait.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/EmbeddedDocument.php b/src/Aggregation/Stage/Search/EmbeddedDocument.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/EmbeddedDocument.php rename to src/Aggregation/Stage/Search/EmbeddedDocument.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Equals.php b/src/Aggregation/Stage/Search/Equals.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Equals.php rename to src/Aggregation/Stage/Search/Equals.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Exists.php b/src/Aggregation/Stage/Search/Exists.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Exists.php rename to src/Aggregation/Stage/Search/Exists.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoShape.php b/src/Aggregation/Stage/Search/GeoShape.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoShape.php rename to src/Aggregation/Stage/Search/GeoShape.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php b/src/Aggregation/Stage/Search/GeoWithin.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/GeoWithin.php rename to src/Aggregation/Stage/Search/GeoWithin.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/MoreLikeThis.php b/src/Aggregation/Stage/Search/MoreLikeThis.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/MoreLikeThis.php rename to src/Aggregation/Stage/Search/MoreLikeThis.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Near.php b/src/Aggregation/Stage/Search/Near.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Near.php rename to src/Aggregation/Stage/Search/Near.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Phrase.php b/src/Aggregation/Stage/Search/Phrase.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Phrase.php rename to src/Aggregation/Stage/Search/Phrase.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/QueryString.php b/src/Aggregation/Stage/Search/QueryString.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/QueryString.php rename to src/Aggregation/Stage/Search/QueryString.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Range.php b/src/Aggregation/Stage/Search/Range.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Range.php rename to src/Aggregation/Stage/Search/Range.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Regex.php b/src/Aggregation/Stage/Search/Regex.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Regex.php rename to src/Aggregation/Stage/Search/Regex.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/ScoredSearchOperator.php b/src/Aggregation/Stage/Search/ScoredSearchOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/ScoredSearchOperator.php rename to src/Aggregation/Stage/Search/ScoredSearchOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/ScoredSearchOperatorTrait.php b/src/Aggregation/Stage/Search/ScoredSearchOperatorTrait.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/ScoredSearchOperatorTrait.php rename to src/Aggregation/Stage/Search/ScoredSearchOperatorTrait.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SearchOperator.php b/src/Aggregation/Stage/Search/SearchOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SearchOperator.php rename to src/Aggregation/Stage/Search/SearchOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsAllSearchOperators.php b/src/Aggregation/Stage/Search/SupportsAllSearchOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsAllSearchOperators.php rename to src/Aggregation/Stage/Search/SupportsAllSearchOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsAllSearchOperatorsTrait.php b/src/Aggregation/Stage/Search/SupportsAllSearchOperatorsTrait.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsAllSearchOperatorsTrait.php rename to src/Aggregation/Stage/Search/SupportsAllSearchOperatorsTrait.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsAutocompleteOperator.php b/src/Aggregation/Stage/Search/SupportsAutocompleteOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsAutocompleteOperator.php rename to src/Aggregation/Stage/Search/SupportsAutocompleteOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsCompoundOperator.php b/src/Aggregation/Stage/Search/SupportsCompoundOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsCompoundOperator.php rename to src/Aggregation/Stage/Search/SupportsCompoundOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsCompoundableOperatorsTrait.php b/src/Aggregation/Stage/Search/SupportsCompoundableOperatorsTrait.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsCompoundableOperatorsTrait.php rename to src/Aggregation/Stage/Search/SupportsCompoundableOperatorsTrait.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsCompoundableSearchOperators.php b/src/Aggregation/Stage/Search/SupportsCompoundableSearchOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsCompoundableSearchOperators.php rename to src/Aggregation/Stage/Search/SupportsCompoundableSearchOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsEmbeddableSearchOperators.php b/src/Aggregation/Stage/Search/SupportsEmbeddableSearchOperators.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsEmbeddableSearchOperators.php rename to src/Aggregation/Stage/Search/SupportsEmbeddableSearchOperators.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsEmbeddedDocumentOperator.php b/src/Aggregation/Stage/Search/SupportsEmbeddedDocumentOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsEmbeddedDocumentOperator.php rename to src/Aggregation/Stage/Search/SupportsEmbeddedDocumentOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsEqualsOperator.php b/src/Aggregation/Stage/Search/SupportsEqualsOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsEqualsOperator.php rename to src/Aggregation/Stage/Search/SupportsEqualsOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsExistsOperator.php b/src/Aggregation/Stage/Search/SupportsExistsOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsExistsOperator.php rename to src/Aggregation/Stage/Search/SupportsExistsOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsGeoShapeOperator.php b/src/Aggregation/Stage/Search/SupportsGeoShapeOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsGeoShapeOperator.php rename to src/Aggregation/Stage/Search/SupportsGeoShapeOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsGeoWithinOperator.php b/src/Aggregation/Stage/Search/SupportsGeoWithinOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsGeoWithinOperator.php rename to src/Aggregation/Stage/Search/SupportsGeoWithinOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsMoreLikeThisOperator.php b/src/Aggregation/Stage/Search/SupportsMoreLikeThisOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsMoreLikeThisOperator.php rename to src/Aggregation/Stage/Search/SupportsMoreLikeThisOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsNearOperator.php b/src/Aggregation/Stage/Search/SupportsNearOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsNearOperator.php rename to src/Aggregation/Stage/Search/SupportsNearOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsPhraseOperator.php b/src/Aggregation/Stage/Search/SupportsPhraseOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsPhraseOperator.php rename to src/Aggregation/Stage/Search/SupportsPhraseOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsQueryStringOperator.php b/src/Aggregation/Stage/Search/SupportsQueryStringOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsQueryStringOperator.php rename to src/Aggregation/Stage/Search/SupportsQueryStringOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsRangeOperator.php b/src/Aggregation/Stage/Search/SupportsRangeOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsRangeOperator.php rename to src/Aggregation/Stage/Search/SupportsRangeOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsRegexOperator.php b/src/Aggregation/Stage/Search/SupportsRegexOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsRegexOperator.php rename to src/Aggregation/Stage/Search/SupportsRegexOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsTextOperator.php b/src/Aggregation/Stage/Search/SupportsTextOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsTextOperator.php rename to src/Aggregation/Stage/Search/SupportsTextOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsWildcardOperator.php b/src/Aggregation/Stage/Search/SupportsWildcardOperator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/SupportsWildcardOperator.php rename to src/Aggregation/Stage/Search/SupportsWildcardOperator.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Text.php b/src/Aggregation/Stage/Search/Text.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Text.php rename to src/Aggregation/Stage/Search/Text.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Wildcard.php b/src/Aggregation/Stage/Search/Wildcard.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Search/Wildcard.php rename to src/Aggregation/Stage/Search/Wildcard.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Set.php b/src/Aggregation/Stage/Set.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Set.php rename to src/Aggregation/Stage/Set.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/SetWindowFields.php b/src/Aggregation/Stage/SetWindowFields.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/SetWindowFields.php rename to src/Aggregation/Stage/SetWindowFields.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/SetWindowFields/Output.php b/src/Aggregation/Stage/SetWindowFields/Output.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/SetWindowFields/Output.php rename to src/Aggregation/Stage/SetWindowFields/Output.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Skip.php b/src/Aggregation/Stage/Skip.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Skip.php rename to src/Aggregation/Stage/Skip.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Sort.php b/src/Aggregation/Stage/Sort.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Sort.php rename to src/Aggregation/Stage/Sort.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/SortByCount.php b/src/Aggregation/Stage/SortByCount.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/SortByCount.php rename to src/Aggregation/Stage/SortByCount.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnionWith.php b/src/Aggregation/Stage/UnionWith.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnionWith.php rename to src/Aggregation/Stage/UnionWith.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnsetStage.php b/src/Aggregation/Stage/UnsetStage.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/UnsetStage.php rename to src/Aggregation/Stage/UnsetStage.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Unwind.php b/src/Aggregation/Stage/Unwind.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/Unwind.php rename to src/Aggregation/Stage/Unwind.php diff --git a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/VectorSearch.php b/src/Aggregation/Stage/VectorSearch.php similarity index 94% rename from lib/Doctrine/ODM/MongoDB/Aggregation/Stage/VectorSearch.php rename to src/Aggregation/Stage/VectorSearch.php index 97d1ba723f..85c1f9d868 100644 --- a/lib/Doctrine/ODM/MongoDB/Aggregation/Stage/VectorSearch.php +++ b/src/Aggregation/Stage/VectorSearch.php @@ -8,6 +8,7 @@ use Doctrine\ODM\MongoDB\Aggregation\Stage; use Doctrine\ODM\MongoDB\Persisters\DocumentPersister; use Doctrine\ODM\MongoDB\Query\Expr; +use Doctrine\ODM\MongoDB\Types\Type; use InvalidArgumentException; use MongoDB\BSON\Binary; use MongoDB\BSON\Decimal128; @@ -81,7 +82,7 @@ public function getExpression(): array } if ($this->queryVector !== null) { - $params['queryVector'] = $this->queryVector; + $params['queryVector'] = Type::getType($this->persister->getClassMetadata()->fieldMappings[$this->path]['type'] ?? Type::RAW)->convertToDatabaseValue($this->queryVector); } return [$this->getStageName() => $params]; diff --git a/lib/Doctrine/ODM/MongoDB/Configuration.php b/src/Configuration.php similarity index 95% rename from lib/Doctrine/ODM/MongoDB/Configuration.php rename to src/Configuration.php index debf869270..6b38f50762 100644 --- a/lib/Doctrine/ODM/MongoDB/Configuration.php +++ b/src/Configuration.php @@ -47,6 +47,8 @@ use function trigger_deprecation; use function trim; +use const PHP_VERSION_ID; + /** * Configuration class for the DocumentManager. When setting up your DocumentManager * you can optionally specify an instance of this class as the second argument. @@ -145,7 +147,8 @@ class Configuration private bool $useTransactionalFlush = false; - private bool $useLazyGhostObject = false; + private bool $lazyGhostObject = false; + private bool $nativeLazyObject = false; private static string $version; @@ -688,24 +691,43 @@ public function isTransactionalFlushEnabled(): bool */ public function setUseLazyGhostObject(bool $flag): void { + if ($this->nativeLazyObject) { + throw new LogicException('Cannot enable or disable LazyGhostObject when native lazy objects are enabled.'); + } + if ($flag === false) { if (! class_exists(ProxyManagerConfiguration::class)) { throw new LogicException('Package "friendsofphp/proxy-manager-lts" is required to disable LazyGhostObject.'); } - trigger_deprecation( - 'doctrine/mongodb-odm', - '2.10', - 'Using "friendsofphp/proxy-manager-lts" is deprecated. Use "symfony/var-exporter" LazyGhostObjects instead.', - ); + trigger_deprecation('doctrine/mongodb-odm', '2.10', 'Using "friendsofphp/proxy-manager-lts" is deprecated. Use "symfony/var-exporter" LazyGhostObjects instead.'); } - $this->useLazyGhostObject = $flag; + $this->lazyGhostObject = $flag; } public function isLazyGhostObjectEnabled(): bool { - return $this->useLazyGhostObject; + return $this->lazyGhostObject; + } + + public function setUseNativeLazyObject(bool $nativeLazyObject): void + { + if (PHP_VERSION_ID < 80400 && $nativeLazyObject) { + throw new LogicException('Native lazy objects require PHP 8.4 or higher.'); + } + + $this->nativeLazyObject = $nativeLazyObject; + $this->lazyGhostObject = ! $nativeLazyObject || $this->lazyGhostObject; + } + + public function isNativeLazyObjectEnabled(): bool + { + if (PHP_VERSION_ID >= 80400 && ! $this->nativeLazyObject) { + trigger_deprecation('doctrine/mongodb-odm', '2.14', 'Not using native lazy objects is deprecated and will be impossible in Doctrine MongoDB ODM 3.0.'); + } + + return $this->nativeLazyObject; } /** diff --git a/lib/Doctrine/ODM/MongoDB/ConfigurationException.php b/src/ConfigurationException.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/ConfigurationException.php rename to src/ConfigurationException.php diff --git a/lib/Doctrine/ODM/MongoDB/DocumentManager.php b/src/DocumentManager.php similarity index 97% rename from lib/Doctrine/ODM/MongoDB/DocumentManager.php rename to src/DocumentManager.php index b9f440aefb..7ed9e3e73b 100644 --- a/lib/Doctrine/ODM/MongoDB/DocumentManager.php +++ b/src/DocumentManager.php @@ -10,6 +10,7 @@ use Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactoryInterface; use Doctrine\ODM\MongoDB\Mapping\MappingException; use Doctrine\ODM\MongoDB\Proxy\Factory\LazyGhostProxyFactory; +use Doctrine\ODM\MongoDB\Proxy\Factory\NativeLazyObjectFactory; use Doctrine\ODM\MongoDB\Proxy\Factory\ProxyFactory; use Doctrine\ODM\MongoDB\Proxy\Factory\StaticProxyFactory; use Doctrine\ODM\MongoDB\Proxy\Resolver\CachingClassNameResolver; @@ -31,7 +32,6 @@ use MongoDB\Driver\ClientEncryption; use MongoDB\Driver\ReadPreference; use MongoDB\GridFS\Bucket; -use ProxyManager\Proxy\GhostObjectInterface; use RuntimeException; use Throwable; @@ -179,11 +179,13 @@ protected function __construct(?Client $client = null, ?Configuration $config = $this->config->getAutoGenerateHydratorClasses(), ); - $this->unitOfWork = new UnitOfWork($this, $this->eventManager, $this->hydratorFactory); - $this->schemaManager = new SchemaManager($this, $this->metadataFactory); - $this->proxyFactory = $this->config->isLazyGhostObjectEnabled() - ? new LazyGhostProxyFactory($this, $this->config->getProxyDir(), $this->config->getProxyNamespace(), $this->config->getAutoGenerateProxyClasses()) - : new StaticProxyFactory($this); + $this->unitOfWork = new UnitOfWork($this, $this->eventManager, $this->hydratorFactory); + $this->schemaManager = new SchemaManager($this, $this->metadataFactory); + $this->proxyFactory = match (true) { + $this->config->isNativeLazyObjectEnabled() => new NativeLazyObjectFactory($this), + $this->config->isLazyGhostObjectEnabled() => new LazyGhostProxyFactory($this, $this->config->getProxyDir(), $this->config->getProxyNamespace(), $this->config->getAutoGenerateProxyClasses()), + default => new StaticProxyFactory($this), + }; $this->repositoryFactory = $this->config->getRepositoryFactory(); } @@ -607,7 +609,7 @@ public function flush(array $options = []): void * @param mixed $identifier * @param class-string $documentName * - * @return T|(T&GhostObjectInterface) + * @return T * * @template T of object */ @@ -624,9 +626,8 @@ public function getReference(string $documentName, $identifier): object return $document; } - /** @var T&GhostObjectInterface $document */ $document = $this->proxyFactory->getProxy($class, $identifier); - $this->unitOfWork->registerManaged($document, $identifier, []); + $this->unitOfWork->registerManaged($document, $identifier, [$class->identifier => $identifier]); return $document; } diff --git a/lib/Doctrine/ODM/MongoDB/DocumentNotFoundException.php b/src/DocumentNotFoundException.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/DocumentNotFoundException.php rename to src/DocumentNotFoundException.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/DocumentNotFoundEventArgs.php b/src/Event/DocumentNotFoundEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/DocumentNotFoundEventArgs.php rename to src/Event/DocumentNotFoundEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/LifecycleEventArgs.php b/src/Event/LifecycleEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/LifecycleEventArgs.php rename to src/Event/LifecycleEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/LoadClassMetadataEventArgs.php b/src/Event/LoadClassMetadataEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/LoadClassMetadataEventArgs.php rename to src/Event/LoadClassMetadataEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/ManagerEventArgs.php b/src/Event/ManagerEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/ManagerEventArgs.php rename to src/Event/ManagerEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/OnClassMetadataNotFoundEventArgs.php b/src/Event/OnClassMetadataNotFoundEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/OnClassMetadataNotFoundEventArgs.php rename to src/Event/OnClassMetadataNotFoundEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/OnClearEventArgs.php b/src/Event/OnClearEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/OnClearEventArgs.php rename to src/Event/OnClearEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/OnFlushEventArgs.php b/src/Event/OnFlushEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/OnFlushEventArgs.php rename to src/Event/OnFlushEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/PostCollectionLoadEventArgs.php b/src/Event/PostCollectionLoadEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/PostCollectionLoadEventArgs.php rename to src/Event/PostCollectionLoadEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/PostFlushEventArgs.php b/src/Event/PostFlushEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/PostFlushEventArgs.php rename to src/Event/PostFlushEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/PreFlushEventArgs.php b/src/Event/PreFlushEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/PreFlushEventArgs.php rename to src/Event/PreFlushEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/PreLoadEventArgs.php b/src/Event/PreLoadEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/PreLoadEventArgs.php rename to src/Event/PreLoadEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Event/PreUpdateEventArgs.php b/src/Event/PreUpdateEventArgs.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Event/PreUpdateEventArgs.php rename to src/Event/PreUpdateEventArgs.php diff --git a/lib/Doctrine/ODM/MongoDB/Events.php b/src/Events.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Events.php rename to src/Events.php diff --git a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorException.php b/src/Hydrator/HydratorException.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Hydrator/HydratorException.php rename to src/Hydrator/HydratorException.php diff --git a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php b/src/Hydrator/HydratorFactory.php similarity index 95% rename from lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php rename to src/Hydrator/HydratorFactory.php index e9542f5b46..5a821677fb 100644 --- a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorFactory.php +++ b/src/Hydrator/HydratorFactory.php @@ -33,6 +33,7 @@ use function uniqid; use const DIRECTORY_SEPARATOR; +use const PHP_VERSION_ID; /** * The HydratorFactory class is responsible for instantiating a correct hydrator @@ -187,7 +188,7 @@ private function generateHydratorClass(ClassMetadata $class, string $hydratorCla if (array_key_exists('%1$s', $data) && ($data['%1$s'] !== null || ($this->class->fieldMappings['%2$s']['nullable'] ?? false))) { $value = $data['%1$s']; %3$s - $this->class->reflFields['%2$s']->setValue($document, $return === null ? null : clone $return); + $this->class->propertyAccessors['%2$s']->setValue($document, $return === null ? null : clone $return); $hydratedData['%2$s'] = $return; } @@ -210,7 +211,7 @@ private function generateHydratorClass(ClassMetadata $class, string $hydratorCla } else { \$return = null; } - \$this->class->reflFields['%2\$s']->setValue(\$document, \$return); + \$this->class->propertyAccessors['%2\$s']->setValue(\$document, \$return); \$hydratedData['%2\$s'] = \$return; } @@ -239,7 +240,7 @@ private function generateHydratorClass(ClassMetadata $class, string $hydratorCla $return = $this->dm->getReference($className, $id); } - $this->class->reflFields['%2$s']->setValue($document, $return); + $this->class->propertyAccessors['%2$s']->setValue($document, $return); $hydratedData['%2$s'] = $return; } @@ -256,7 +257,7 @@ private function generateHydratorClass(ClassMetadata $class, string $hydratorCla $className = $this->class->fieldMappings['%2$s']['targetDocument']; $return = $this->dm->getRepository($className)->%3$s($document); - $this->class->reflFields['%2$s']->setValue($document, $return); + $this->class->propertyAccessors['%2$s']->setValue($document, $return); $hydratedData['%2$s'] = $return; EOF @@ -280,7 +281,7 @@ private function generateHydratorClass(ClassMetadata $class, string $hydratorCla ); $sort = $this->class->fieldMappings['%2$s']['sort'] ?? []; $return = $this->dm->getUnitOfWork()->getDocumentPersister($className)->load($criteria, null, [], 0, $sort); - $this->class->reflFields['%2$s']->setValue($document, $return); + $this->class->propertyAccessors['%2$s']->setValue($document, $return); $hydratedData['%2$s'] = $return; EOF @@ -307,7 +308,7 @@ private function generateHydratorClass(ClassMetadata $class, string $hydratorCla if ($mongoData) { $return->setMongoData($mongoData); } - $this->class->reflFields['%2$s']->setValue($document, $return); + $this->class->propertyAccessors['%2$s']->setValue($document, $return); $hydratedData['%2$s'] = $return; EOF @@ -345,7 +346,7 @@ private function generateHydratorClass(ClassMetadata $class, string $hydratorCla } } - $this->class->reflFields['%2$s']->setValue($document, $return); + $this->class->propertyAccessors['%2$s']->setValue($document, $return); $hydratedData['%2$s'] = $return; } @@ -450,6 +451,10 @@ public function hydrate(object $document, array $data, array $hints = []): array } } + if (PHP_VERSION_ID >= 80400) { + $metadata->reflClass->markLazyObjectAsInitialized($document); + } + if ($document instanceof InternalProxy) { // Skip initialization to not load any object data $document->__setInitialized(true); diff --git a/lib/Doctrine/ODM/MongoDB/Hydrator/HydratorInterface.php b/src/Hydrator/HydratorInterface.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Hydrator/HydratorInterface.php rename to src/Hydrator/HydratorInterface.php diff --git a/lib/Doctrine/ODM/MongoDB/Id/AbstractIdGenerator.php b/src/Id/AbstractIdGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Id/AbstractIdGenerator.php rename to src/Id/AbstractIdGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Id/AlnumGenerator.php b/src/Id/AlnumGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Id/AlnumGenerator.php rename to src/Id/AlnumGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Id/AutoGenerator.php b/src/Id/AutoGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Id/AutoGenerator.php rename to src/Id/AutoGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Id/IdGenerator.php b/src/Id/IdGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Id/IdGenerator.php rename to src/Id/IdGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Id/IncrementGenerator.php b/src/Id/IncrementGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Id/IncrementGenerator.php rename to src/Id/IncrementGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Id/ObjectIdGenerator.php b/src/Id/ObjectIdGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Id/ObjectIdGenerator.php rename to src/Id/ObjectIdGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Id/SymfonyUuidGenerator.php b/src/Id/SymfonyUuidGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Id/SymfonyUuidGenerator.php rename to src/Id/SymfonyUuidGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Id/UuidGenerator.php b/src/Id/UuidGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Id/UuidGenerator.php rename to src/Id/UuidGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php b/src/Iterator/CachingIterator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Iterator/CachingIterator.php rename to src/Iterator/CachingIterator.php diff --git a/lib/Doctrine/ODM/MongoDB/Iterator/HydratingIterator.php b/src/Iterator/HydratingIterator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Iterator/HydratingIterator.php rename to src/Iterator/HydratingIterator.php diff --git a/lib/Doctrine/ODM/MongoDB/Iterator/IterableResult.php b/src/Iterator/IterableResult.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Iterator/IterableResult.php rename to src/Iterator/IterableResult.php diff --git a/lib/Doctrine/ODM/MongoDB/Iterator/Iterator.php b/src/Iterator/Iterator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Iterator/Iterator.php rename to src/Iterator/Iterator.php diff --git a/lib/Doctrine/ODM/MongoDB/Iterator/PrimingIterator.php b/src/Iterator/PrimingIterator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Iterator/PrimingIterator.php rename to src/Iterator/PrimingIterator.php diff --git a/lib/Doctrine/ODM/MongoDB/Iterator/UnrewindableIterator.php b/src/Iterator/UnrewindableIterator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Iterator/UnrewindableIterator.php rename to src/Iterator/UnrewindableIterator.php diff --git a/lib/Doctrine/ODM/MongoDB/LockException.php b/src/LockException.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/LockException.php rename to src/LockException.php diff --git a/lib/Doctrine/ODM/MongoDB/LockMode.php b/src/LockMode.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/LockMode.php rename to src/LockMode.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/AbstractDocument.php b/src/Mapping/Annotations/AbstractDocument.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/AbstractDocument.php rename to src/Mapping/Annotations/AbstractDocument.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/AbstractField.php b/src/Mapping/Annotations/AbstractField.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/AbstractField.php rename to src/Mapping/Annotations/AbstractField.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/AbstractIndex.php b/src/Mapping/Annotations/AbstractIndex.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/AbstractIndex.php rename to src/Mapping/Annotations/AbstractIndex.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/AlsoLoad.php b/src/Mapping/Annotations/AlsoLoad.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/AlsoLoad.php rename to src/Mapping/Annotations/AlsoLoad.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Annotation.php b/src/Mapping/Annotations/Annotation.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Annotation.php rename to src/Mapping/Annotations/Annotation.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ChangeTrackingPolicy.php b/src/Mapping/Annotations/ChangeTrackingPolicy.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ChangeTrackingPolicy.php rename to src/Mapping/Annotations/ChangeTrackingPolicy.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DefaultDiscriminatorValue.php b/src/Mapping/Annotations/DefaultDiscriminatorValue.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DefaultDiscriminatorValue.php rename to src/Mapping/Annotations/DefaultDiscriminatorValue.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DiscriminatorField.php b/src/Mapping/Annotations/DiscriminatorField.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DiscriminatorField.php rename to src/Mapping/Annotations/DiscriminatorField.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DiscriminatorMap.php b/src/Mapping/Annotations/DiscriminatorMap.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DiscriminatorMap.php rename to src/Mapping/Annotations/DiscriminatorMap.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DiscriminatorValue.php b/src/Mapping/Annotations/DiscriminatorValue.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/DiscriminatorValue.php rename to src/Mapping/Annotations/DiscriminatorValue.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Document.php b/src/Mapping/Annotations/Document.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Document.php rename to src/Mapping/Annotations/Document.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/EmbedMany.php b/src/Mapping/Annotations/EmbedMany.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/EmbedMany.php rename to src/Mapping/Annotations/EmbedMany.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/EmbedOne.php b/src/Mapping/Annotations/EmbedOne.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/EmbedOne.php rename to src/Mapping/Annotations/EmbedOne.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/EmbeddedDocument.php b/src/Mapping/Annotations/EmbeddedDocument.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/EmbeddedDocument.php rename to src/Mapping/Annotations/EmbeddedDocument.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Encrypt.php b/src/Mapping/Annotations/Encrypt.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Encrypt.php rename to src/Mapping/Annotations/Encrypt.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/EncryptQuery.php b/src/Mapping/Annotations/EncryptQuery.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/EncryptQuery.php rename to src/Mapping/Annotations/EncryptQuery.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Field.php b/src/Mapping/Annotations/Field.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Field.php rename to src/Mapping/Annotations/Field.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File.php b/src/Mapping/Annotations/File.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File.php rename to src/Mapping/Annotations/File.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/ChunkSize.php b/src/Mapping/Annotations/File/ChunkSize.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/ChunkSize.php rename to src/Mapping/Annotations/File/ChunkSize.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/Filename.php b/src/Mapping/Annotations/File/Filename.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/Filename.php rename to src/Mapping/Annotations/File/Filename.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/Length.php b/src/Mapping/Annotations/File/Length.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/Length.php rename to src/Mapping/Annotations/File/Length.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/Metadata.php b/src/Mapping/Annotations/File/Metadata.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/Metadata.php rename to src/Mapping/Annotations/File/Metadata.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/UploadDate.php b/src/Mapping/Annotations/File/UploadDate.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/File/UploadDate.php rename to src/Mapping/Annotations/File/UploadDate.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/HasLifecycleCallbacks.php b/src/Mapping/Annotations/HasLifecycleCallbacks.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/HasLifecycleCallbacks.php rename to src/Mapping/Annotations/HasLifecycleCallbacks.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Id.php b/src/Mapping/Annotations/Id.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Id.php rename to src/Mapping/Annotations/Id.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Index.php b/src/Mapping/Annotations/Index.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Index.php rename to src/Mapping/Annotations/Index.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Indexes.php b/src/Mapping/Annotations/Indexes.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Indexes.php rename to src/Mapping/Annotations/Indexes.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/InheritanceType.php b/src/Mapping/Annotations/InheritanceType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/InheritanceType.php rename to src/Mapping/Annotations/InheritanceType.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Lock.php b/src/Mapping/Annotations/Lock.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Lock.php rename to src/Mapping/Annotations/Lock.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/MappedSuperclass.php b/src/Mapping/Annotations/MappedSuperclass.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/MappedSuperclass.php rename to src/Mapping/Annotations/MappedSuperclass.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PostLoad.php b/src/Mapping/Annotations/PostLoad.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PostLoad.php rename to src/Mapping/Annotations/PostLoad.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PostPersist.php b/src/Mapping/Annotations/PostPersist.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PostPersist.php rename to src/Mapping/Annotations/PostPersist.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PostRemove.php b/src/Mapping/Annotations/PostRemove.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PostRemove.php rename to src/Mapping/Annotations/PostRemove.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PostUpdate.php b/src/Mapping/Annotations/PostUpdate.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PostUpdate.php rename to src/Mapping/Annotations/PostUpdate.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PreFlush.php b/src/Mapping/Annotations/PreFlush.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PreFlush.php rename to src/Mapping/Annotations/PreFlush.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PreLoad.php b/src/Mapping/Annotations/PreLoad.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PreLoad.php rename to src/Mapping/Annotations/PreLoad.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PrePersist.php b/src/Mapping/Annotations/PrePersist.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PrePersist.php rename to src/Mapping/Annotations/PrePersist.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PreRemove.php b/src/Mapping/Annotations/PreRemove.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PreRemove.php rename to src/Mapping/Annotations/PreRemove.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PreUpdate.php b/src/Mapping/Annotations/PreUpdate.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/PreUpdate.php rename to src/Mapping/Annotations/PreUpdate.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/QueryResultDocument.php b/src/Mapping/Annotations/QueryResultDocument.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/QueryResultDocument.php rename to src/Mapping/Annotations/QueryResultDocument.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ReadPreference.php b/src/Mapping/Annotations/ReadPreference.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ReadPreference.php rename to src/Mapping/Annotations/ReadPreference.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ReferenceMany.php b/src/Mapping/Annotations/ReferenceMany.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ReferenceMany.php rename to src/Mapping/Annotations/ReferenceMany.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ReferenceOne.php b/src/Mapping/Annotations/ReferenceOne.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ReferenceOne.php rename to src/Mapping/Annotations/ReferenceOne.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/SearchIndex.php b/src/Mapping/Annotations/SearchIndex.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/SearchIndex.php rename to src/Mapping/Annotations/SearchIndex.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ShardKey.php b/src/Mapping/Annotations/ShardKey.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/ShardKey.php rename to src/Mapping/Annotations/ShardKey.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/TimeSeries.php b/src/Mapping/Annotations/TimeSeries.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/TimeSeries.php rename to src/Mapping/Annotations/TimeSeries.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/UniqueIndex.php b/src/Mapping/Annotations/UniqueIndex.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/UniqueIndex.php rename to src/Mapping/Annotations/UniqueIndex.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Validation.php b/src/Mapping/Annotations/Validation.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Validation.php rename to src/Mapping/Annotations/Validation.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/VectorSearchIndex.php b/src/Mapping/Annotations/VectorSearchIndex.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/VectorSearchIndex.php rename to src/Mapping/Annotations/VectorSearchIndex.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Version.php b/src/Mapping/Annotations/Version.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/Version.php rename to src/Mapping/Annotations/Version.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Annotations/View.php b/src/Mapping/Annotations/View.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Annotations/View.php rename to src/Mapping/Annotations/View.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php b/src/Mapping/ClassMetadata.php similarity index 96% rename from lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php rename to src/Mapping/ClassMetadata.php index 3088a770e4..763d70cfa9 100644 --- a/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadata.php +++ b/src/Mapping/ClassMetadata.php @@ -15,6 +15,9 @@ use Doctrine\ODM\MongoDB\LockException; use Doctrine\ODM\MongoDB\Mapping\Annotations\EncryptQuery; use Doctrine\ODM\MongoDB\Mapping\Annotations\TimeSeries; +use Doctrine\ODM\MongoDB\Mapping\PropertyAccessors\EnumPropertyAccessor; +use Doctrine\ODM\MongoDB\Mapping\PropertyAccessors\PropertyAccessor; +use Doctrine\ODM\MongoDB\Mapping\PropertyAccessors\PropertyAccessorFactory; use Doctrine\ODM\MongoDB\Proxy\InternalProxy; use Doctrine\ODM\MongoDB\Types\Incrementable; use Doctrine\ODM\MongoDB\Types\Type; @@ -23,7 +26,6 @@ use Doctrine\Persistence\Mapping\ClassMetadata as BaseClassMetadata; use Doctrine\Persistence\Mapping\ReflectionService; use Doctrine\Persistence\Mapping\RuntimeReflectionService; -use Doctrine\Persistence\Reflection\EnumReflectionProperty; use InvalidArgumentException; use LogicException; use MongoDB\BSON\Decimal128; @@ -61,6 +63,8 @@ use function strtoupper; use function trigger_deprecation; +use const PHP_VERSION_ID; + /** * A ClassMetadata instance holds all the object-document mapping metadata * of a document and it's references. @@ -638,10 +642,15 @@ /** * The ReflectionProperty instances of the mapped class. * - * @var ReflectionProperty[] + * @deprecated Since 2.13, use $propertyAccessors instead. + * + * @var LegacyReflectionFields|array */ public $reflFields = []; + /** @var array */ + public array $propertyAccessors = []; + /** * READ-ONLY: The inheritance mapping type used by the class. * @@ -870,6 +879,7 @@ public function __construct(string $documentName) $this->rootDocumentName = $documentName; $this->reflectionService = new RuntimeReflectionService(); $this->reflClass = new ReflectionClass($documentName); + $this->reflFields = new LegacyReflectionFields($this, $this->reflectionService); $this->setCollection($this->reflClass->getShortName()); $this->instantiator = new Instantiator(); } @@ -1498,21 +1508,40 @@ public function isChangeTrackingNotify(): bool /** * Gets the ReflectionProperties of the mapped class. * - * @return ReflectionProperty[] + * @deprecated Since 2.13, use getPropertyAccessors() instead. + * + * @return array|LegacyReflectionFields */ - public function getReflectionProperties(): array + public function getReflectionProperties(): array|LegacyReflectionFields { return $this->reflFields; } + /** + * Gets the ReflectionProperties of the mapped class. + * + * @return PropertyAccessor[] An array of PropertyAccessor instances. + */ + public function getPropertyAccessors(): array + { + return $this->propertyAccessors; + } + /** * Gets a ReflectionProperty for a specific field of the mapped class. + * + * @deprecated Since 2.13, use getPropertyAccessor() instead. */ public function getReflectionProperty(string $name): ReflectionProperty { return $this->reflFields[$name]; } + public function getPropertyAccessor(string $name): PropertyAccessor|null + { + return $this->propertyAccessors[$name] ?? null; + } + /** @return class-string */ public function getName(): string { @@ -1915,7 +1944,7 @@ public function getDatabaseIdentifierValue($id) public function setIdentifierValue(object $document, $id): void { $id = $this->getPHPIdentifierValue($id); - $this->reflFields[$this->identifier]->setValue($document, $id); + $this->propertyAccessors[$this->identifier]->setValue($document, $id); } /** @@ -1925,7 +1954,7 @@ public function setIdentifierValue(object $document, $id): void */ public function getIdentifierValue(object $document) { - return $this->reflFields[$this->identifier]->getValue($document); + return $this->propertyAccessors[$this->identifier]->getValue($document); } /** @@ -1963,9 +1992,11 @@ public function setFieldValue(object $document, string $field, $value): void $document->__load(); } elseif ($document instanceof GhostObjectInterface && ! $document->isProxyInitialized()) { $document->initializeProxy(); + } elseif (PHP_VERSION_ID >= 80400) { + $this->reflClass->initializeLazyObject($document); } - $this->reflFields[$field]->setValue($document, $value); + $this->propertyAccessors[$field]->setValue($document, $value); } /** @@ -1979,9 +2010,11 @@ public function getFieldValue(object $document, string $field) $document->__load(); } elseif ($document instanceof GhostObjectInterface && $field !== $this->identifier && ! $document->isProxyInitialized()) { $document->initializeProxy(); + } elseif (PHP_VERSION_ID >= 80400 && $field !== $this->identifier && $this->reflClass->isUninitializedLazyObject($document)) { + $this->reflClass->initializeLazyObject($document); } - return $this->reflFields[$field]->getValue($document); + return $this->propertyAccessors[$field]->getValue($document); } /** @@ -2408,7 +2441,7 @@ public function mapField(array $mapping): array } elseif (empty($mapping['type'])) { $mapping['type'] = $this->generatorType === self::GENERATOR_TYPE_INCREMENT ? Type::INT : Type::CUSTOMID; } - } elseif ($mapping['type'] !== Type::UUID) { + } elseif (empty($mapping['type']) || $mapping['type'] !== Type::UUID) { $mapping['type'] = Type::ID; } @@ -2567,8 +2600,11 @@ public function mapField(array $mapping): array $this->associationMappings[$mapping['fieldName']] = $mapping; } - $reflProp = $this->reflectionService->getAccessibleProperty($this->name, $mapping['fieldName']); - assert($reflProp instanceof ReflectionProperty); + $accessor = PropertyAccessorFactory::createPropertyAccessor($this->name, $mapping['fieldName']); + + if (PHP_VERSION_ID >= 80400 && $accessor->getUnderlyingReflector()->isVirtual()) { + throw MappingException::mappingVirtualPropertyNotAllowed($this->name, $mapping['fieldName']); + } if (isset($mapping['enumType'])) { if (! enum_exists($mapping['enumType'])) { @@ -2580,10 +2616,10 @@ public function mapField(array $mapping): array throw MappingException::nonBackedEnumMapped($this->name, $mapping['fieldName'], $mapping['enumType']); } - $reflProp = new EnumReflectionProperty($reflProp, $mapping['enumType']); + $accessor = new EnumPropertyAccessor($accessor, $mapping['enumType']); } - $this->reflFields[$mapping['fieldName']] = $reflProp; + $this->propertyAccessors[$mapping['fieldName']] = $accessor; return $mapping; } @@ -2595,9 +2631,10 @@ public function mapField(array $mapping): array * That means any metadata properties that are not set or empty or simply have * their default value are NOT serialized. * - * Parts that are also NOT serialized because they can not be properly unserialized: + * Parts that are also NOT serialized because they cannot be properly unserialized: * - reflClass (ReflectionClass) * - reflFields (ReflectionProperty array) + * - propertyAccessors (ReflectionProperty array) * * @return array The names of all the fields that should be serialized. */ @@ -2699,24 +2736,24 @@ public function __sleep() } /** - * Restores some state that can not be serialized/unserialized. + * Restores some state that cannot be serialized/unserialized. */ - public function __wakeup() + public function __wakeup(): void { // Restore ReflectionClass and properties - $this->reflectionService = new RuntimeReflectionService(); $this->reflClass = new ReflectionClass($this->name); $this->instantiator = new Instantiator(); + $this->reflectionService = new RuntimeReflectionService(); + $this->reflFields = new LegacyReflectionFields($this, $this->reflectionService); foreach ($this->fieldMappings as $field => $mapping) { - $prop = $this->reflectionService->getAccessibleProperty($mapping['declared'] ?? $this->name, $field); - assert($prop instanceof ReflectionProperty); + $accessor = PropertyAccessorFactory::createPropertyAccessor($mapping['declared'] ?? $this->name, $field); if (isset($mapping['enumType'])) { - $prop = new EnumReflectionProperty($prop, $mapping['enumType']); + $accessor = new EnumPropertyAccessor($accessor, $mapping['enumType']); } - $this->reflFields[$field] = $prop; + $this->propertyAccessors[$field] = $accessor; } } @@ -2786,9 +2823,19 @@ private function isTypedProperty(string $name): bool */ private function validateAndCompleteTypedFieldMapping(array $mapping): array { + if (isset($mapping['type'])) { + return $mapping; + } + $type = $this->reflClass->getProperty($mapping['fieldName'])->getType(); - if (! $type instanceof ReflectionNamedType || isset($mapping['type'])) { + if (! $type instanceof ReflectionNamedType) { + return $mapping; + } + + if (! $type->isBuiltin() && Type::hasType($type->getName())) { + $mapping['type'] = $type->getName(); + return $mapping; } @@ -2799,6 +2846,7 @@ private function validateAndCompleteTypedFieldMapping(array $mapping): array throw MappingException::nonBackedEnumMapped($this->name, $mapping['fieldName'], $reflection->getName()); } + // Use the backing type of the enum for the mapping type $type = $reflection->getBackingType(); assert($type instanceof ReflectionNamedType); $mapping['enumType'] = $reflection->getName(); diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php b/src/Mapping/ClassMetadataFactory.php similarity index 95% rename from lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php rename to src/Mapping/ClassMetadataFactory.php index 87b073d753..6f02bde635 100644 --- a/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactory.php +++ b/src/Mapping/ClassMetadataFactory.php @@ -31,6 +31,8 @@ use function trigger_deprecation; use function ucfirst; +use const PHP_VERSION_ID; + /** * The ClassMetadataFactory is used to create ClassMetadata objects that contain all the * metadata mapping informations of a class which describes how a class should be mapped @@ -117,6 +119,17 @@ protected function getDriver(): MappingDriver protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService): void { + if (PHP_VERSION_ID < 80400) { + return; + } + + foreach ($class->propertyAccessors as $propertyAccessor) { + $property = $propertyAccessor->getUnderlyingReflector(); + + if ($property->isVirtual()) { + throw MappingException::mappingVirtualPropertyNotAllowed($class->name, $property->getName()); + } + } } protected function initializeReflection(ClassMetadataInterface $class, ReflectionService $reflService): void @@ -241,12 +254,12 @@ private function generateAutoIdGenerator(ClassMetadata $class): void $class->setIdGenerator(new ObjectIdGenerator()); break; case 'uuid': - $reflectionProperty = $class->getReflectionProperty($identifierMapping['fieldName']); - if (! $reflectionProperty->getType() instanceof ReflectionNamedType) { + $type = $class->propertyAccessors[$identifierMapping['fieldName']]->getUnderlyingReflector()->getType(); + if (! $type instanceof ReflectionNamedType) { throw MappingException::autoIdGeneratorNeedsType($class->name, $identifierMapping['fieldName']); } - $class->setIdGenerator(new SymfonyUuidGenerator($reflectionProperty->getType()->getName())); + $class->setIdGenerator(new SymfonyUuidGenerator($type->getName())); break; default: throw MappingException::unsupportedTypeForAutoGenerator( @@ -348,8 +361,8 @@ private function addInheritedFields(ClassMetadata $subClass, ClassMetadata $pare $subClass->addInheritedFieldMapping($mapping); } - foreach ($parentClass->reflFields as $name => $field) { - $subClass->reflFields[$name] = $field; + foreach ($parentClass->propertyAccessors as $name => $field) { + $subClass->propertyAccessors[$name] = $field; } } diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactoryInterface.php b/src/Mapping/ClassMetadataFactoryInterface.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/ClassMetadataFactoryInterface.php rename to src/Mapping/ClassMetadataFactoryInterface.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AnnotationDriver.php b/src/Mapping/Driver/AnnotationDriver.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Driver/AnnotationDriver.php rename to src/Mapping/Driver/AnnotationDriver.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeDriver.php b/src/Mapping/Driver/AttributeDriver.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeDriver.php rename to src/Mapping/Driver/AttributeDriver.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeReader.php b/src/Mapping/Driver/AttributeReader.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Driver/AttributeReader.php rename to src/Mapping/Driver/AttributeReader.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/SimplifiedXmlDriver.php b/src/Mapping/Driver/SimplifiedXmlDriver.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/Driver/SimplifiedXmlDriver.php rename to src/Mapping/Driver/SimplifiedXmlDriver.php diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php b/src/Mapping/Driver/XmlDriver.php similarity index 99% rename from lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php rename to src/Mapping/Driver/XmlDriver.php index 2655649fa5..f0acbfc8b8 100644 --- a/lib/Doctrine/ODM/MongoDB/Mapping/Driver/XmlDriver.php +++ b/src/Mapping/Driver/XmlDriver.php @@ -928,7 +928,7 @@ private function validateSchema(string $filename): void try { libxml_clear_errors(); - if (! $document->schemaValidate(__DIR__ . '/../../../../../../doctrine-mongo-mapping.xsd')) { + if (! $document->schemaValidate(__DIR__ . '/../../../doctrine-mongo-mapping.xsd')) { throw MappingException::xmlMappingFileInvalid($filename, $this->formatErrors(libxml_get_errors())); } } finally { diff --git a/src/Mapping/LegacyReflectionFields.php b/src/Mapping/LegacyReflectionFields.php new file mode 100644 index 0000000000..138f6fa685 --- /dev/null +++ b/src/Mapping/LegacyReflectionFields.php @@ -0,0 +1,136 @@ + + * @template-implements IteratorAggregate + */ +class LegacyReflectionFields implements ArrayAccess, IteratorAggregate, Countable +{ + /** @var array */ + private array $reflFields = []; + + public function __construct(private ClassMetadata $classMetadata, private ReflectionService $reflectionService) + { + } + + /** @param string $offset */ + public function offsetExists($offset): bool // phpcs:ignore + { + trigger_deprecation('doctrine/mongodb-odm', '2.14', 'Access to ClassMetadata::$reflFields is deprecated and will be removed in Doctrine ODM 3.0.'); + + return isset($this->classMetadata->propertyAccessors[$offset]); + } + + /** + * @param string $field + * + * @psalm-suppress LessSpecificImplementedReturnType + */ + public function offsetGet($field): mixed // phpcs:ignore + { + if (isset($this->reflFields[$field])) { + return $this->reflFields[$field]; + } + + trigger_deprecation('doctrine/mongodb-odm', '2.14', 'Access to ClassMetadata::$reflFields is deprecated and will be removed in Doctrine ODM 3.0.'); + + if (! isset($this->classMetadata->propertyAccessors[$field])) { + throw new OutOfBoundsException('Unknown field: ' . $this->classMetadata->name . ' ::$' . $field); + } + + $className = $this->classMetadata->fieldMappings[$field]['inherited'] + ?? $this->classMetadata->fieldMappings[$field]['declared'] + ?? $this->classMetadata->associationMappings[$field]['declared'] + ?? $this->classMetadata->name; + + $this->reflFields[$field] = $this->getAccessibleProperty($className, $field); + + if (isset($this->classMetadata->fieldMappings[$field])) { + if ($this->classMetadata->fieldMappings[$field]['enumType'] ?? null) { + $this->reflFields[$field] = new EnumReflectionProperty( + $this->reflFields[$field], + $this->classMetadata->fieldMappings[$field]['enumType'], + ); + } + } + + return $this->reflFields[$field]; + } + + /** + * @param string $offset + * @param ReflectionProperty $value + */ + public function offsetSet($offset, $value): void // phpcs:ignore + { + $this->reflFields[$offset] = $value; + } + + /** @param string $offset */ + public function offsetUnset($offset): void // phpcs:ignore + { + unset($this->reflFields[$offset]); + } + + /** @psalm-param class-string $class */ + private function getAccessibleProperty(string $class, string $field): ReflectionProperty + { + $reflectionProperty = $this->reflectionService->getAccessibleProperty($class, $field); + + assert($reflectionProperty !== null); + + if ($reflectionProperty->isReadOnly()) { + $declaringClass = $reflectionProperty->class; + if ($declaringClass !== $class) { + $reflectionProperty = $this->reflectionService->getAccessibleProperty($declaringClass, $field); + + assert($reflectionProperty !== null); + } + + $reflectionProperty = new ReflectionReadonlyProperty($reflectionProperty); + } + + return $reflectionProperty; + } + + /** @return Generator */ + public function getIterator(): Traversable + { + trigger_deprecation('doctrine/mongodb-odm', '2.14', 'Access to ClassMetadata::$reflFields is deprecated and will be removed in Doctrine ODM 3.0.'); + + $keys = array_keys($this->classMetadata->propertyAccessors); + + foreach ($keys as $key) { + yield $key => $this->offsetGet($key); + } + } + + public function count(): int + { + trigger_deprecation('doctrine/mongodb-odm', '2.14', 'Access to ClassMetadata::$reflFields is deprecated and will be removed in Doctrine ODM 3.0.'); + + return count($this->classMetadata->propertyAccessors); + } +} diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/MappingException.php b/src/Mapping/MappingException.php similarity index 98% rename from lib/Doctrine/ODM/MongoDB/Mapping/MappingException.php rename to src/Mapping/MappingException.php index abd19c1535..d91b95e5b0 100644 --- a/lib/Doctrine/ODM/MongoDB/Mapping/MappingException.php +++ b/src/Mapping/MappingException.php @@ -337,4 +337,13 @@ public static function autoIdGeneratorNeedsType(string $className, string $ident $identifierFieldName, )); } + + public static function mappingVirtualPropertyNotAllowed(string $entityName, string $propertyName): self + { + return new self(sprintf( + 'Mapping virtual property "%s" on document "%s" is not allowed.', + $propertyName, + $entityName, + )); + } } diff --git a/src/Mapping/PropertyAccessors/EnumPropertyAccessor.php b/src/Mapping/PropertyAccessors/EnumPropertyAccessor.php new file mode 100644 index 0000000000..eba80a3be7 --- /dev/null +++ b/src/Mapping/PropertyAccessors/EnumPropertyAccessor.php @@ -0,0 +1,85 @@ + $enumType */ + public function __construct(private PropertyAccessor $parent, private string $enumType) + { + } + + public function setValue(object $object, mixed $value): void + { + if ($value !== null) { + $value = $this->toEnum($value); + } + + $this->parent->setValue($object, $value); + } + + public function getValue(object $object): mixed + { + $enum = $this->parent->getValue($object); + + if ($enum === null) { + return null; + } + + return $this->fromEnum($enum); + } + + /** + * @param BackedEnum|BackedEnum[] $enum + * + * @return ($enum is BackedEnum ? (string|int) : (string[]|int[])) + */ + private function fromEnum($enum) // phpcs:ignore + { + if (is_array($enum)) { + return array_map(static function (BackedEnum $enum) { + return $enum->value; + }, $enum); + } + + return $enum->value; + } + + /** + * @phpstan-param BackedEnum|BackedEnum[]|int|string|int[]|string[] $value + * + * @return ($value is int|string|BackedEnum ? BackedEnum : BackedEnum[]) + */ + private function toEnum($value): BackedEnum|array + { + if ($value instanceof BackedEnum) { + return $value; + } + + if (is_array($value)) { + $v = reset($value); + if ($v instanceof BackedEnum) { + return $value; + } + + return array_map([$this->enumType, 'from'], $value); + } + + return $this->enumType::from($value); + } + + public function getUnderlyingReflector(): ReflectionProperty + { + return $this->parent->getUnderlyingReflector(); + } +} diff --git a/src/Mapping/PropertyAccessors/ObjectCastPropertyAccessor.php b/src/Mapping/PropertyAccessors/ObjectCastPropertyAccessor.php new file mode 100644 index 0000000000..dced04aed5 --- /dev/null +++ b/src/Mapping/PropertyAccessors/ObjectCastPropertyAccessor.php @@ -0,0 +1,72 @@ +isPrivate() => "\0" . ltrim($class, '\\') . "\0" . $name, + $reflectionProperty->isProtected() => "\0*\0" . $name, + default => $name, + }; + + return new self($reflectionProperty, $key); + } + + public static function fromReflectionProperty(ReflectionProperty $reflectionProperty): self + { + $name = $reflectionProperty->getName(); + + $key = match (true) { + $reflectionProperty->isPrivate() => "\0" . ltrim($reflectionProperty->getDeclaringClass()->getName(), '\\') . "\0" . $name, + $reflectionProperty->isProtected() => "\0*\0" . $name, + default => $name, + }; + + return new self($reflectionProperty, $key); + } + + private function __construct(private ReflectionProperty $reflectionProperty, private string $key) + { + } + + public function setValue(object $object, mixed $value): void + { + if ($object instanceof InternalProxy && ! $object->__isInitialized()) { + $object->__setInitialized(true); + $this->reflectionProperty->setValue($object, $value); + $object->__setInitialized(false); + } elseif ($object instanceof GhostObjectInterface && ! $object->isProxyInitialized()) { + $initializer = $object->getProxyInitializer(); + $object->setProxyInitializer(); + $this->reflectionProperty->setValue($object, $value); + $object->setProxyInitializer($initializer); + } else { + $this->reflectionProperty->setValue($object, $value); + } + } + + public function getValue(object $object): mixed + { + return ((array) $object)[$this->key] ?? null; + } + + public function getUnderlyingReflector(): ReflectionProperty + { + return $this->reflectionProperty; + } +} diff --git a/src/Mapping/PropertyAccessors/PropertyAccessor.php b/src/Mapping/PropertyAccessors/PropertyAccessor.php new file mode 100644 index 0000000000..da46932dfa --- /dev/null +++ b/src/Mapping/PropertyAccessors/PropertyAccessor.php @@ -0,0 +1,27 @@ += 80400 + ? RawValuePropertyAccessor::fromReflectionProperty($reflectionProperty) + : ObjectCastPropertyAccessor::fromReflectionProperty($reflectionProperty); + + if ($reflectionProperty->hasType() && ! $reflectionProperty->getType()->allowsNull()) { + $accessor = new TypedNoDefaultPropertyAccessor($accessor, $reflectionProperty); + } + + if ($reflectionProperty->isReadOnly()) { + $accessor = new ReadonlyAccessor($accessor, $reflectionProperty); + } + + return $accessor; + } +} diff --git a/src/Mapping/PropertyAccessors/RawValuePropertyAccessor.php b/src/Mapping/PropertyAccessors/RawValuePropertyAccessor.php new file mode 100644 index 0000000000..d84beb852b --- /dev/null +++ b/src/Mapping/PropertyAccessors/RawValuePropertyAccessor.php @@ -0,0 +1,72 @@ +getName(); + + $key = match (true) { + $reflectionProperty->isPrivate() => "\0" . ltrim($reflectionProperty->getDeclaringClass()->getName(), '\\') . "\0" . $name, + $reflectionProperty->isProtected() => "\0*\0" . $name, + default => $name, + }; + + return new self($reflectionProperty, $key); + } + + private function __construct(private ReflectionProperty $reflectionProperty, private string $key) + { + if (PHP_VERSION_ID < 80400) { + throw new LogicException('This class requires PHP 8.4 or higher.'); + } + } + + public function setValue(object $object, mixed $value): void + { + if ($object instanceof InternalProxy && ! $object->__isInitialized()) { + $object->__setInitialized(true); + $this->reflectionProperty->setRawValue($object, $value); + $object->__setInitialized(false); + } elseif ($object instanceof GhostObjectInterface && ! $object->isProxyInitialized()) { + $initializer = $object->getProxyInitializer(); + $object->setProxyInitializer(null); + $this->reflectionProperty->setRawValue($object, $value); + $object->setProxyInitializer($initializer); + } else { + $this->reflectionProperty->setRawValueWithoutLazyInitialization($object, $value); + } + } + + public function getValue(object $object): mixed + { + return ((array) $object)[$this->key] ?? null; + } + + public function getUnderlyingReflector(): ReflectionProperty + { + return $this->reflectionProperty; + } +} diff --git a/src/Mapping/PropertyAccessors/ReadonlyAccessor.php b/src/Mapping/PropertyAccessors/ReadonlyAccessor.php new file mode 100644 index 0000000000..4e255aae17 --- /dev/null +++ b/src/Mapping/PropertyAccessors/ReadonlyAccessor.php @@ -0,0 +1,53 @@ +reflectionProperty->isReadOnly()) { + throw new InvalidArgumentException(sprintf( + '%s::$%s must be readonly property', + $this->reflectionProperty->getDeclaringClass()->getName(), + $this->reflectionProperty->getName(), + )); + } + } + + public function setValue(object $object, mixed $value): void + { + if (! $this->reflectionProperty->isInitialized($object)) { + $this->parent->setValue($object, $value); + + return; + } + + if ($this->parent->getValue($object) !== $value) { + throw new LogicException(sprintf( + 'Attempting to change readonly property %s::$%s.', + $this->reflectionProperty->getDeclaringClass()->getName(), + $this->reflectionProperty->getName(), + )); + } + } + + public function getValue(object $object): mixed + { + return $this->parent->getValue($object); + } + + public function getUnderlyingReflector(): ReflectionProperty + { + return $this->reflectionProperty; + } +} diff --git a/src/Mapping/PropertyAccessors/ReflectionReadonlyProperty.php b/src/Mapping/PropertyAccessors/ReflectionReadonlyProperty.php new file mode 100644 index 0000000000..e49b9f876e --- /dev/null +++ b/src/Mapping/PropertyAccessors/ReflectionReadonlyProperty.php @@ -0,0 +1,49 @@ +isReadOnly()) { + throw new InvalidArgumentException('Given property is not readonly.'); + } + + parent::__construct($wrappedProperty->class, $wrappedProperty->name); + } + + public function getValue(object|null $object = null): mixed + { + return $this->wrappedProperty->getValue(...func_get_args()); + } + + public function setValue(mixed $objectOrValue, mixed $value = null): void + { + if (func_num_args() < 2 || $objectOrValue === null || ! $this->isInitialized($objectOrValue)) { + $this->wrappedProperty->setValue(...func_get_args()); + + return; + } + + assert(is_object($objectOrValue)); + + if (parent::getValue($objectOrValue) !== $value) { + throw new LogicException(sprintf('Attempting to change readonly property %s::$%s.', $this->class, $this->name)); + } + } +} diff --git a/src/Mapping/PropertyAccessors/TypedNoDefaultPropertyAccessor.php b/src/Mapping/PropertyAccessors/TypedNoDefaultPropertyAccessor.php new file mode 100644 index 0000000000..027c95644f --- /dev/null +++ b/src/Mapping/PropertyAccessors/TypedNoDefaultPropertyAccessor.php @@ -0,0 +1,69 @@ +reflectionProperty->hasType()) { + throw new InvalidArgumentException(sprintf( + '%s::$%s must have a type when used with TypedNoDefaultPropertyAccessor', + $this->reflectionProperty->getDeclaringClass()->getName(), + $this->reflectionProperty->getName(), + )); + } + + if ($this->reflectionProperty->getType()->allowsNull()) { + throw new InvalidArgumentException(sprintf( + '%s::$%s must not be nullable when used with TypedNoDefaultPropertyAccessor', + $this->reflectionProperty->getDeclaringClass()->getName(), + $this->reflectionProperty->getName(), + )); + } + } + + public function setValue(object $object, mixed $value): void + { + if ($value === null) { + if ($this->unsetter === null) { + $propertyName = $this->reflectionProperty->getName(); + $this->unsetter = function () use ($propertyName): void { + unset($this->$propertyName); + }; + } + + $unsetter = $this->unsetter->bindTo($object, $this->reflectionProperty->getDeclaringClass()->getName()); + + assert($unsetter instanceof Closure); + + $unsetter(); + + return; + } + + $this->parent->setValue($object, $value); + } + + public function getValue(object $object): mixed + { + return $this->reflectionProperty->isInitialized($object) ? $this->parent->getValue($object) : null; + } + + public function getUnderlyingReflector(): ReflectionProperty + { + return $this->reflectionProperty; + } +} diff --git a/lib/Doctrine/ODM/MongoDB/Mapping/TimeSeries/Granularity.php b/src/Mapping/TimeSeries/Granularity.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Mapping/TimeSeries/Granularity.php rename to src/Mapping/TimeSeries/Granularity.php diff --git a/lib/Doctrine/ODM/MongoDB/MongoDBException.php b/src/MongoDBException.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/MongoDBException.php rename to src/MongoDBException.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection.php b/src/PersistentCollection.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection.php rename to src/PersistentCollection.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/AbstractPersistentCollectionFactory.php b/src/PersistentCollection/AbstractPersistentCollectionFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection/AbstractPersistentCollectionFactory.php rename to src/PersistentCollection/AbstractPersistentCollectionFactory.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionFactory.php b/src/PersistentCollection/DefaultPersistentCollectionFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionFactory.php rename to src/PersistentCollection/DefaultPersistentCollectionFactory.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php b/src/PersistentCollection/DefaultPersistentCollectionGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection/DefaultPersistentCollectionGenerator.php rename to src/PersistentCollection/DefaultPersistentCollectionGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionException.php b/src/PersistentCollection/PersistentCollectionException.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionException.php rename to src/PersistentCollection/PersistentCollectionException.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionFactory.php b/src/PersistentCollection/PersistentCollectionFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionFactory.php rename to src/PersistentCollection/PersistentCollectionFactory.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionGenerator.php b/src/PersistentCollection/PersistentCollectionGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionGenerator.php rename to src/PersistentCollection/PersistentCollectionGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionInterface.php b/src/PersistentCollection/PersistentCollectionInterface.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionInterface.php rename to src/PersistentCollection/PersistentCollectionInterface.php diff --git a/lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionTrait.php b/src/PersistentCollection/PersistentCollectionTrait.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/PersistentCollection/PersistentCollectionTrait.php rename to src/PersistentCollection/PersistentCollectionTrait.php diff --git a/lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php b/src/Persisters/CollectionPersister.php similarity index 99% rename from lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php rename to src/Persisters/CollectionPersister.php index 8b99e0ccbf..e65b500a87 100644 --- a/lib/Doctrine/ODM/MongoDB/Persisters/CollectionPersister.php +++ b/src/Persisters/CollectionPersister.php @@ -455,7 +455,7 @@ private function executeQuery(object $document, array $newObj, array $options): $id = $class->getDatabaseIdentifierValue($this->uow->getDocumentIdentifier($document)); $query = ['_id' => $id]; if ($class->isVersioned) { - $query[$class->fieldMappings[$class->versionField]['name']] = $class->reflFields[$class->versionField]->getValue($document); + $query[$class->fieldMappings[$class->versionField]['name']] = $class->propertyAccessors[$class->versionField]->getValue($document); } $collection = $this->dm->getDocumentCollection($className); diff --git a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php b/src/Persisters/DocumentPersister.php similarity index 98% rename from lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php rename to src/Persisters/DocumentPersister.php index 1bf370fc02..c74c668fe5 100644 --- a/lib/Doctrine/ODM/MongoDB/Persisters/DocumentPersister.php +++ b/src/Persisters/DocumentPersister.php @@ -211,12 +211,12 @@ public function executeInserts(array $options = []): void // Set the initial version for each insert if ($this->class->isVersioned) { $versionMapping = $this->class->fieldMappings[$this->class->versionField]; - $nextVersion = $this->class->reflFields[$this->class->versionField]->getValue($document); + $nextVersion = $this->class->propertyAccessors[$this->class->versionField]->getValue($document); $type = Type::getType($versionMapping['type']); assert($type instanceof Versionable); if ($nextVersion === null) { $nextVersion = $type->getNextVersion(null); - $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersion); + $this->class->propertyAccessors[$this->class->versionField]->setValue($document, $nextVersion); } $data[$versionMapping['name']] = $type->convertToDatabaseValue($nextVersion); @@ -289,12 +289,12 @@ private function executeUpsert(object $document, array $options): void // Set the initial version for each upsert if ($this->class->isVersioned) { $versionMapping = $this->class->fieldMappings[$this->class->versionField]; - $nextVersion = $this->class->reflFields[$this->class->versionField]->getValue($document); + $nextVersion = $this->class->propertyAccessors[$this->class->versionField]->getValue($document); $type = Type::getType($versionMapping['type']); assert($type instanceof Versionable); if ($nextVersion === null) { $nextVersion = $type->getNextVersion(null); - $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersion); + $this->class->propertyAccessors[$this->class->versionField]->setValue($document, $nextVersion); } $data['$set'][$versionMapping['name']] = $type->convertToDatabaseValue($nextVersion); @@ -374,7 +374,7 @@ public function update(object $document, array $options = []): void $nextVersion = null; if ($this->class->isVersioned) { $versionMapping = $this->class->fieldMappings[$this->class->versionField]; - $currentVersion = $this->class->reflFields[$this->class->versionField]->getValue($document); + $currentVersion = $this->class->propertyAccessors[$this->class->versionField]->getValue($document); $type = Type::getType($versionMapping['type']); assert($type instanceof Versionable); $nextVersion = $type->getNextVersion($currentVersion); @@ -386,7 +386,7 @@ public function update(object $document, array $options = []): void // Include locking logic so that if the document object in memory is currently // locked then it will remove it, otherwise it ensures the document is not locked. if ($this->class->isLockable) { - $isLocked = $this->class->reflFields[$this->class->lockField]->getValue($document); + $isLocked = $this->class->propertyAccessors[$this->class->lockField]->getValue($document); $lockMapping = $this->class->fieldMappings[$this->class->lockField]; if ($isLocked) { $update['$unset'] = [$lockMapping['name'] => true]; @@ -405,7 +405,7 @@ public function update(object $document, array $options = []): void } if ($this->class->isVersioned) { - $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersion); + $this->class->propertyAccessors[$this->class->versionField]->setValue($document, $nextVersion); } } @@ -615,7 +615,7 @@ public function lock(object $document, int $lockMode): void $lockMapping = $this->class->fieldMappings[$this->class->lockField]; assert($this->collection instanceof Collection); $this->collection->updateOne($criteria, ['$set' => [$lockMapping['name'] => $lockMode]]); - $this->class->reflFields[$this->class->lockField]->setValue($document, $lockMode); + $this->class->propertyAccessors[$this->class->lockField]->setValue($document, $lockMode); } /** @@ -628,7 +628,7 @@ public function unlock(object $document): void $lockMapping = $this->class->fieldMappings[$this->class->lockField]; assert($this->collection instanceof Collection); $this->collection->updateOne($criteria, ['$unset' => [$lockMapping['name'] => true]]); - $this->class->reflFields[$this->class->lockField]->setValue($document, null); + $this->class->propertyAccessors[$this->class->lockField]->setValue($document, null); } /** diff --git a/lib/Doctrine/ODM/MongoDB/Persisters/PersistenceBuilder.php b/src/Persisters/PersistenceBuilder.php similarity index 99% rename from lib/Doctrine/ODM/MongoDB/Persisters/PersistenceBuilder.php rename to src/Persisters/PersistenceBuilder.php index beb53ee47f..130269412c 100644 --- a/lib/Doctrine/ODM/MongoDB/Persisters/PersistenceBuilder.php +++ b/src/Persisters/PersistenceBuilder.php @@ -366,8 +366,7 @@ public function prepareEmbeddedDocumentValue(array $embeddedMapping, $embeddedDo continue; } - // Inline ClassMetadata::getFieldValue() - $rawValue = $class->reflFields[$mapping['fieldName']]->getValue($embeddedDocument); + $rawValue = $class->propertyAccessors[$mapping['fieldName']]->getValue($embeddedDocument); $value = null; diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/Autoloader.php b/src/Proxy/Autoloader.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/Autoloader.php rename to src/Proxy/Autoloader.php diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/Factory/LazyGhostProxyFactory.php b/src/Proxy/Factory/LazyGhostProxyFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/Factory/LazyGhostProxyFactory.php rename to src/Proxy/Factory/LazyGhostProxyFactory.php diff --git a/src/Proxy/Factory/NativeLazyObjectFactory.php b/src/Proxy/Factory/NativeLazyObjectFactory.php new file mode 100644 index 0000000000..35552cfb6d --- /dev/null +++ b/src/Proxy/Factory/NativeLazyObjectFactory.php @@ -0,0 +1,97 @@ +|null */ + private static ?WeakMap $lazyObjects = null; + + private readonly UnitOfWork $unitOfWork; + private readonly LifecycleEventManager $lifecycleEventManager; + + public function __construct( + DocumentManager $documentManager, + ) { + if (PHP_VERSION_ID < 80400) { + throw new LogicException('Native lazy objects require PHP 8.4 or higher.'); + } + + $this->unitOfWork = $documentManager->getUnitOfWork(); + $this->lifecycleEventManager = new LifecycleEventManager($documentManager, $this->unitOfWork, $documentManager->getEventManager()); + } + + public function generateProxyClasses(array $classes): int + { + // Nothing to generate, that's the point of native lazy objects + + return count($classes); + } + + public function getProxy(ClassMetadata $metadata, $identifier): object + { + $proxy = $metadata->reflClass->newLazyGhost(function (object $object) use ( + $identifier, + $metadata, + ): void { + $original = $this->unitOfWork->getDocumentPersister($metadata->name)->load([$metadata->identifier => $identifier], $object); + + if ($object instanceof NotifyPropertyChanged) { + $object->addPropertyChangedListener($this->unitOfWork); + } + + if ($original !== null) { + return; + } + + if (! $this->lifecycleEventManager->documentNotFound($object, $identifier)) { + throw DocumentNotFoundException::documentNotFound($metadata->name, $identifier); + } + }, ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE); + + $metadata->propertyAccessors[$metadata->identifier]->setValue($proxy, $identifier); + + if (isset(self::$lazyObjects)) { + self::$lazyObjects[$proxy] = true; + } + + return $proxy; + } + + /** @internal Only for tests */ + public static function enableTracking(bool $enabled = true): void + { + if ($enabled) { + self::$lazyObjects ??= new WeakMap(); + } else { + self::$lazyObjects = null; + } + } + + /** @internal Only for tests */ + public static function isLazyObject(object $object): bool + { + if (! isset(self::$lazyObjects)) { + throw new LogicException('Lazy object tracking is not enabled.'); + } + + return self::$lazyObjects->offsetExists($object); + } +} diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/Factory/ProxyFactory.php b/src/Proxy/Factory/ProxyFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/Factory/ProxyFactory.php rename to src/Proxy/Factory/ProxyFactory.php diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/Factory/StaticProxyFactory.php b/src/Proxy/Factory/StaticProxyFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/Factory/StaticProxyFactory.php rename to src/Proxy/Factory/StaticProxyFactory.php diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/FileLocator.php b/src/Proxy/FileLocator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/FileLocator.php rename to src/Proxy/FileLocator.php diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/InternalProxy.php b/src/Proxy/InternalProxy.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/InternalProxy.php rename to src/Proxy/InternalProxy.php diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/Resolver/CachingClassNameResolver.php b/src/Proxy/Resolver/CachingClassNameResolver.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/Resolver/CachingClassNameResolver.php rename to src/Proxy/Resolver/CachingClassNameResolver.php diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/Resolver/ClassNameResolver.php b/src/Proxy/Resolver/ClassNameResolver.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/Resolver/ClassNameResolver.php rename to src/Proxy/Resolver/ClassNameResolver.php diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/Resolver/LazyGhostProxyClassNameResolver.php b/src/Proxy/Resolver/LazyGhostProxyClassNameResolver.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/Resolver/LazyGhostProxyClassNameResolver.php rename to src/Proxy/Resolver/LazyGhostProxyClassNameResolver.php diff --git a/lib/Doctrine/ODM/MongoDB/Proxy/Resolver/ProxyManagerClassNameResolver.php b/src/Proxy/Resolver/ProxyManagerClassNameResolver.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Proxy/Resolver/ProxyManagerClassNameResolver.php rename to src/Proxy/Resolver/ProxyManagerClassNameResolver.php diff --git a/lib/Doctrine/ODM/MongoDB/Query/Builder.php b/src/Query/Builder.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Query/Builder.php rename to src/Query/Builder.php diff --git a/lib/Doctrine/ODM/MongoDB/Query/CriteriaMerger.php b/src/Query/CriteriaMerger.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Query/CriteriaMerger.php rename to src/Query/CriteriaMerger.php diff --git a/lib/Doctrine/ODM/MongoDB/Query/Expr.php b/src/Query/Expr.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Query/Expr.php rename to src/Query/Expr.php diff --git a/lib/Doctrine/ODM/MongoDB/Query/Filter/BsonFilter.php b/src/Query/Filter/BsonFilter.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Query/Filter/BsonFilter.php rename to src/Query/Filter/BsonFilter.php diff --git a/lib/Doctrine/ODM/MongoDB/Query/FilterCollection.php b/src/Query/FilterCollection.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Query/FilterCollection.php rename to src/Query/FilterCollection.php diff --git a/lib/Doctrine/ODM/MongoDB/Query/Query.php b/src/Query/Query.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Query/Query.php rename to src/Query/Query.php diff --git a/lib/Doctrine/ODM/MongoDB/Query/QueryExpressionVisitor.php b/src/Query/QueryExpressionVisitor.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Query/QueryExpressionVisitor.php rename to src/Query/QueryExpressionVisitor.php diff --git a/lib/Doctrine/ODM/MongoDB/Query/ReferencePrimer.php b/src/Query/ReferencePrimer.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Query/ReferencePrimer.php rename to src/Query/ReferencePrimer.php diff --git a/lib/Doctrine/ODM/MongoDB/Repository/AbstractRepositoryFactory.php b/src/Repository/AbstractRepositoryFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Repository/AbstractRepositoryFactory.php rename to src/Repository/AbstractRepositoryFactory.php diff --git a/lib/Doctrine/ODM/MongoDB/Repository/DefaultGridFSRepository.php b/src/Repository/DefaultGridFSRepository.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Repository/DefaultGridFSRepository.php rename to src/Repository/DefaultGridFSRepository.php diff --git a/lib/Doctrine/ODM/MongoDB/Repository/DefaultRepositoryFactory.php b/src/Repository/DefaultRepositoryFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Repository/DefaultRepositoryFactory.php rename to src/Repository/DefaultRepositoryFactory.php diff --git a/lib/Doctrine/ODM/MongoDB/Repository/DocumentRepository.php b/src/Repository/DocumentRepository.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Repository/DocumentRepository.php rename to src/Repository/DocumentRepository.php diff --git a/lib/Doctrine/ODM/MongoDB/Repository/GridFSRepository.php b/src/Repository/GridFSRepository.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Repository/GridFSRepository.php rename to src/Repository/GridFSRepository.php diff --git a/lib/Doctrine/ODM/MongoDB/Repository/RepositoryFactory.php b/src/Repository/RepositoryFactory.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Repository/RepositoryFactory.php rename to src/Repository/RepositoryFactory.php diff --git a/lib/Doctrine/ODM/MongoDB/Repository/UploadOptions.php b/src/Repository/UploadOptions.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Repository/UploadOptions.php rename to src/Repository/UploadOptions.php diff --git a/lib/Doctrine/ODM/MongoDB/Repository/ViewRepository.php b/src/Repository/ViewRepository.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Repository/ViewRepository.php rename to src/Repository/ViewRepository.php diff --git a/lib/Doctrine/ODM/MongoDB/SchemaException.php b/src/SchemaException.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/SchemaException.php rename to src/SchemaException.php diff --git a/lib/Doctrine/ODM/MongoDB/SchemaManager.php b/src/SchemaManager.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/SchemaManager.php rename to src/SchemaManager.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/ClearCache/MetadataCommand.php b/src/Tools/Console/Command/ClearCache/MetadataCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/ClearCache/MetadataCommand.php rename to src/Tools/Console/Command/ClearCache/MetadataCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/CommandCompatibility.php b/src/Tools/Console/Command/CommandCompatibility.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/CommandCompatibility.php rename to src/Tools/Console/Command/CommandCompatibility.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateHydratorsCommand.php b/src/Tools/Console/Command/GenerateHydratorsCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateHydratorsCommand.php rename to src/Tools/Console/Command/GenerateHydratorsCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GeneratePersistentCollectionsCommand.php b/src/Tools/Console/Command/GeneratePersistentCollectionsCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GeneratePersistentCollectionsCommand.php rename to src/Tools/Console/Command/GeneratePersistentCollectionsCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateProxiesCommand.php b/src/Tools/Console/Command/GenerateProxiesCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/GenerateProxiesCommand.php rename to src/Tools/Console/Command/GenerateProxiesCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/QueryCommand.php b/src/Tools/Console/Command/QueryCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/QueryCommand.php rename to src/Tools/Console/Command/QueryCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/AbstractCommand.php b/src/Tools/Console/Command/Schema/AbstractCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/AbstractCommand.php rename to src/Tools/Console/Command/Schema/AbstractCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/CreateCommand.php b/src/Tools/Console/Command/Schema/CreateCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/CreateCommand.php rename to src/Tools/Console/Command/Schema/CreateCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/DropCommand.php b/src/Tools/Console/Command/Schema/DropCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/DropCommand.php rename to src/Tools/Console/Command/Schema/DropCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/ShardCommand.php b/src/Tools/Console/Command/Schema/ShardCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/ShardCommand.php rename to src/Tools/Console/Command/Schema/ShardCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/UpdateCommand.php b/src/Tools/Console/Command/Schema/UpdateCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/UpdateCommand.php rename to src/Tools/Console/Command/Schema/UpdateCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/ValidateCommand.php b/src/Tools/Console/Command/Schema/ValidateCommand.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Command/Schema/ValidateCommand.php rename to src/Tools/Console/Command/Schema/ValidateCommand.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/Helper/DocumentManagerHelper.php b/src/Tools/Console/Helper/DocumentManagerHelper.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/Helper/DocumentManagerHelper.php rename to src/Tools/Console/Helper/DocumentManagerHelper.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/Console/MetadataFilter.php b/src/Tools/Console/MetadataFilter.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/Console/MetadataFilter.php rename to src/Tools/Console/MetadataFilter.php diff --git a/lib/Doctrine/ODM/MongoDB/Tools/ResolveTargetDocumentListener.php b/src/Tools/ResolveTargetDocumentListener.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Tools/ResolveTargetDocumentListener.php rename to src/Tools/ResolveTargetDocumentListener.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/AbstractVectorType.php b/src/Types/AbstractVectorType.php similarity index 84% rename from lib/Doctrine/ODM/MongoDB/Types/AbstractVectorType.php rename to src/Types/AbstractVectorType.php index aeeb62e775..dbc472b776 100644 --- a/lib/Doctrine/ODM/MongoDB/Types/AbstractVectorType.php +++ b/src/Types/AbstractVectorType.php @@ -77,27 +77,17 @@ public function closureToMongo(): string return str_replace('%%vectorType%%', $this->getVectorType()->name, <<<'PHP' if ($value === null) { $return = null; - return; - } - - if (\is_array($value)) { + } elseif (\is_array($value)) { $return = \MongoDB\BSON\Binary::fromVector($value, \MongoDB\BSON\VectorType::%%vectorType%%); - return; - } - - if (! $value instanceof \MongoDB\BSON\Binary) { + } elseif (! $value instanceof \MongoDB\BSON\Binary) { throw new InvalidArgumentException(sprintf('Invalid data type %s received for vector field, expected null, array or MongoDB\BSON\Binary', get_debug_type($value))); - } - - if ($value->getType() !== \MongoDB\BSON\Binary::TYPE_VECTOR) { + } elseif ($value->getType() !== \MongoDB\BSON\Binary::TYPE_VECTOR) { throw new InvalidArgumentException(sprintf('Invalid binary data of type %d received for vector field, expected binary type %d', $value->getType(), \MongoDB\BSON\Binary::TYPE_VECTOR)); - } - - if ($value->getVectorType() !== \MongoDB\BSON\VectorType::%%vectorType%%) { + } elseif ($value->getVectorType() !== \MongoDB\BSON\VectorType::%%vectorType%%) { throw new \InvalidArgumentException(sprintf('Invalid binary vector data of vector type %s received for vector field, expected vector type %%vectorType%%', $value->getVectorType()->name)); + } else { + $return = $value; } - - $return = $value; PHP); } @@ -106,27 +96,17 @@ public function closureToPHP(): string return str_replace('%%vectorType%%', $this->getVectorType()->name, <<<'PHP' if ($value === null) { $return = null; - return; - } - - if (\is_array($value)) { + } elseif (\is_array($value)) { $return = $value; - return; - } - - if (! $value instanceof \MongoDB\BSON\Binary) { + } elseif (! $value instanceof \MongoDB\BSON\Binary) { throw new \InvalidArgumentException(sprintf('Invalid data of type "%s" received for vector field', get_debug_type($value))); - } - - if ($value->getType() !== \MongoDB\BSON\Binary::TYPE_VECTOR) { + } elseif ($value->getType() !== \MongoDB\BSON\Binary::TYPE_VECTOR) { throw new \InvalidArgumentException(sprintf('Invalid binary data of type %d received for vector field', $value->getType())); - } - - if ($value->getVectorType() !== \MongoDB\BSON\VectorType::%%vectorType%%) { + } elseif ($value->getVectorType() !== \MongoDB\BSON\VectorType::%%vectorType%%) { throw new \InvalidArgumentException(sprintf('Invalid binary vector data of vector type %s received for vector field, expected vector type %%vectorType%%', $value->getVectorType()->name)); + } else { + $return = $value->toArray(); } - - $return = $value->toArray(); PHP); } diff --git a/lib/Doctrine/ODM/MongoDB/Types/BinDataByteArrayType.php b/src/Types/BinDataByteArrayType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/BinDataByteArrayType.php rename to src/Types/BinDataByteArrayType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/BinDataCustomType.php b/src/Types/BinDataCustomType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/BinDataCustomType.php rename to src/Types/BinDataCustomType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/BinDataFuncType.php b/src/Types/BinDataFuncType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/BinDataFuncType.php rename to src/Types/BinDataFuncType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/BinDataMD5Type.php b/src/Types/BinDataMD5Type.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/BinDataMD5Type.php rename to src/Types/BinDataMD5Type.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/BinDataType.php b/src/Types/BinDataType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/BinDataType.php rename to src/Types/BinDataType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/BinDataUUIDRFC4122Type.php b/src/Types/BinDataUUIDRFC4122Type.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/BinDataUUIDRFC4122Type.php rename to src/Types/BinDataUUIDRFC4122Type.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/BinDataUUIDType.php b/src/Types/BinDataUUIDType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/BinDataUUIDType.php rename to src/Types/BinDataUUIDType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/BinaryUuidType.php b/src/Types/BinaryUuidType.php similarity index 90% rename from lib/Doctrine/ODM/MongoDB/Types/BinaryUuidType.php rename to src/Types/BinaryUuidType.php index 0038dfc7f2..2c257e27b4 100644 --- a/lib/Doctrine/ODM/MongoDB/Types/BinaryUuidType.php +++ b/src/Types/BinaryUuidType.php @@ -60,18 +60,13 @@ public function closureToPHP(): string return <<<'PHP' if ($value instanceof \Symfony\Component\Uid\Uuid) { $return = $value; - return; - } - - if (! $value instanceof \MongoDB\BSON\Binary) { + } elseif (! $value instanceof \MongoDB\BSON\Binary) { throw new \InvalidArgumentException(sprintf('Invalid data of type "%s" received for Uuid', get_debug_type($value))); - } - - if ($value->getType() !== \MongoDB\BSON\Binary::TYPE_UUID) { + } elseif ($value->getType() !== \MongoDB\BSON\Binary::TYPE_UUID) { throw new \InvalidArgumentException(sprintf('Invalid binary data of type %d received for Uuid', $value->getType())); + } else { + $return = \Symfony\Component\Uid\Uuid::fromBinary($value->getData()); } - - $return = \Symfony\Component\Uid\Uuid::fromBinary($value->getData()); PHP; } } diff --git a/lib/Doctrine/ODM/MongoDB/Types/BooleanType.php b/src/Types/BooleanType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/BooleanType.php rename to src/Types/BooleanType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/ClosureToPHP.php b/src/Types/ClosureToPHP.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/ClosureToPHP.php rename to src/Types/ClosureToPHP.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/CollectionType.php b/src/Types/CollectionType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/CollectionType.php rename to src/Types/CollectionType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/CustomIdType.php b/src/Types/CustomIdType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/CustomIdType.php rename to src/Types/CustomIdType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/DateImmutableType.php b/src/Types/DateImmutableType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/DateImmutableType.php rename to src/Types/DateImmutableType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/DateType.php b/src/Types/DateType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/DateType.php rename to src/Types/DateType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/Decimal128Type.php b/src/Types/Decimal128Type.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/Decimal128Type.php rename to src/Types/Decimal128Type.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/FloatType.php b/src/Types/FloatType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/FloatType.php rename to src/Types/FloatType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/HashType.php b/src/Types/HashType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/HashType.php rename to src/Types/HashType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/IdType.php b/src/Types/IdType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/IdType.php rename to src/Types/IdType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/Incrementable.php b/src/Types/Incrementable.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/Incrementable.php rename to src/Types/Incrementable.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/Int64Type.php b/src/Types/Int64Type.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/Int64Type.php rename to src/Types/Int64Type.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/IntIdType.php b/src/Types/IntIdType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/IntIdType.php rename to src/Types/IntIdType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/IntType.php b/src/Types/IntType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/IntType.php rename to src/Types/IntType.php diff --git a/src/Types/InvalidTypeException.php b/src/Types/InvalidTypeException.php new file mode 100644 index 0000000000..defe905e79 --- /dev/null +++ b/src/Types/InvalidTypeException.php @@ -0,0 +1,17 @@ + self::getType(self::INT), + 'boolean' => self::getType(self::BOOL), + 'double' => self::getType(self::FLOAT), + 'string' => self::getType(self::STRING), + default => null, + }; } /** diff --git a/lib/Doctrine/ODM/MongoDB/Types/VectorFloat32Type.php b/src/Types/VectorFloat32Type.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/VectorFloat32Type.php rename to src/Types/VectorFloat32Type.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/VectorInt8Type.php b/src/Types/VectorInt8Type.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/VectorInt8Type.php rename to src/Types/VectorInt8Type.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/VectorPackedBitType.php b/src/Types/VectorPackedBitType.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/VectorPackedBitType.php rename to src/Types/VectorPackedBitType.php diff --git a/lib/Doctrine/ODM/MongoDB/Types/Versionable.php b/src/Types/Versionable.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Types/Versionable.php rename to src/Types/Versionable.php diff --git a/lib/Doctrine/ODM/MongoDB/UnitOfWork.php b/src/UnitOfWork.php similarity index 97% rename from lib/Doctrine/ODM/MongoDB/UnitOfWork.php rename to src/UnitOfWork.php index f6b9b28c25..47fb4233ab 100644 --- a/lib/Doctrine/ODM/MongoDB/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -52,6 +52,8 @@ use function sprintf; use function trigger_deprecation; +use const PHP_VERSION_ID; + /** * The UnitOfWork is responsible for tracking changes to objects during an * "object-level" transaction and for writing out changes to the database @@ -616,7 +618,7 @@ public function getDocumentActualData(object $document): array { $class = $this->dm->getClassMetadata($document::class); $actualData = []; - foreach ($class->reflFields as $name => $refProp) { + foreach ($class->propertyAccessors as $name => $refProp) { $mapping = $class->fieldMappings[$name]; // skip not saved fields if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) { @@ -637,7 +639,7 @@ public function getDocumentActualData(object $document): array $coll = $this->dm->getConfiguration()->getPersistentCollectionFactory()->create($this->dm, $mapping, $value); $coll->setOwner($document, $mapping); $coll->setDirty(! $value->isEmpty()); - $class->reflFields[$name]->setValue($document, $coll); + $class->propertyAccessors[$name]->setValue($document, $coll); $actualData[$name] = $coll; } else { $actualData[$name] = $value; @@ -863,7 +865,7 @@ private function computeOrRecomputeChangeSet(ClassMetadata $class, object $docum ); foreach ($associationMappings as $mapping) { - $value = $class->reflFields[$mapping['fieldName']]->getValue($document); + $value = $class->propertyAccessors[$mapping['fieldName']]->getValue($document); if ($value === null) { continue; @@ -1274,7 +1276,7 @@ private function executeDeletions(ClassMetadata $class, array $documents, array continue; } - $value = $class->reflFields[$fieldMapping['fieldName']]->getValue($document); + $value = $class->propertyAccessors[$fieldMapping['fieldName']]->getValue($document); if (! ($value instanceof PersistentCollectionInterface)) { continue; } @@ -1938,8 +1940,8 @@ private function doMerge(object $document, array &$visited, ?object $prevManaged } if ($class->isVersioned) { - $managedCopyVersion = $class->reflFields[$class->versionField]->getValue($managedCopy); - $documentVersion = $class->reflFields[$class->versionField]->getValue($document); + $managedCopyVersion = $class->propertyAccessors[$class->versionField]->getValue($managedCopy); + $documentVersion = $class->propertyAccessors[$class->versionField]->getValue($document); // Throw exception if versions don't match if ($managedCopyVersion !== $documentVersion) { @@ -1990,7 +1992,7 @@ private function doMerge(object $document, array &$visited, ?object $prevManaged ->dm ->getProxyFactory() ->getProxy($targetClass, $relatedId); - $this->registerManaged($other, $relatedId, []); + $this->registerManaged($other, $relatedId, [$targetClass->identifier => $relatedId]); } } @@ -2054,12 +2056,12 @@ private function doMerge(object $document, array &$visited, ?object $prevManaged $prevClass = $this->dm->getClassMetadata($prevManagedCopy::class); if ($assoc['type'] === ClassMetadata::ONE) { - $prevClass->reflFields[$assocField]->setValue($prevManagedCopy, $managedCopy); + $prevClass->propertyAccessors[$assocField]->setValue($prevManagedCopy, $managedCopy); } else { - $prevClass->reflFields[$assocField]->getValue($prevManagedCopy)->add($managedCopy); + $prevClass->propertyAccessors[$assocField]->getValue($prevManagedCopy)->add($managedCopy); if ($assoc['type'] === ClassMetadata::MANY && isset($assoc['mappedBy'])) { - $class->reflFields[$assoc['mappedBy']]->setValue($managedCopy, $prevManagedCopy); + $class->propertyAccessors[$assoc['mappedBy']]->setValue($managedCopy, $prevManagedCopy); } } } @@ -2180,7 +2182,7 @@ private function cascadeRefresh(object $document, array &$visited): void ); foreach ($associationMappings as $mapping) { - $relatedDocuments = $class->reflFields[$mapping['fieldName']]->getValue($document); + $relatedDocuments = $class->propertyAccessors[$mapping['fieldName']]->getValue($document); if ($relatedDocuments instanceof Collection || is_array($relatedDocuments)) { if ($relatedDocuments instanceof PersistentCollectionInterface) { // Unwrap so that foreach() does not initialize @@ -2209,7 +2211,7 @@ private function cascadeDetach(object $document, array &$visited): void continue; } - $relatedDocuments = $class->reflFields[$mapping['fieldName']]->getValue($document); + $relatedDocuments = $class->propertyAccessors[$mapping['fieldName']]->getValue($document); if ($relatedDocuments instanceof Collection || is_array($relatedDocuments)) { if ($relatedDocuments instanceof PersistentCollectionInterface) { // Unwrap so that foreach() does not initialize @@ -2240,10 +2242,10 @@ private function cascadeMerge(object $document, object $managedCopy, array &$vis ); foreach ($associationMappings as $assoc) { - $relatedDocuments = $class->reflFields[$assoc['fieldName']]->getValue($document); + $relatedDocuments = $class->propertyAccessors[$assoc['fieldName']]->getValue($document); if ($relatedDocuments instanceof Collection || is_array($relatedDocuments)) { - if ($relatedDocuments === $class->reflFields[$assoc['fieldName']]->getValue($managedCopy)) { + if ($relatedDocuments === $class->propertyAccessors[$assoc['fieldName']]->getValue($managedCopy)) { // Collections are the same, so there is nothing to do continue; } @@ -2272,7 +2274,7 @@ private function cascadePersist(object $document, array &$visited): void ); foreach ($associationMappings as $fieldName => $mapping) { - $relatedDocuments = $class->reflFields[$fieldName]->getValue($document); + $relatedDocuments = $class->propertyAccessors[$fieldName]->getValue($document); if ($relatedDocuments instanceof Collection || is_array($relatedDocuments)) { if ($relatedDocuments instanceof PersistentCollectionInterface) { @@ -2330,7 +2332,7 @@ private function cascadeRemove(object $document, array &$visited): void $this->initializeObject($document); - $relatedDocuments = $class->reflFields[$mapping['fieldName']]->getValue($document); + $relatedDocuments = $class->propertyAccessors[$mapping['fieldName']]->getValue($document); if ($relatedDocuments instanceof Collection || is_array($relatedDocuments)) { // If its a PersistentCollection initialization is intended! No unwrap! foreach ($relatedDocuments as $relatedDocument) { @@ -2365,7 +2367,7 @@ public function lock(object $document, int $lockMode, ?int $lockVersion = null): } if ($lockVersion !== null) { - $documentVersion = $class->reflFields[$class->versionField]->getValue($document); + $documentVersion = $class->propertyAccessors[$class->versionField]->getValue($document); if ($documentVersion !== $lockVersion) { throw LockException::lockFailedVersionMissmatch($document, $lockVersion, $documentVersion); } @@ -2483,7 +2485,7 @@ private function fixPersistentCollectionOwnership(PersistentCollectionInterface $this->initializeObject($coll); // we have to do this otherwise the cols share state $newValue = clone $coll; $newValue->setOwner($document, $class->fieldMappings[$propName]); - $class->reflFields[$propName]->setValue($document, $newValue); + $class->propertyAccessors[$propName]->setValue($document, $newValue); if ($this->isScheduledForUpdate($document)) { // @todo following line should be superfluous once collections are stored in change sets $this->setOriginalDocumentProperty(spl_object_id($document), $propName, $newValue); @@ -2783,12 +2785,14 @@ public function getOrCreateDocument(string $className, array $data, array &$hint $document = $this->identityMap[$class->name][$serializedId]; $oid = spl_object_id($document); if ($this->isUninitializedObject($document)) { - if ($document instanceof InternalProxy) { + if ($this->dm->getConfiguration()->isNativeLazyObjectEnabled()) { + $class->reflClass->markLazyObjectAsInitialized($document); + } elseif ($document instanceof InternalProxy) { $document->__setInitialized(true); } elseif ($document instanceof GhostObjectInterface) { $document->setProxyInitializer(null); } else { - throw new \RuntimeException(sprintf('Expected uninitialized proxy or ghost object from class "%s"', $document::name)); + throw new \RuntimeException(sprintf('Expected uninitialized proxy or ghost object from class "%s"', $document::class)); } $overrideLocalValues = true; @@ -3076,6 +3080,8 @@ public function initializeObject(object $obj): void $obj->initializeProxy(); } elseif ($obj instanceof PersistentCollectionInterface) { $obj->initialize(); + } elseif (PHP_VERSION_ID >= 80400) { + $this->dm->getClassMetadata($obj::class)->reflClass->initializeLazyObject($obj); } } @@ -3087,9 +3093,10 @@ public function initializeObject(object $obj): void public function isUninitializedObject(object $obj): bool { return match (true) { - $obj instanceof InternalProxy => $obj->__isInitialized() === false, - $obj instanceof GhostObjectInterface => $obj->isProxyInitialized() === false, - $obj instanceof PersistentCollectionInterface => $obj->isInitialized() === false, + $obj instanceof InternalProxy => ! $obj->__isInitialized(), + $obj instanceof GhostObjectInterface => ! $obj->isProxyInitialized(), + $obj instanceof PersistentCollectionInterface => ! $obj->isInitialized(), + $this->dm->getConfiguration()->isNativeLazyObjectEnabled() => $this->dm->getClassMetadata($obj::class)->reflClass->isUninitializedLazyObject($obj), default => false }; } diff --git a/lib/Doctrine/ODM/MongoDB/Utility/CollectionHelper.php b/src/Utility/CollectionHelper.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Utility/CollectionHelper.php rename to src/Utility/CollectionHelper.php diff --git a/lib/Doctrine/ODM/MongoDB/Utility/EncryptedFieldsMapGenerator.php b/src/Utility/EncryptedFieldsMapGenerator.php similarity index 100% rename from lib/Doctrine/ODM/MongoDB/Utility/EncryptedFieldsMapGenerator.php rename to src/Utility/EncryptedFieldsMapGenerator.php diff --git a/lib/Doctrine/ODM/MongoDB/Utility/LifecycleEventManager.php b/src/Utility/LifecycleEventManager.php similarity index 97% rename from lib/Doctrine/ODM/MongoDB/Utility/LifecycleEventManager.php rename to src/Utility/LifecycleEventManager.php index ca7ef6691d..4214c01568 100644 --- a/lib/Doctrine/ODM/MongoDB/Utility/LifecycleEventManager.php +++ b/src/Utility/LifecycleEventManager.php @@ -213,7 +213,7 @@ public function preUpdate(ClassMetadata $class, object $document, ?Session $sess private function cascadePreUpdate(ClassMetadata $class, object $document, ?Session $session = null): void { foreach ($class->getEmbeddedFieldsMappings() as $mapping) { - $value = $class->reflFields[$mapping['fieldName']]->getValue($document); + $value = $class->propertyAccessors[$mapping['fieldName']]->getValue($document); if ($value === null) { continue; } @@ -241,7 +241,7 @@ private function cascadePreUpdate(ClassMetadata $class, object $document, ?Sessi private function cascadePostUpdate(ClassMetadata $class, object $document, ?Session $session = null): void { foreach ($class->getEmbeddedFieldsMappings() as $mapping) { - $value = $class->reflFields[$mapping['fieldName']]->getValue($document); + $value = $class->propertyAccessors[$mapping['fieldName']]->getValue($document); if ($value === null) { continue; } @@ -281,7 +281,7 @@ private function cascadePostUpdate(ClassMetadata $class, object $document, ?Sess private function cascadePostPersist(ClassMetadata $class, object $document, ?Session $session = null): void { foreach ($class->getEmbeddedFieldsMappings() as $mapping) { - $value = $class->reflFields[$mapping['fieldName']]->getValue($document); + $value = $class->propertyAccessors[$mapping['fieldName']]->getValue($document); if ($value === null) { continue; } diff --git a/tests/Documentation/CustomMapping/CustomMappingTest.php b/tests/Documentation/CustomMapping/CustomMappingTest.php index 956f9701cf..54b515b167 100644 --- a/tests/Documentation/CustomMapping/CustomMappingTest.php +++ b/tests/Documentation/CustomMapping/CustomMappingTest.php @@ -8,9 +8,18 @@ use DateTimeZone; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; use Doctrine\ODM\MongoDB\Types\Type; +use PHPUnit\Framework\Attributes\After; +use ReflectionProperty; class CustomMappingTest extends BaseTestCase { + #[After] + public function restoreTypeMap(): void + { + $r = new ReflectionProperty(Type::class, 'typesMap'); + $r->setValue(null, $r->getDefaultValue()); + } + public function testTest(): void { Type::addType('date_with_timezone', DateTimeWithTimezoneType::class); diff --git a/tests/Documentation/CustomMapping/DateTimeWithTimezoneType.php b/tests/Documentation/CustomMapping/DateTimeWithTimezoneType.php index 39e2395a05..26ee750e4c 100644 --- a/tests/Documentation/CustomMapping/DateTimeWithTimezoneType.php +++ b/tests/Documentation/CustomMapping/DateTimeWithTimezoneType.php @@ -5,13 +5,15 @@ namespace Documentation\CustomMapping; use DateTimeImmutable; -use DateTimeInterface; use DateTimeZone; use Doctrine\ODM\MongoDB\Types\ClosureToPHP; use Doctrine\ODM\MongoDB\Types\Type; use MongoDB\BSON\UTCDateTime; use RuntimeException; +use function gettype; +use function sprintf; + class DateTimeWithTimezoneType extends Type { // This trait provides default closureToPHP used during data hydration @@ -32,13 +34,18 @@ public function convertToPHPValue($value): DateTimeImmutable return DateTimeImmutable::createFromMutable($dateTime); } - /** - * @param DateTimeInterface $value - * - * @return array{utc: UTCDateTime, tz: string} - */ + /** @return array{utc: UTCDateTime, tz: string} */ public function convertToDatabaseValue($value): array { + if (! $value instanceof DateTimeImmutable) { + throw new RuntimeException( + sprintf( + 'Expected instance of \DateTimeImmutable, got %s', + gettype($value), + ), + ); + } + return [ 'utc' => new UTCDateTime($value), 'tz' => $value->getTimezone()->getName(), diff --git a/tests/Documents/BaseDocument.php b/tests/Documents/BaseDocument.php index b107762f35..0f9d335bf8 100644 --- a/tests/Documents/BaseDocument.php +++ b/tests/Documents/BaseDocument.php @@ -15,7 +15,7 @@ abstract class BaseDocument /** @var string|null */ #[ODM\Field(type: 'string')] - protected $inheritedProperty; + private $inheritedProperty; public function setInheritedProperty(string $value): void { diff --git a/tests/Documents/ForumAvatar.php b/tests/Documents/ForumAvatar.php index 1dc18f24f2..c0187a6c6b 100644 --- a/tests/Documents/ForumAvatar.php +++ b/tests/Documents/ForumAvatar.php @@ -9,7 +9,9 @@ #[ODM\Document] class ForumAvatar { - /** @var string|null */ #[ODM\Id] - public $id; + public ?string $id; + + #[ODM\Field] + public ?string $url = null; } diff --git a/tests/Documents/ForumStar.php b/tests/Documents/ForumStar.php new file mode 100644 index 0000000000..df3fb2ad43 --- /dev/null +++ b/tests/Documents/ForumStar.php @@ -0,0 +1,17 @@ +avatar = $avatar; } + + public function getStar(): ForumStar + { + return $this->star; + } + + public function setStar(ForumStar $star): void + { + $this->star = $star; + } } diff --git a/tests/Documents/Tag.php b/tests/Documents/Tag.php index 4814a2afaf..5461d1d7ea 100644 --- a/tests/Documents/Tag.php +++ b/tests/Documents/Tag.php @@ -10,13 +10,11 @@ #[ODM\Document] class Tag { - /** @var string|null */ #[ODM\Id] - public $id; + public ?string $id; - /** @var string */ - #[ODM\Field(type: 'string')] - public $name; + #[ODM\Field] + public readonly string $name; /** @var Collection */ #[ODM\ReferenceMany(targetDocument: BlogPost::class, mappedBy: 'tags')] diff --git a/tests/Documents84/PropertyHooks/MappingVirtualProperty.php b/tests/Documents84/PropertyHooks/MappingVirtualProperty.php new file mode 100644 index 0000000000..7a7a2b6dbb --- /dev/null +++ b/tests/Documents84/PropertyHooks/MappingVirtualProperty.php @@ -0,0 +1,28 @@ + $this->first . " " . $this->last; + set { + [$this->first, $this->last] = explode(' ', $value, 2); + } + } +} diff --git a/tests/Documents84/PropertyHooks/User.php b/tests/Documents84/PropertyHooks/User.php new file mode 100644 index 0000000000..cc251be3c9 --- /dev/null +++ b/tests/Documents84/PropertyHooks/User.php @@ -0,0 +1,53 @@ +first = $value; + } + } + + #[Field] + public string $last { + set { + if (strlen($value) === 0) { + throw new ValueError("Name must be non-empty"); + } + $this->last = $value; + } + } + + public string $fullName { + get => $this->first . " " . $this->last; + set { + [$this->first, $this->last] = explode(' ', $value, 2); + } + } + + #[Field] + public string $language = 'de' { + // Override the "read" action with arbitrary logic. + get => strtoupper($this->language); + + // Override the "write" action with arbitrary logic. + set { + $this->language = strtolower($value); + } + } +} \ No newline at end of file diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/AggregationOperatorsProviderTrait.php b/tests/Tests/Aggregation/AggregationOperatorsProviderTrait.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/AggregationOperatorsProviderTrait.php rename to tests/Tests/Aggregation/AggregationOperatorsProviderTrait.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/AggregationTestTrait.php b/tests/Tests/Aggregation/AggregationTestTrait.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/AggregationTestTrait.php rename to tests/Tests/Aggregation/AggregationTestTrait.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/BuilderTest.php b/tests/Tests/Aggregation/BuilderTest.php similarity index 95% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/BuilderTest.php rename to tests/Tests/Aggregation/BuilderTest.php index 53584a1f71..4302ba84f8 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/BuilderTest.php +++ b/tests/Tests/Aggregation/BuilderTest.php @@ -7,6 +7,7 @@ use DateTimeImmutable; use Doctrine\ODM\MongoDB\Aggregation\Aggregation; use Doctrine\ODM\MongoDB\Aggregation\Stage; +use Doctrine\ODM\MongoDB\Iterator\CachingIterator; use Doctrine\ODM\MongoDB\Iterator\Iterator; use Doctrine\ODM\MongoDB\Iterator\UnrewindableIterator; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; @@ -18,6 +19,8 @@ use Documents\Tag; use MongoDB\BSON\ObjectId; use MongoDB\BSON\UTCDateTime; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; +use PHPUnit\Framework\Attributes\TestWith; use function array_keys; @@ -188,6 +191,7 @@ public function testAggregationBuilder(): void ->field('numPosts') ->sum(1) ->sort('numPosts', 'desc') + ->getAggregation() ->execute(); self::assertInstanceOf(Iterator::class, $resultCursor); @@ -437,7 +441,7 @@ public function testBuilderWithOutStageReturnsNoData(): void $builder ->out('sampleCollection'); - $result = $builder->execute()->toArray(); + $result = $builder->getAggregation()->getIterator(); self::assertEmpty($result); } @@ -464,6 +468,20 @@ public function testEmptyMatchStageIsSkipped(): void ], $builder->getPipeline()); } + #[IgnoreDeprecations] + #[TestWith([false, UnrewindableIterator::class])] + #[TestWith([true, CachingIterator::class])] + public function testExecute(bool $rewindable, string $iteratorClass): void + { + $builder = $this->dm + ->createAggregationBuilder(BlogPost::class) + ->match() + ->rewindable($rewindable); + + $iterator = $builder->getAggregation()->execute(); + self::assertInstanceOf($iteratorClass, $iterator); + } + public function testNonRewindableBuilder(): void { $builder = $this->dm @@ -471,7 +489,7 @@ public function testNonRewindableBuilder(): void ->match() ->rewindable(false); - $iterator = $builder->execute(); + $iterator = $builder->getAggregation()->execute(); self::assertInstanceOf(UnrewindableIterator::class, $iterator); } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/ExprTest.php b/tests/Tests/Aggregation/ExprTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/ExprTest.php rename to tests/Tests/Aggregation/ExprTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/AddFieldsTest.php b/tests/Tests/Aggregation/Stage/AddFieldsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/AddFieldsTest.php rename to tests/Tests/Aggregation/Stage/AddFieldsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/BucketAutoTest.php b/tests/Tests/Aggregation/Stage/BucketAutoTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/BucketAutoTest.php rename to tests/Tests/Aggregation/Stage/BucketAutoTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/BucketTest.php b/tests/Tests/Aggregation/Stage/BucketTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/BucketTest.php rename to tests/Tests/Aggregation/Stage/BucketTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/CollStatsTest.php b/tests/Tests/Aggregation/Stage/CollStatsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/CollStatsTest.php rename to tests/Tests/Aggregation/Stage/CollStatsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/CountTest.php b/tests/Tests/Aggregation/Stage/CountTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/CountTest.php rename to tests/Tests/Aggregation/Stage/CountTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/DensifyTest.php b/tests/Tests/Aggregation/Stage/DensifyTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/DensifyTest.php rename to tests/Tests/Aggregation/Stage/DensifyTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/FacetTest.php b/tests/Tests/Aggregation/Stage/FacetTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/FacetTest.php rename to tests/Tests/Aggregation/Stage/FacetTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/FillTest.php b/tests/Tests/Aggregation/Stage/FillTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/FillTest.php rename to tests/Tests/Aggregation/Stage/FillTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/GeoNearTest.php b/tests/Tests/Aggregation/Stage/GeoNearTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/GeoNearTest.php rename to tests/Tests/Aggregation/Stage/GeoNearTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/GraphLookupTest.php b/tests/Tests/Aggregation/Stage/GraphLookupTest.php similarity index 98% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/GraphLookupTest.php rename to tests/Tests/Aggregation/Stage/GraphLookupTest.php index 21489a8ddf..6b8b976675 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/GraphLookupTest.php +++ b/tests/Tests/Aggregation/Stage/GraphLookupTest.php @@ -20,6 +20,7 @@ use function array_merge; use function count; +use function iterator_to_array; class GraphLookupTest extends BaseTestCase { @@ -172,7 +173,7 @@ public function testWithEmployees(Closure $addGraphLookupStage, array $expectedF self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = $builder->getAggregation(); self::assertCount(6, $result); foreach ($result as $reportingHierarchy) { @@ -245,7 +246,7 @@ public function testWithTraveller(Closure $addGraphLookupStage, array $expectedF self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(3, $result); } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/GroupTest.php b/tests/Tests/Aggregation/Stage/GroupTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/GroupTest.php rename to tests/Tests/Aggregation/Stage/GroupTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/IndexStatsTest.php b/tests/Tests/Aggregation/Stage/IndexStatsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/IndexStatsTest.php rename to tests/Tests/Aggregation/Stage/IndexStatsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/LimitTest.php b/tests/Tests/Aggregation/Stage/LimitTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/LimitTest.php rename to tests/Tests/Aggregation/Stage/LimitTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/LookupTest.php b/tests/Tests/Aggregation/Stage/LookupTest.php similarity index 95% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/LookupTest.php rename to tests/Tests/Aggregation/Stage/LookupTest.php index 226c8f7ade..c8ffba693a 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/LookupTest.php +++ b/tests/Tests/Aggregation/Stage/LookupTest.php @@ -11,6 +11,8 @@ use Documents\User; use InvalidArgumentException; +use function iterator_to_array; + class LookupTest extends BaseTestCase { public function setUp(): void @@ -40,7 +42,7 @@ public function testStage(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result); self::assertCount(1, $result[0]['user']); @@ -237,7 +239,7 @@ public function testStageWithClassName(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result); self::assertCount(1, $result[0]['user']); @@ -266,7 +268,7 @@ public function testStageWithCollectionName(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result); self::assertEmpty($result[0]['user']); @@ -294,7 +296,7 @@ public function testStageReferenceMany(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(2, $result); self::assertCount(1, $result[0]['users']); @@ -325,7 +327,7 @@ public function testStageReferenceManyStoreAsRef(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(2, $result); self::assertCount(1, $result[0]['users']); @@ -360,7 +362,7 @@ public function testStageReferenceOneInverse(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result); self::assertCount(1, $result[0]['simpleReferenceOneInverse']); @@ -392,7 +394,7 @@ public function testStageReferenceManyInverse(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result); self::assertCount(1, $result[0]['simpleReferenceManyInverse']); @@ -424,7 +426,7 @@ public function testStageReferenceOneInverseStoreAsRef(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result); self::assertCount(1, $result[0]['embeddedReferenceOneInverse']); @@ -456,7 +458,7 @@ public function testStageReferenceManyInverseStoreAsRef(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result); self::assertCount(1, $result[0]['embeddedReferenceManyInverse']); @@ -508,7 +510,7 @@ public function testStageAndDefaultAlias(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result[0]['simpleReferenceOneInverse']); } @@ -532,7 +534,7 @@ public function testStageAndDefaultAliasOverride(): void self::assertEquals($expectedPipeline, $builder->getPipeline()); - $result = $builder->execute()->toArray(); + $result = iterator_to_array($builder->getAggregation()); self::assertCount(1, $result[0]['override']); } } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/MatchStageTest.php b/tests/Tests/Aggregation/Stage/MatchStageTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/MatchStageTest.php rename to tests/Tests/Aggregation/Stage/MatchStageTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/MergeTest.php b/tests/Tests/Aggregation/Stage/MergeTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/MergeTest.php rename to tests/Tests/Aggregation/Stage/MergeTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/OperatorTest.php b/tests/Tests/Aggregation/Stage/OperatorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/OperatorTest.php rename to tests/Tests/Aggregation/Stage/OperatorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/OutTest.php b/tests/Tests/Aggregation/Stage/OutTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/OutTest.php rename to tests/Tests/Aggregation/Stage/OutTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/ProjectTest.php b/tests/Tests/Aggregation/Stage/ProjectTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/ProjectTest.php rename to tests/Tests/Aggregation/Stage/ProjectTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/RedactTest.php b/tests/Tests/Aggregation/Stage/RedactTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/RedactTest.php rename to tests/Tests/Aggregation/Stage/RedactTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/ReplaceRootTest.php b/tests/Tests/Aggregation/Stage/ReplaceRootTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/ReplaceRootTest.php rename to tests/Tests/Aggregation/Stage/ReplaceRootTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/ReplaceWithTest.php b/tests/Tests/Aggregation/Stage/ReplaceWithTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/ReplaceWithTest.php rename to tests/Tests/Aggregation/Stage/ReplaceWithTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SampleTest.php b/tests/Tests/Aggregation/Stage/SampleTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SampleTest.php rename to tests/Tests/Aggregation/Stage/SampleTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SearchTest.php b/tests/Tests/Aggregation/Stage/SearchTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SearchTest.php rename to tests/Tests/Aggregation/Stage/SearchTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SetTest.php b/tests/Tests/Aggregation/Stage/SetTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SetTest.php rename to tests/Tests/Aggregation/Stage/SetTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SetWindowFieldsTest.php b/tests/Tests/Aggregation/Stage/SetWindowFieldsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SetWindowFieldsTest.php rename to tests/Tests/Aggregation/Stage/SetWindowFieldsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SkipTest.php b/tests/Tests/Aggregation/Stage/SkipTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SkipTest.php rename to tests/Tests/Aggregation/Stage/SkipTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SortByCountTest.php b/tests/Tests/Aggregation/Stage/SortByCountTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SortByCountTest.php rename to tests/Tests/Aggregation/Stage/SortByCountTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SortTest.php b/tests/Tests/Aggregation/Stage/SortTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/SortTest.php rename to tests/Tests/Aggregation/Stage/SortTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/UnionWithTest.php b/tests/Tests/Aggregation/Stage/UnionWithTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/UnionWithTest.php rename to tests/Tests/Aggregation/Stage/UnionWithTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/UnsetTest.php b/tests/Tests/Aggregation/Stage/UnsetTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/UnsetTest.php rename to tests/Tests/Aggregation/Stage/UnsetTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/UnwindTest.php b/tests/Tests/Aggregation/Stage/UnwindTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/UnwindTest.php rename to tests/Tests/Aggregation/Stage/UnwindTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/VectorSearchTest.php b/tests/Tests/Aggregation/Stage/VectorSearchTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Aggregation/Stage/VectorSearchTest.php rename to tests/Tests/Aggregation/Stage/VectorSearchTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/BaseTestCase.php b/tests/Tests/BaseTestCase.php similarity index 94% rename from tests/Doctrine/ODM/MongoDB/Tests/BaseTestCase.php rename to tests/Tests/BaseTestCase.php index 665f4ef964..43fec12308 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/BaseTestCase.php +++ b/tests/Tests/BaseTestCase.php @@ -7,6 +7,7 @@ use Doctrine\ODM\MongoDB\Configuration; use Doctrine\ODM\MongoDB\DocumentManager; use Doctrine\ODM\MongoDB\Mapping\Driver\AttributeDriver; +use Doctrine\ODM\MongoDB\Proxy\Factory\NativeLazyObjectFactory; use Doctrine\ODM\MongoDB\Proxy\InternalProxy; use Doctrine\ODM\MongoDB\Tests\Query\Filter\Filter; use Doctrine\ODM\MongoDB\UnitOfWork; @@ -96,15 +97,20 @@ protected static function getConfiguration(): Configuration { $config = new Configuration(); - $config->setProxyDir(__DIR__ . '/../../../../Proxies'); + $config->setProxyDir(__DIR__ . '/../Proxies'); $config->setProxyNamespace('Proxies'); - $config->setHydratorDir(__DIR__ . '/../../../../Hydrators'); + $config->setHydratorDir(__DIR__ . '/../Hydrators'); $config->setHydratorNamespace('Hydrators'); - $config->setPersistentCollectionDir(__DIR__ . '/../../../../PersistentCollections'); + $config->setPersistentCollectionDir(__DIR__ . '/../PersistentCollections'); $config->setPersistentCollectionNamespace('PersistentCollections'); $config->setDefaultDB(DOCTRINE_MONGODB_DATABASE); $config->setMetadataDriverImpl(static::createMetadataDriverImpl()); - $config->setUseLazyGhostObject((bool) $_ENV['USE_LAZY_GHOST_OBJECTS']); + $config->setUseLazyGhostObject((bool) $_ENV['USE_LAZY_GHOST_OBJECT']); + $config->setUseNativeLazyObject((bool) $_ENV['USE_NATIVE_LAZY_OBJECT']); + + if ($config->isNativeLazyObjectEnabled()) { + NativeLazyObjectFactory::enableTracking(); + } $config->addFilter('testFilter', Filter::class); $config->addFilter('testFilter2', Filter::class); @@ -134,12 +140,16 @@ public static function assertArraySubset(array $subset, array $array, bool $chec public static function isLazyObject(object $document): bool { + if ($_ENV['USE_NATIVE_LAZY_OBJECT']) { + return NativeLazyObjectFactory::isLazyObject($document); + } + return $document instanceof InternalProxy || $document instanceof LazyLoadingInterface; } protected static function createMetadataDriverImpl(): MappingDriver { - $paths = [__DIR__ . '/../../../../Documents']; + $paths = [__DIR__ . '/../Documents']; // Available in Doctrine Persistence 4.1+ if (class_exists(FileClassLocator::class)) { diff --git a/tests/Doctrine/ODM/MongoDB/Tests/ClassMetadataTestUtil.php b/tests/Tests/ClassMetadataTestUtil.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/ClassMetadataTestUtil.php rename to tests/Tests/ClassMetadataTestUtil.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/ConfigurationTest.php b/tests/Tests/ConfigurationTest.php similarity index 82% rename from tests/Doctrine/ODM/MongoDB/Tests/ConfigurationTest.php rename to tests/Tests/ConfigurationTest.php index 6432494156..c07d62c8f9 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/ConfigurationTest.php +++ b/tests/Tests/ConfigurationTest.php @@ -8,7 +8,10 @@ use Doctrine\ODM\MongoDB\ConfigurationException; use Doctrine\ODM\MongoDB\PersistentCollection\PersistentCollectionFactory; use Doctrine\ODM\MongoDB\PersistentCollection\PersistentCollectionGenerator; +use LogicException; use MongoDB\Driver\Manager; +use PHPUnit\Framework\Attributes\RequiresPhp; +use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; use stdClass; @@ -17,6 +20,49 @@ class ConfigurationTest extends TestCase { + #[RequiresPhp('< 8.4')] + public function testUseNativeLazyObjectBeforePHP84(): void + { + $c = new Configuration(); + + self::expectException(LogicException::class); + self::expectExceptionMessage('Native lazy objects require PHP 8.4 or higher.'); + + $c->setUseNativeLazyObject(true); + } + + public function testUseLazyGhostObject(): void + { + $c = new Configuration(); + + self::assertFalse($c->isLazyGhostObjectEnabled()); + $c->setUseLazyGhostObject(true); + self::assertTrue($c->isLazyGhostObjectEnabled()); + $c->setUseLazyGhostObject(false); + self::assertFalse($c->isLazyGhostObjectEnabled()); + } + + public function testNativeLazyObjectDeprecatedByDefault(): void + { + $c = new Configuration(); + + self::assertFalse($c->isNativeLazyObjectEnabled()); + } + + #[RequiresPhp('>= 8.4')] + #[TestWith([true])] + #[TestWith([false])] + public function testConflictingLazyObjectSettings(bool $flag): void + { + $c = new Configuration(); + $c->setUseNativeLazyObject(true); + + self::expectException(LogicException::class); + self::expectExceptionMessage('Cannot enable or disable LazyGhostObject when native lazy objects are enabled.'); + + $c->setUseLazyGhostObject($flag); + } + public function testDefaultPersistentCollectionFactory(): void { $c = new Configuration(); @@ -28,7 +74,7 @@ public function testDefaultPersistentCollectionFactory(): void public function testDefaultPersistentCollectionGenerator(): void { $c = new Configuration(); - $c->setPersistentCollectionDir(__DIR__ . '/../../../../PersistentCollections'); + $c->setPersistentCollectionDir(__DIR__ . '/../PersistentCollections'); $c->setPersistentCollectionNamespace('PersistentCollections'); $generator = $c->getPersistentCollectionGenerator(); self::assertInstanceOf(PersistentCollectionGenerator::class, $generator); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/DocumentManagerTest.php b/tests/Tests/DocumentManagerTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/DocumentManagerTest.php rename to tests/Tests/DocumentManagerTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/DocumentRepositoryTest.php b/tests/Tests/DocumentRepositoryTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/DocumentRepositoryTest.php rename to tests/Tests/DocumentRepositoryTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Events/LifecycleCallbacksTest.php b/tests/Tests/Events/LifecycleCallbacksTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Events/LifecycleCallbacksTest.php rename to tests/Tests/Events/LifecycleCallbacksTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Events/LifecycleListenersTest.php b/tests/Tests/Events/LifecycleListenersTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Events/LifecycleListenersTest.php rename to tests/Tests/Events/LifecycleListenersTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Events/OnClassMetadataNotFoundEventArgsTest.php b/tests/Tests/Events/OnClassMetadataNotFoundEventArgsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Events/OnClassMetadataNotFoundEventArgsTest.php rename to tests/Tests/Events/OnClassMetadataNotFoundEventArgsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Events/PreLoadEventArgsTest.php b/tests/Tests/Events/PreLoadEventArgsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Events/PreLoadEventArgsTest.php rename to tests/Tests/Events/PreLoadEventArgsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Events/PreUpdateEventArgsTest.php b/tests/Tests/Events/PreUpdateEventArgsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Events/PreUpdateEventArgsTest.php rename to tests/Tests/Events/PreUpdateEventArgsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Events/TransactionalLifecycleEventsTest.php b/tests/Tests/Events/TransactionalLifecycleEventsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Events/TransactionalLifecycleEventsTest.php rename to tests/Tests/Events/TransactionalLifecycleEventsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/AlsoLoadTest.php b/tests/Tests/Functional/AlsoLoadTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/AlsoLoadTest.php rename to tests/Tests/Functional/AlsoLoadTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/AtlasSearchTest.php b/tests/Tests/Functional/AtlasSearchTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/AtlasSearchTest.php rename to tests/Tests/Functional/AtlasSearchTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/AtomicSetTest.php b/tests/Tests/Functional/AtomicSetTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/AtomicSetTest.php rename to tests/Tests/Functional/AtomicSetTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/BidirectionalInheritanceTest.php b/tests/Tests/Functional/BidirectionalInheritanceTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/BidirectionalInheritanceTest.php rename to tests/Tests/Functional/BidirectionalInheritanceTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/BinDataTest.php b/tests/Tests/Functional/BinDataTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/BinDataTest.php rename to tests/Tests/Functional/BinDataTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CollectionPersisterTest.php b/tests/Tests/Functional/CollectionPersisterTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/CollectionPersisterTest.php rename to tests/Tests/Functional/CollectionPersisterTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CollectionsTest.php b/tests/Tests/Functional/CollectionsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/CollectionsTest.php rename to tests/Tests/Functional/CollectionsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CommitImprovementTest.php b/tests/Tests/Functional/CommitImprovementTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/CommitImprovementTest.php rename to tests/Tests/Functional/CommitImprovementTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomCollectionsTest.php b/tests/Tests/Functional/CustomCollectionsTest.php similarity index 98% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomCollectionsTest.php rename to tests/Tests/Functional/CustomCollectionsTest.php index f0a846b2de..d821746573 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomCollectionsTest.php +++ b/tests/Tests/Functional/CustomCollectionsTest.php @@ -16,6 +16,7 @@ use Doctrine\ODM\MongoDB\Tests\ClassMetadataTestUtil; use Documents\File; use Documents\ProfileNotify; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use stdClass; use function assert; @@ -148,6 +149,8 @@ public function testModifyingCollectionByCustomMethod(): void self::assertEquals($e1, $d->coll[1]); } + /** @see ClassMetadata::CHANGETRACKING_NOTIFY */ + #[IgnoreDeprecations] public function testModifyingCollectionInChangeTrackingNotifyDocument(): void { $repository = $this->dm->getRepository(File::class); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomFieldNameTest.php b/tests/Tests/Functional/CustomFieldNameTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomFieldNameTest.php rename to tests/Tests/Functional/CustomFieldNameTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomIdTest.php b/tests/Tests/Functional/CustomIdTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomIdTest.php rename to tests/Tests/Functional/CustomIdTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomTypeTest.php b/tests/Tests/Functional/CustomTypeTest.php similarity index 52% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomTypeTest.php rename to tests/Tests/Functional/CustomTypeTest.php index 3a123f5051..77fa019261 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/CustomTypeTest.php +++ b/tests/Tests/Functional/CustomTypeTest.php @@ -10,16 +10,29 @@ use Doctrine\ODM\MongoDB\Types\ClosureToPHP; use Doctrine\ODM\MongoDB\Types\Type; use Exception; +use PHPUnit\Framework\Attributes\After; +use ReflectionProperty; use function array_map; use function array_values; +use function assert; use function is_array; class CustomTypeTest extends BaseTestCase { - public static function setUpBeforeClass(): void + public function setUp(): void { + parent::setUp(); + Type::addType('date_collection', DateCollectionType::class); + Type::addType(Language::class, LanguageType::class); + } + + #[After] + public function restoreTypeMap(): void + { + $r = new ReflectionProperty(Type::class, 'typesMap'); + $r->setValue(null, $r->getDefaultValue()); } public function testCustomTypeValueConversions(): void @@ -46,6 +59,36 @@ public function testConvertToDatabaseValueExpectsArray(): void $this->expectException(CustomTypeException::class); $this->dm->flush(); } + + public function testCustomTypeDetection(): void + { + $typeOfField = $this->dm->getClassMetadata(Country::class)->getTypeOfField('lang'); + self::assertSame(Language::class, $typeOfField, 'The custom type should be detected on the field'); + + $country = new Country(); + $country->lang = new Language('French', 'fr'); + + $this->dm->persist($country); + $this->dm->flush(); + $this->dm->clear(); + + $country = $this->dm->find(Country::class, $country->id); + + self::assertNotNull($country); + self::assertInstanceOf(Language::class, $country->lang); + self::assertSame('French', $country->lang->name); + self::assertSame('fr', $country->lang->code); + } + + public function testTypeFromPHPVariable(): void + { + $lang = new Language('French', 'fr'); + $type = Type::getTypeFromPHPVariable($lang); + self::assertInstanceOf(LanguageType::class, $type); + + $databaseValue = Type::convertPHPToDatabaseValue($lang); + self::assertSame(['name' => 'French', 'code' => 'fr'], $databaseValue); + } } class DateCollectionType extends Type @@ -106,11 +149,52 @@ class CustomTypeException extends Exception #[ODM\Document] class Country { - /** @var string|null */ #[ODM\Id] - public $id; + public ?string $id; /** @var DateTime[]|DateTime|null */ #[ODM\Field(type: 'date_collection')] public $nationalHolidays; + + /** The field type is detected from the property type */ + #[ODM\Field(/* type: Language::class */)] + public ?Language $lang; +} + +class Language +{ + public function __construct( + public string $name, + public string $code, + ) { + } +} + +class LanguageType extends Type +{ + use ClosureToPHP; + + /** @return array{name:string,code:string}|null */ + public function convertToDatabaseValue($value): ?array + { + if ($value === null) { + return null; + } + + assert($value instanceof Language); + + return ['name' => $value->name, 'code' => $value->code]; + } + + /** @param array{name:string,code:string}|null $value */ + public function convertToPHPValue($value): ?Language + { + if ($value === null) { + return null; + } + + assert(is_array($value) && isset($value['name'], $value['code'])); + + return new Language($value['name'], $value['code']); + } } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/DatabasesTest.php b/tests/Tests/Functional/DatabasesTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/DatabasesTest.php rename to tests/Tests/Functional/DatabasesTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/DateTest.php b/tests/Tests/Functional/DateTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/DateTest.php rename to tests/Tests/Functional/DateTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/DetachedDocumentTest.php b/tests/Tests/Functional/DetachedDocumentTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/DetachedDocumentTest.php rename to tests/Tests/Functional/DetachedDocumentTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/DiscriminatorsDefaultValueTest.php b/tests/Tests/Functional/DiscriminatorsDefaultValueTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/DiscriminatorsDefaultValueTest.php rename to tests/Tests/Functional/DiscriminatorsDefaultValueTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/DocumentPersisterTest.php b/tests/Tests/Functional/DocumentPersisterTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/DocumentPersisterTest.php rename to tests/Tests/Functional/DocumentPersisterTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/EcommerceTest.php b/tests/Tests/Functional/EcommerceTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/EcommerceTest.php rename to tests/Tests/Functional/EcommerceTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/EmbeddedIdTest.php b/tests/Tests/Functional/EmbeddedIdTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/EmbeddedIdTest.php rename to tests/Tests/Functional/EmbeddedIdTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/EmbeddedReferenceTest.php b/tests/Tests/Functional/EmbeddedReferenceTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/EmbeddedReferenceTest.php rename to tests/Tests/Functional/EmbeddedReferenceTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/EmbeddedTest.php b/tests/Tests/Functional/EmbeddedTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/EmbeddedTest.php rename to tests/Tests/Functional/EmbeddedTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/EnsureShardingTest.php b/tests/Tests/Functional/EnsureShardingTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/EnsureShardingTest.php rename to tests/Tests/Functional/EnsureShardingTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/EnumTest.php b/tests/Tests/Functional/EnumTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/EnumTest.php rename to tests/Tests/Functional/EnumTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/FilterTest.php b/tests/Tests/Functional/FilterTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/FilterTest.php rename to tests/Tests/Functional/FilterTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/FindAndModifyTest.php b/tests/Tests/Functional/FindAndModifyTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/FindAndModifyTest.php rename to tests/Tests/Functional/FindAndModifyTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/FlushTest.php b/tests/Tests/Functional/FlushTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/FlushTest.php rename to tests/Tests/Functional/FlushTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/FunctionalTest.php b/tests/Tests/Functional/FunctionalTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/FunctionalTest.php rename to tests/Tests/Functional/FunctionalTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/GeoTest.php b/tests/Tests/Functional/GeoTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/GeoTest.php rename to tests/Tests/Functional/GeoTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/HasLifecycleCallbacksTest.php b/tests/Tests/Functional/HasLifecycleCallbacksTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/HasLifecycleCallbacksTest.php rename to tests/Tests/Functional/HasLifecycleCallbacksTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/IdTest.php b/tests/Tests/Functional/IdTest.php similarity index 99% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/IdTest.php rename to tests/Tests/Functional/IdTest.php index 298f0c38af..099e380650 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/IdTest.php +++ b/tests/Tests/Functional/IdTest.php @@ -254,9 +254,9 @@ public static function getTestIdTypesAndStrategiesData(): array return [ // boolean - ['boolean', 'none', true, true, 'boolean'], - ['boolean', 'none', 1, true, 'boolean'], - ['boolean', 'none', false, false, 'boolean'], + ['bool', 'none', true, true, 'boolean'], + ['bool', 'none', 1, true, 'boolean'], + ['bool', 'none', false, false, 'boolean'], // integer ['int', 'none', 0, 0, 'integer'], diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/IdentifiersTest.php b/tests/Tests/Functional/IdentifiersTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/IdentifiersTest.php rename to tests/Tests/Functional/IdentifiersTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/IndexesTest.php b/tests/Tests/Functional/IndexesTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/IndexesTest.php rename to tests/Tests/Functional/IndexesTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/InheritanceTest.php b/tests/Tests/Functional/InheritanceTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/InheritanceTest.php rename to tests/Tests/Functional/InheritanceTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/CachingIteratorTest.php b/tests/Tests/Functional/Iterator/CachingIteratorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/CachingIteratorTest.php rename to tests/Tests/Functional/Iterator/CachingIteratorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/HydratingIteratorTest.php b/tests/Tests/Functional/Iterator/HydratingIteratorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/HydratingIteratorTest.php rename to tests/Tests/Functional/Iterator/HydratingIteratorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/PrimingIteratorTest.php b/tests/Tests/Functional/Iterator/PrimingIteratorTest.php similarity index 93% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/PrimingIteratorTest.php rename to tests/Tests/Functional/Iterator/PrimingIteratorTest.php index 79f72830d2..d95cbe313e 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/PrimingIteratorTest.php +++ b/tests/Tests/Functional/Iterator/PrimingIteratorTest.php @@ -16,12 +16,15 @@ use Documents\User; use Iterator; use MongoDB\BSON\ObjectId; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; final class PrimingIteratorTest extends BaseTestCase { /** @var class-string[] */ private array $callbackCalls = []; + /** This test uses the deprecated "NOTIFY" tracking policy */ + #[IgnoreDeprecations] public function testPrimerIsCalledOnceForEveryField(): void { $primer = new ReferencePrimer($this->dm, $this->uow); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/UnrewindableIteratorTest.php b/tests/Tests/Functional/Iterator/UnrewindableIteratorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Iterator/UnrewindableIteratorTest.php rename to tests/Tests/Functional/Iterator/UnrewindableIteratorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/LifecycleTest.php b/tests/Tests/Functional/LifecycleTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/LifecycleTest.php rename to tests/Tests/Functional/LifecycleTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/LockTest.php b/tests/Tests/Functional/LockTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/LockTest.php rename to tests/Tests/Functional/LockTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/MappedSuperclassTest.php b/tests/Tests/Functional/MappedSuperclassTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/MappedSuperclassTest.php rename to tests/Tests/Functional/MappedSuperclassTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/MemoryUsageTest.php b/tests/Tests/Functional/MemoryUsageTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/MemoryUsageTest.php rename to tests/Tests/Functional/MemoryUsageTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/NestedCollectionsTest.php b/tests/Tests/Functional/NestedCollectionsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/NestedCollectionsTest.php rename to tests/Tests/Functional/NestedCollectionsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/NestedDocumentsTest.php b/tests/Tests/Functional/NestedDocumentsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/NestedDocumentsTest.php rename to tests/Tests/Functional/NestedDocumentsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/OrphanRemovalEmbedTest.php b/tests/Tests/Functional/OrphanRemovalEmbedTest.php similarity index 99% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/OrphanRemovalEmbedTest.php rename to tests/Tests/Functional/OrphanRemovalEmbedTest.php index c4e034be80..5f37672eac 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/OrphanRemovalEmbedTest.php +++ b/tests/Tests/Functional/OrphanRemovalEmbedTest.php @@ -96,7 +96,7 @@ public function testClearEmbedMany(): void $user->profileMany->clear(); $this->dm->flush(); - $this->dm->clear(OrphanRemovalCascadeUser::class); + $this->dm->detach($user); self::assertNull($this->getAddressRepository()->find($address1->id), 'Should have removed address 1'); self::assertNull($this->getAddressRepository()->find($address2->id), 'Should have removed address 2'); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/OrphanRemovalTest.php b/tests/Tests/Functional/OrphanRemovalTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/OrphanRemovalTest.php rename to tests/Tests/Functional/OrphanRemovalTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/OwningAndInverseReferencesTest.php b/tests/Tests/Functional/OwningAndInverseReferencesTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/OwningAndInverseReferencesTest.php rename to tests/Tests/Functional/OwningAndInverseReferencesTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/PersistentCollectionCloneTest.php b/tests/Tests/Functional/PersistentCollectionCloneTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/PersistentCollectionCloneTest.php rename to tests/Tests/Functional/PersistentCollectionCloneTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/PersistingTest.php b/tests/Tests/Functional/PersistingTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/PersistingTest.php rename to tests/Tests/Functional/PersistingTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/PrePersistTest.php b/tests/Tests/Functional/PrePersistTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/PrePersistTest.php rename to tests/Tests/Functional/PrePersistTest.php diff --git a/tests/Tests/Functional/PropertyHooksTest.php b/tests/Tests/Functional/PropertyHooksTest.php new file mode 100644 index 0000000000..2ffeb1ee74 --- /dev/null +++ b/tests/Tests/Functional/PropertyHooksTest.php @@ -0,0 +1,100 @@ += 8.4.0')] +class PropertyHooksTest extends BaseTestCase +{ + protected function setUp(): void + { + parent::setUp(); + + if ($this->dm->getConfiguration()->isNativeLazyObjectEnabled()) { + return; + } + + $this->markTestSkipped('Property hooks require native lazy objects to be enabled.'); + } + + public function testMapPropertyHooks(): void + { + $user = new User(); + $user->fullName = 'John Doe'; + $user->language = 'EN'; + + $this->dm->persist($user); + $this->dm->flush(); + $this->dm->clear(); + + $user = $this->dm->find(User::class, $user->id); + + self::assertSame('John', $user->first); + self::assertSame('Doe', $user->last); + self::assertSame('John Doe', $user->fullName); + self::assertSame('EN', $user->language, 'The property hook uppercases the language.'); + + $document = $this->dm->createQueryBuilder() + ->find(User::class) + ->field('id')->equals($user->id) + ->select('language') + ->hydrate(false) + ->getQuery() + ->getSingleResult(); + + self::assertSame('en', $document['language'], 'Selecting a field without hydration does not go through the property hook, accessing raw data.'); + + $this->dm->clear(); + + $user = $this->dm->getRepository(User::class)->findOneBy(['language' => 'EN']); + + self::assertNull($user); + + $user = $this->dm->getRepository(User::class)->findOneBy(['language' => 'en']); + + self::assertNotNull($user); + } + + public function testTriggerLazyLoadingWhenAccessingPropertyHooks(): void + { + $user = new User(); + $user->fullName = 'Ludwig von Beethoven'; + $user->language = 'DE'; + + $this->dm->persist($user); + $this->dm->flush(); + $this->dm->clear(); + + $user = $this->dm->getReference(User::class, $user->id); + + $this->assertTrue($this->dm->getUnitOfWork()->isUninitializedObject($user)); + + self::assertSame('Ludwig', $user->first); + self::assertSame('von Beethoven', $user->last); + self::assertSame('Ludwig von Beethoven', $user->fullName); + self::assertSame('DE', $user->language, 'The property hook uppercases the language.'); + + $this->assertFalse($this->dm->getUnitOfWork()->isUninitializedObject($user)); + + $this->dm->clear(); + + $user = $this->dm->getReference(User::class, $user->id); + + self::assertSame('Ludwig von Beethoven', $user->fullName); + } + + public function testMappingVirtualPropertyIsNotSupported(): void + { + $this->expectException(MappingException::class); + $this->expectExceptionMessage('Mapping virtual property "fullName" on document "Documents84\PropertyHooks\MappingVirtualProperty" is not allowed.'); + + $this->dm->getClassMetadata(MappingVirtualProperty::class); + } +} diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryTest.php b/tests/Tests/Functional/QueryTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryTest.php rename to tests/Tests/Functional/QueryTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryableEncryptionTest.php b/tests/Tests/Functional/QueryableEncryptionTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/QueryableEncryptionTest.php rename to tests/Tests/Functional/QueryableEncryptionTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/RawTypeTest.php b/tests/Tests/Functional/RawTypeTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/RawTypeTest.php rename to tests/Tests/Functional/RawTypeTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ReadOnlyDocumentTest.php b/tests/Tests/Functional/ReadOnlyDocumentTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ReadOnlyDocumentTest.php rename to tests/Tests/Functional/ReadOnlyDocumentTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ReadPreferenceTest.php b/tests/Tests/Functional/ReadPreferenceTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ReadPreferenceTest.php rename to tests/Tests/Functional/ReadPreferenceTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferenceDiscriminatorsTest.php b/tests/Tests/Functional/ReferenceDiscriminatorsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferenceDiscriminatorsTest.php rename to tests/Tests/Functional/ReferenceDiscriminatorsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferenceEmbeddedDocumentsTest.php b/tests/Tests/Functional/ReferenceEmbeddedDocumentsTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferenceEmbeddedDocumentsTest.php rename to tests/Tests/Functional/ReferenceEmbeddedDocumentsTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferencePrimerTest.php b/tests/Tests/Functional/ReferencePrimerTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferencePrimerTest.php rename to tests/Tests/Functional/ReferencePrimerTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferenceRepositoryMethodTest.php b/tests/Tests/Functional/ReferenceRepositoryMethodTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferenceRepositoryMethodTest.php rename to tests/Tests/Functional/ReferenceRepositoryMethodTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferencesTest.php b/tests/Tests/Functional/ReferencesTest.php similarity index 99% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferencesTest.php rename to tests/Tests/Functional/ReferencesTest.php index 88cc979f03..d2f1761b96 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ReferencesTest.php +++ b/tests/Tests/Functional/ReferencesTest.php @@ -22,6 +22,7 @@ use Documents\User; use MongoDB\BSON\Binary; use MongoDB\BSON\ObjectId; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use function assert; @@ -88,6 +89,7 @@ public function testLazyLoadReference(): void self::assertEquals('Wage', $profile->getLastName()); } + #[IgnoreDeprecations] public function testLazyLoadedWithNotifyPropertyChanged(): void { $user = new User(); @@ -523,6 +525,9 @@ class DocumentWithArrayId /** @var array */ #[ODM\Id(strategy: 'none', options: ['type' => 'hash'])] public $id; + + #[ODM\Field] + public string $name; } @@ -544,6 +549,9 @@ class DocumentWithMongoBinDataId /** @var string|null */ #[ODM\Id(strategy: 'none', options: ['type' => 'bin'])] public $id; + + #[ODM\Field] + public string $name; } class DocumentNotFoundListener diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/RemoveTest.php b/tests/Tests/Functional/RemoveTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/RemoveTest.php rename to tests/Tests/Functional/RemoveTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/RepositoriesTest.php b/tests/Tests/Functional/RepositoriesTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/RepositoriesTest.php rename to tests/Tests/Functional/RepositoriesTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/SchemaManagerWaitForSearchIndexesTest.php b/tests/Tests/Functional/SchemaManagerWaitForSearchIndexesTest.php similarity index 97% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/SchemaManagerWaitForSearchIndexesTest.php rename to tests/Tests/Functional/SchemaManagerWaitForSearchIndexesTest.php index 00b6cd7a96..9cfdd7003f 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/SchemaManagerWaitForSearchIndexesTest.php +++ b/tests/Tests/Functional/SchemaManagerWaitForSearchIndexesTest.php @@ -7,6 +7,7 @@ use Doctrine\ODM\MongoDB\MongoDBException; use Doctrine\ODM\MongoDB\SchemaException; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; +use Documents\CmsAddress; use Documents\CmsArticle; use MongoDB\Driver\BulkWrite; use MongoDB\Driver\WriteConcern; @@ -99,7 +100,7 @@ public function testErrors(): void // Not specifying classes waits for all try { - $schemaManager->waitForSearchIndexes(); + $schemaManager->waitForSearchIndexes([CmsArticle::class, CmsAddress::class]); $this->fail('Expected SchemaException not thrown'); } catch (SchemaException $exception) { // The missing class varies depending on the test execution order, diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ShardKeyTest.php b/tests/Tests/Functional/ShardKeyTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ShardKeyTest.php rename to tests/Tests/Functional/ShardKeyTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/SimpleReferencesTest.php b/tests/Tests/Functional/SimpleReferencesTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/SimpleReferencesTest.php rename to tests/Tests/Functional/SimpleReferencesTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/SimpleTest.php b/tests/Tests/Functional/SimpleTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/SimpleTest.php rename to tests/Tests/Functional/SimpleTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/SplObjectHashCollisionsTest.php b/tests/Tests/Functional/SplObjectHashCollisionsTest.php similarity index 89% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/SplObjectHashCollisionsTest.php rename to tests/Tests/Functional/SplObjectHashCollisionsTest.php index b76e045f1a..8a3255de47 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/SplObjectHashCollisionsTest.php +++ b/tests/Tests/Functional/SplObjectHashCollisionsTest.php @@ -9,6 +9,7 @@ use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use ReflectionObject; class SplObjectHashCollisionsTest extends BaseTestCase @@ -58,12 +59,6 @@ static function (DocumentManager $dm): void { }, 0, ], - [ - static function (DocumentManager $dm, $doc): void { - $dm->clear($doc::class); - }, - 1, - ], [ static function (DocumentManager $dm, $doc): void { $dm->detach($doc); @@ -73,6 +68,17 @@ static function (DocumentManager $dm, $doc): void { ]; } + #[IgnoreDeprecations] + public function testParentAssociationsLeftoverPartialClear(): void + { + $this->testParentAssociationsLeftover( + static function (DocumentManager $dm): void { + $dm->clear(SplColDoc::class); + }, + 1, + ); + } + private function expectCount(string $prop, int $expected): void { $ro = new ReflectionObject($this->uow); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/TargetDocumentTest.php b/tests/Tests/Functional/TargetDocumentTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/TargetDocumentTest.php rename to tests/Tests/Functional/TargetDocumentTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1011Test.php b/tests/Tests/Functional/Ticket/GH1011Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1011Test.php rename to tests/Tests/Functional/Ticket/GH1011Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1017Test.php b/tests/Tests/Functional/Ticket/GH1017Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1017Test.php rename to tests/Tests/Functional/Ticket/GH1017Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1058Test.php b/tests/Tests/Functional/Ticket/GH1058Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1058Test.php rename to tests/Tests/Functional/Ticket/GH1058Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1107Test.php b/tests/Tests/Functional/Ticket/GH1107Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1107Test.php rename to tests/Tests/Functional/Ticket/GH1107Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1117Test.php b/tests/Tests/Functional/Ticket/GH1117Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1117Test.php rename to tests/Tests/Functional/Ticket/GH1117Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1132Test.php b/tests/Tests/Functional/Ticket/GH1132Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1132Test.php rename to tests/Tests/Functional/Ticket/GH1132Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1138Test.php b/tests/Tests/Functional/Ticket/GH1138Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1138Test.php rename to tests/Tests/Functional/Ticket/GH1138Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1152Test.php b/tests/Tests/Functional/Ticket/GH1152Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1152Test.php rename to tests/Tests/Functional/Ticket/GH1152Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1225Test.php b/tests/Tests/Functional/Ticket/GH1225Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1225Test.php rename to tests/Tests/Functional/Ticket/GH1225Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1229Test.php b/tests/Tests/Functional/Ticket/GH1229Test.php similarity index 98% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1229Test.php rename to tests/Tests/Functional/Ticket/GH1229Test.php index a3bae06157..a1bc2aa2d3 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1229Test.php +++ b/tests/Tests/Functional/Ticket/GH1229Test.php @@ -8,7 +8,6 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; -use PHPUnit\Framework\Attributes\Group; use function assert; use function count; @@ -42,7 +41,6 @@ public function setUp(): void $this->secondParentId = $secondParent->id; } - #[Group('m')] public function testMethodAWithoutClone(): void { $firstParent = $this->dm->find(GH1229Parent::CLASSNAME, $this->firstParentId); @@ -88,7 +86,6 @@ public function testMethodAWithoutClone(): void self::assertInstanceOf(GH1229ChildTypeB::CLASSNAME, $children[1]); } - #[Group('m')] public function testMethodAWithClone(): void { $firstParent = $this->dm->find(GH1229Parent::CLASSNAME, $this->firstParentId); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1232Test.php b/tests/Tests/Functional/Ticket/GH1232Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1232Test.php rename to tests/Tests/Functional/Ticket/GH1232Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1275Test.php b/tests/Tests/Functional/Ticket/GH1275Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1275Test.php rename to tests/Tests/Functional/Ticket/GH1275Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1294Test.php b/tests/Tests/Functional/Ticket/GH1294Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1294Test.php rename to tests/Tests/Functional/Ticket/GH1294Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1344Test.php b/tests/Tests/Functional/Ticket/GH1344Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1344Test.php rename to tests/Tests/Functional/Ticket/GH1344Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1346Test.php b/tests/Tests/Functional/Ticket/GH1346Test.php similarity index 97% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1346Test.php rename to tests/Tests/Functional/Ticket/GH1346Test.php index 4f97ab6d06..af5259614a 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1346Test.php +++ b/tests/Tests/Functional/Ticket/GH1346Test.php @@ -8,11 +8,9 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; -use PHPUnit\Framework\Attributes\Group; class GH1346Test extends BaseTestCase { - #[Group('GH1346Test')] public function testPublicProperty(): void { $referenced1 = new GH1346ReferencedDocument(); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1418Test.php b/tests/Tests/Functional/Ticket/GH1418Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1418Test.php rename to tests/Tests/Functional/Ticket/GH1418Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1428Test.php b/tests/Tests/Functional/Ticket/GH1428Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1428Test.php rename to tests/Tests/Functional/Ticket/GH1428Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1435Test.php b/tests/Tests/Functional/Ticket/GH1435Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1435Test.php rename to tests/Tests/Functional/Ticket/GH1435Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1525Test.php b/tests/Tests/Functional/Ticket/GH1525Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1525Test.php rename to tests/Tests/Functional/Ticket/GH1525Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1572Test.php b/tests/Tests/Functional/Ticket/GH1572Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1572Test.php rename to tests/Tests/Functional/Ticket/GH1572Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1674Test.php b/tests/Tests/Functional/Ticket/GH1674Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1674Test.php rename to tests/Tests/Functional/Ticket/GH1674Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1775Test.php b/tests/Tests/Functional/Ticket/GH1775Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1775Test.php rename to tests/Tests/Functional/Ticket/GH1775Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1962Test.php b/tests/Tests/Functional/Ticket/GH1962Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1962Test.php rename to tests/Tests/Functional/Ticket/GH1962Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1964Test.php b/tests/Tests/Functional/Ticket/GH1964Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1964Test.php rename to tests/Tests/Functional/Ticket/GH1964Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1990Test.php b/tests/Tests/Functional/Ticket/GH1990Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH1990Test.php rename to tests/Tests/Functional/Ticket/GH1990Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2002Test.php b/tests/Tests/Functional/Ticket/GH2002Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2002Test.php rename to tests/Tests/Functional/Ticket/GH2002Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2157Test.php b/tests/Tests/Functional/Ticket/GH2157Test.php similarity index 90% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2157Test.php rename to tests/Tests/Functional/Ticket/GH2157Test.php index cbfc95abcb..32276ceb31 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2157Test.php +++ b/tests/Tests/Functional/Ticket/GH2157Test.php @@ -31,10 +31,10 @@ public function testFacetDiscriminatorMapCreation(): void $this->dm->createAggregationBuilder(GH2157FirstType::class) ->limit(2), ) - ->execute()->toArray(); + ->getAggregation()->getSingleResult(); - self::assertEquals(4, $result[0]['count'][0]['count']); - self::assertCount(2, $result[0]['limitedResults']); + self::assertEquals(4, $result['count'][0]['count']); + self::assertCount(2, $result['limitedResults']); } } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2158Test.php b/tests/Tests/Functional/Ticket/GH2158Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2158Test.php rename to tests/Tests/Functional/Ticket/GH2158Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2251Test.php b/tests/Tests/Functional/Ticket/GH2251Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2251Test.php rename to tests/Tests/Functional/Ticket/GH2251Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2310Test.php b/tests/Tests/Functional/Ticket/GH2310Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2310Test.php rename to tests/Tests/Functional/Ticket/GH2310Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH232Test.php b/tests/Tests/Functional/Ticket/GH232Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH232Test.php rename to tests/Tests/Functional/Ticket/GH232Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH245Test.php b/tests/Tests/Functional/Ticket/GH245Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH245Test.php rename to tests/Tests/Functional/Ticket/GH245Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH267Test.php b/tests/Tests/Functional/Ticket/GH267Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH267Test.php rename to tests/Tests/Functional/Ticket/GH267Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2730Test.php b/tests/Tests/Functional/Ticket/GH2730Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2730Test.php rename to tests/Tests/Functional/Ticket/GH2730Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2789Test.php b/tests/Tests/Functional/Ticket/GH2789Test.php similarity index 90% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2789Test.php rename to tests/Tests/Functional/Ticket/GH2789Test.php index bae9c72e30..92ef106f80 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2789Test.php +++ b/tests/Tests/Functional/Ticket/GH2789Test.php @@ -9,17 +9,25 @@ use Doctrine\ODM\MongoDB\Types\Type; use Doctrine\ODM\MongoDB\Types\Versionable; use MongoDB\BSON\Binary; -use PHPUnit\Framework\Attributes\BackupGlobals; +use PHPUnit\Framework\Attributes\After; +use ReflectionProperty; use function assert; use function is_int; -#[BackupGlobals(true)] class GH2789Test extends BaseTestCase { + #[After] + public function restoreTypeMap(): void + { + $r = new ReflectionProperty(Type::class, 'typesMap'); + $r->setValue(null, $r->getDefaultValue()); + } + public function testVersionWithCustomType(): void { Type::addType(GH2789CustomType::class, GH2789CustomType::class); + $doc = new GH2789VersionedUuid('original message'); $this->dm->persist($doc); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2825Test.php b/tests/Tests/Functional/Ticket/GH2825Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH2825Test.php rename to tests/Tests/Functional/Ticket/GH2825Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH385Test.php b/tests/Tests/Functional/Ticket/GH385Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH385Test.php rename to tests/Tests/Functional/Ticket/GH385Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH389Test.php b/tests/Tests/Functional/Ticket/GH389Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH389Test.php rename to tests/Tests/Functional/Ticket/GH389Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH426Test.php b/tests/Tests/Functional/Ticket/GH426Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH426Test.php rename to tests/Tests/Functional/Ticket/GH426Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH435Test.php b/tests/Tests/Functional/Ticket/GH435Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH435Test.php rename to tests/Tests/Functional/Ticket/GH435Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH453Test.php b/tests/Tests/Functional/Ticket/GH453Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH453Test.php rename to tests/Tests/Functional/Ticket/GH453Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH467Test.php b/tests/Tests/Functional/Ticket/GH467Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH467Test.php rename to tests/Tests/Functional/Ticket/GH467Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH499Test.php b/tests/Tests/Functional/Ticket/GH499Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH499Test.php rename to tests/Tests/Functional/Ticket/GH499Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH520Test.php b/tests/Tests/Functional/Ticket/GH520Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH520Test.php rename to tests/Tests/Functional/Ticket/GH520Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH529Test.php b/tests/Tests/Functional/Ticket/GH529Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH529Test.php rename to tests/Tests/Functional/Ticket/GH529Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH560Test.php b/tests/Tests/Functional/Ticket/GH560Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH560Test.php rename to tests/Tests/Functional/Ticket/GH560Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH561Test.php b/tests/Tests/Functional/Ticket/GH561Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH561Test.php rename to tests/Tests/Functional/Ticket/GH561Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH566Test.php b/tests/Tests/Functional/Ticket/GH566Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH566Test.php rename to tests/Tests/Functional/Ticket/GH566Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH580Test.php b/tests/Tests/Functional/Ticket/GH580Test.php similarity index 93% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH580Test.php rename to tests/Tests/Functional/Ticket/GH580Test.php index 18827e0f59..7c12331567 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH580Test.php +++ b/tests/Tests/Functional/Ticket/GH580Test.php @@ -27,7 +27,7 @@ public function testDocumentPersisterShouldClearQueuedInsertsOnMongoException(): $this->dm->persist($doc1); $this->dm->flush(); - $this->dm->clear($class); + $this->dm->clear(); // Create, persist and flush a second, duplicate object $doc2 = new GH580Document(); @@ -40,20 +40,20 @@ public function testDocumentPersisterShouldClearQueuedInsertsOnMongoException(): } catch (BulkWriteException) { } - $this->dm->clear($class); + $this->dm->clear(); // Remove initial object $doc1 = $repository->findOneBy(['name' => 'foo']); $this->dm->remove($doc1); $this->dm->flush(); - $this->dm->clear($class); + $this->dm->clear(); // Create a third object $doc3 = new GH580Document(); $doc3->name = 'bar'; $this->dm->persist($doc3); $this->dm->flush(); - $this->dm->clear($class); + $this->dm->clear(); /* Repository should contain one object, but may contain two if the * DocumentPersister was not cleaned up. diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH593Test.php b/tests/Tests/Functional/Ticket/GH593Test.php similarity index 98% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH593Test.php rename to tests/Tests/Functional/Ticket/GH593Test.php index b468dd2a86..99a741e327 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH593Test.php +++ b/tests/Tests/Functional/Ticket/GH593Test.php @@ -41,7 +41,7 @@ public function testReferenceManyOwningSidePreparesFilterCriteria(): void $this->dm->persist($user2); $this->dm->persist($user3); $this->dm->flush(); - $this->dm->clear($class); + $this->dm->clear(); /* We cannot simply reinitialize the PersistentCollection, because its * $mongoData property has already been cleared and DocumentPersister @@ -85,7 +85,7 @@ public function testReferenceManyInverseSidePreparesFilterCriteria(): void $this->dm->persist($user2); $this->dm->persist($user3); $this->dm->flush(); - $this->dm->clear($class); + $this->dm->clear(); /* We cannot simply reinitialize the PersistentCollection, because its * $mongoData property has already been cleared and DocumentPersister diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH596Test.php b/tests/Tests/Functional/Ticket/GH596Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH596Test.php rename to tests/Tests/Functional/Ticket/GH596Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH597Test.php b/tests/Tests/Functional/Ticket/GH597Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH597Test.php rename to tests/Tests/Functional/Ticket/GH597Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH602Test.php b/tests/Tests/Functional/Ticket/GH602Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH602Test.php rename to tests/Tests/Functional/Ticket/GH602Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH611Test.php b/tests/Tests/Functional/Ticket/GH611Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH611Test.php rename to tests/Tests/Functional/Ticket/GH611Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH628Test.php b/tests/Tests/Functional/Ticket/GH628Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH628Test.php rename to tests/Tests/Functional/Ticket/GH628Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH665Test.php b/tests/Tests/Functional/Ticket/GH665Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH665Test.php rename to tests/Tests/Functional/Ticket/GH665Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH683Test.php b/tests/Tests/Functional/Ticket/GH683Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH683Test.php rename to tests/Tests/Functional/Ticket/GH683Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH774/Doctrine.ODM.MongoDB.Tests.Functional.Ticket.GH774AbstractThread.dcm.xml b/tests/Tests/Functional/Ticket/GH774/Doctrine.ODM.MongoDB.Tests.Functional.Ticket.GH774AbstractThread.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH774/Doctrine.ODM.MongoDB.Tests.Functional.Ticket.GH774AbstractThread.dcm.xml rename to tests/Tests/Functional/Ticket/GH774/Doctrine.ODM.MongoDB.Tests.Functional.Ticket.GH774AbstractThread.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH774/Doctrine.ODM.MongoDB.Tests.Functional.Ticket.GH774Thread.dcm.xml b/tests/Tests/Functional/Ticket/GH774/Doctrine.ODM.MongoDB.Tests.Functional.Ticket.GH774Thread.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH774/Doctrine.ODM.MongoDB.Tests.Functional.Ticket.GH774Thread.dcm.xml rename to tests/Tests/Functional/Ticket/GH774/Doctrine.ODM.MongoDB.Tests.Functional.Ticket.GH774Thread.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH774Test.php b/tests/Tests/Functional/Ticket/GH774Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH774Test.php rename to tests/Tests/Functional/Ticket/GH774Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH788Test.php b/tests/Tests/Functional/Ticket/GH788Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH788Test.php rename to tests/Tests/Functional/Ticket/GH788Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH816Test.php b/tests/Tests/Functional/Ticket/GH816Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH816Test.php rename to tests/Tests/Functional/Ticket/GH816Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH850Test.php b/tests/Tests/Functional/Ticket/GH850Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH850Test.php rename to tests/Tests/Functional/Ticket/GH850Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH852Test.php b/tests/Tests/Functional/Ticket/GH852Test.php similarity index 98% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH852Test.php rename to tests/Tests/Functional/Ticket/GH852Test.php index 3895f43250..14e4545154 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH852Test.php +++ b/tests/Tests/Functional/Ticket/GH852Test.php @@ -14,6 +14,7 @@ use MongoDB\BSON\Binary; use PHPUnit\Framework\Attributes\DataProvider; +/** @see https://github.com/doctrine/mongodb-odm/pull/852 */ class GH852Test extends BaseTestCase { #[DataProvider('provideIdGenerators')] diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH878Test.php b/tests/Tests/Functional/Ticket/GH878Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH878Test.php rename to tests/Tests/Functional/Ticket/GH878Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH880Test.php b/tests/Tests/Functional/Ticket/GH880Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH880Test.php rename to tests/Tests/Functional/Ticket/GH880Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH897Test.php b/tests/Tests/Functional/Ticket/GH897Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH897Test.php rename to tests/Tests/Functional/Ticket/GH897Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH909Test.php b/tests/Tests/Functional/Ticket/GH909Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH909Test.php rename to tests/Tests/Functional/Ticket/GH909Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH921Test.php b/tests/Tests/Functional/Ticket/GH921Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH921Test.php rename to tests/Tests/Functional/Ticket/GH921Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH927Test.php b/tests/Tests/Functional/Ticket/GH927Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH927Test.php rename to tests/Tests/Functional/Ticket/GH927Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH928Test.php b/tests/Tests/Functional/Ticket/GH928Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH928Test.php rename to tests/Tests/Functional/Ticket/GH928Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH936Test.php b/tests/Tests/Functional/Ticket/GH936Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH936Test.php rename to tests/Tests/Functional/Ticket/GH936Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH942Test.php b/tests/Tests/Functional/Ticket/GH942Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH942Test.php rename to tests/Tests/Functional/Ticket/GH942Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH944Test.php b/tests/Tests/Functional/Ticket/GH944Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH944Test.php rename to tests/Tests/Functional/Ticket/GH944Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH971Test.php b/tests/Tests/Functional/Ticket/GH971Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH971Test.php rename to tests/Tests/Functional/Ticket/GH971Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH977Test.php b/tests/Tests/Functional/Ticket/GH977Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH977Test.php rename to tests/Tests/Functional/Ticket/GH977Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH978Test.php b/tests/Tests/Functional/Ticket/GH978Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH978Test.php rename to tests/Tests/Functional/Ticket/GH978Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH999Test.php b/tests/Tests/Functional/Ticket/GH999Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/GH999Test.php rename to tests/Tests/Functional/Ticket/GH999Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM116Test.php b/tests/Tests/Functional/Ticket/MODM116Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM116Test.php rename to tests/Tests/Functional/Ticket/MODM116Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM140Test.php b/tests/Tests/Functional/Ticket/MODM140Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM140Test.php rename to tests/Tests/Functional/Ticket/MODM140Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM160Test.php b/tests/Tests/Functional/Ticket/MODM160Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM160Test.php rename to tests/Tests/Functional/Ticket/MODM160Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM166Test.php b/tests/Tests/Functional/Ticket/MODM166Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM166Test.php rename to tests/Tests/Functional/Ticket/MODM166Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM167Test.php b/tests/Tests/Functional/Ticket/MODM167Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM167Test.php rename to tests/Tests/Functional/Ticket/MODM167Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM29Test.php b/tests/Tests/Functional/Ticket/MODM29Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM29Test.php rename to tests/Tests/Functional/Ticket/MODM29Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM42/test1.txt b/tests/Tests/Functional/Ticket/MODM42/test1.txt similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM42/test1.txt rename to tests/Tests/Functional/Ticket/MODM42/test1.txt diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM42/test2.txt b/tests/Tests/Functional/Ticket/MODM42/test2.txt similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM42/test2.txt rename to tests/Tests/Functional/Ticket/MODM42/test2.txt diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM43Test.php b/tests/Tests/Functional/Ticket/MODM43Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM43Test.php rename to tests/Tests/Functional/Ticket/MODM43Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM45Test.php b/tests/Tests/Functional/Ticket/MODM45Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM45Test.php rename to tests/Tests/Functional/Ticket/MODM45Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM46Test.php b/tests/Tests/Functional/Ticket/MODM46Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM46Test.php rename to tests/Tests/Functional/Ticket/MODM46Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM47Test.php b/tests/Tests/Functional/Ticket/MODM47Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM47Test.php rename to tests/Tests/Functional/Ticket/MODM47Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM48Test.php b/tests/Tests/Functional/Ticket/MODM48Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM48Test.php rename to tests/Tests/Functional/Ticket/MODM48Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM50/test.txt b/tests/Tests/Functional/Ticket/MODM50/test.txt similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM50/test.txt rename to tests/Tests/Functional/Ticket/MODM50/test.txt diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM52Test.php b/tests/Tests/Functional/Ticket/MODM52Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM52Test.php rename to tests/Tests/Functional/Ticket/MODM52Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM56Test.php b/tests/Tests/Functional/Ticket/MODM56Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM56Test.php rename to tests/Tests/Functional/Ticket/MODM56Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM62Test.php b/tests/Tests/Functional/Ticket/MODM62Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM62Test.php rename to tests/Tests/Functional/Ticket/MODM62Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM65Test.php b/tests/Tests/Functional/Ticket/MODM65Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM65Test.php rename to tests/Tests/Functional/Ticket/MODM65Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM66Test.php b/tests/Tests/Functional/Ticket/MODM66Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM66Test.php rename to tests/Tests/Functional/Ticket/MODM66Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM67Test.php b/tests/Tests/Functional/Ticket/MODM67Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM67Test.php rename to tests/Tests/Functional/Ticket/MODM67Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM70Test.php b/tests/Tests/Functional/Ticket/MODM70Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM70Test.php rename to tests/Tests/Functional/Ticket/MODM70Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM72Test.php b/tests/Tests/Functional/Ticket/MODM72Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM72Test.php rename to tests/Tests/Functional/Ticket/MODM72Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM76Test.php b/tests/Tests/Functional/Ticket/MODM76Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM76Test.php rename to tests/Tests/Functional/Ticket/MODM76Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM81Test.php b/tests/Tests/Functional/Ticket/MODM81Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM81Test.php rename to tests/Tests/Functional/Ticket/MODM81Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM83Test.php b/tests/Tests/Functional/Ticket/MODM83Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM83Test.php rename to tests/Tests/Functional/Ticket/MODM83Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM88Test.php b/tests/Tests/Functional/Ticket/MODM88Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM88Test.php rename to tests/Tests/Functional/Ticket/MODM88Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM90Test.php b/tests/Tests/Functional/Ticket/MODM90Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM90Test.php rename to tests/Tests/Functional/Ticket/MODM90Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM91Test.php b/tests/Tests/Functional/Ticket/MODM91Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM91Test.php rename to tests/Tests/Functional/Ticket/MODM91Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM92Test.php b/tests/Tests/Functional/Ticket/MODM92Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM92Test.php rename to tests/Tests/Functional/Ticket/MODM92Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM95Test.php b/tests/Tests/Functional/Ticket/MODM95Test.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/Ticket/MODM95Test.php rename to tests/Tests/Functional/Ticket/MODM95Test.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/TimeSeriesTest.php b/tests/Tests/Functional/TimeSeriesTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/TimeSeriesTest.php rename to tests/Tests/Functional/TimeSeriesTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/TypedPropertiesTest.php b/tests/Tests/Functional/TypedPropertiesTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/TypedPropertiesTest.php rename to tests/Tests/Functional/TypedPropertiesTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/UpsertTest.php b/tests/Tests/Functional/UpsertTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/UpsertTest.php rename to tests/Tests/Functional/UpsertTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/UuidMappingTest.php b/tests/Tests/Functional/UuidMappingTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/UuidMappingTest.php rename to tests/Tests/Functional/UuidMappingTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ValidationTest.php b/tests/Tests/Functional/ValidationTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ValidationTest.php rename to tests/Tests/Functional/ValidationTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/VectorSearchTest.php b/tests/Tests/Functional/VectorSearchTest.php similarity index 61% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/VectorSearchTest.php rename to tests/Tests/Functional/VectorSearchTest.php index 05db805fc0..4c86c538eb 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Functional/VectorSearchTest.php +++ b/tests/Tests/Functional/VectorSearchTest.php @@ -5,9 +5,12 @@ namespace Doctrine\ODM\MongoDB\Tests\Functional; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; +use Doctrine\ODM\MongoDB\Types\Type; use Documents\VectorEmbedding; +use MongoDB\BSON\Binary; use MongoDB\Driver\WriteConcern; use PHPUnit\Framework\Attributes\Group; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; #[Group('atlas')] class VectorSearchTest extends BaseTestCase @@ -45,9 +48,21 @@ public function testAtlasVectorSearch(): void // Index must be created after data insertion, so the index status is not immediately "READY" $schemaManager->createDocumentSearchIndexes(VectorEmbedding::class); - // Wait for search index to be ready (Atlas Local needs time to build the index) + // Wait for the search index to be ready (Atlas Local needs time to build the index) $schemaManager->waitForSearchIndexes([VectorEmbedding::class]); + $results = $this->dm->createQueryBuilder(VectorEmbedding::class)->getQuery()->toArray(); + $this->assertCount(3, $results, 'All documents should be present in the collection'); + + foreach ($results as $result) { + $this->assertInstanceOf(VectorEmbedding::class, $result); + + $this->assertIsArray($result->vectorFloat); + $this->assertCount(3, $result->vectorFloat); + $this->assertIsArray($result->vectorInt); + $this->assertCount(3, $result->vectorInt); + } + $results = $this->dm->createAggregationBuilder(VectorEmbedding::class) ->vectorSearch() ->index('default') @@ -68,6 +83,7 @@ public function testAtlasVectorSearch(): void // Test with filter $results = ($builder = $this->dm->createAggregationBuilder(VectorEmbedding::class)) + ->hydrate(VectorEmbedding::class) ->vectorSearch() ->index('vector_int') ->queryVector([1, 1, 3]) @@ -79,8 +95,28 @@ public function testAtlasVectorSearch(): void $this->assertCount(2, $results); foreach ($results as $result) { - $this->assertIsArray($result); - $this->assertEquals('active', $result['filterField'], 'Filtered results should only contain active documents'); + $this->assertInstanceOf(VectorEmbedding::class, $result); + $this->assertEquals('active', $result->filterField, 'Filtered results should only contain active documents'); } } + + #[RequiresPhpExtension('mongodb', '>= 2.2')] + public function testAtlasVectorSearchWithBinaryType(): void + { + $cm = $this->dm->getClassMetadata(VectorEmbedding::class); + + $cm->fieldMappings['vectorFloat']['type'] = Type::VECTOR_FLOAT32; + $cm->fieldMappings['vectorInt']['type'] = Type::VECTOR_INT8; + + // Change the collection name to avoid conflicts with asynchronous index building + $cm->collection .= '_binary_type'; + + $this->testAtlasVectorSearch(); + + // Ensure that the vectors are stored in as binary vectors + $doc = $this->dm->getDocumentCollection(VectorEmbedding::class)->findOne(['filterField' => 'active']); + $this->assertIsArray($doc); + $this->assertInstanceOf(Binary::class, $doc['vectorInt']); + $this->assertInstanceOf(Binary::class, $doc['db_vector_float']); + } } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/VersionTest.php b/tests/Tests/Functional/VersionTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/VersionTest.php rename to tests/Tests/Functional/VersionTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/ViewTest.php b/tests/Tests/Functional/ViewTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/ViewTest.php rename to tests/Tests/Functional/ViewTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/XmlMappingQueryableEncryptionTest.php b/tests/Tests/Functional/XmlMappingQueryableEncryptionTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/XmlMappingQueryableEncryptionTest.php rename to tests/Tests/Functional/XmlMappingQueryableEncryptionTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Functional/file.txt b/tests/Tests/Functional/file.txt similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Functional/file.txt rename to tests/Tests/Functional/file.txt diff --git a/tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php b/tests/Tests/HydratorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/HydratorTest.php rename to tests/Tests/HydratorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Id/IncrementGeneratorTest.php b/tests/Tests/Id/IncrementGeneratorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Id/IncrementGeneratorTest.php rename to tests/Tests/Id/IncrementGeneratorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AbstractAnnotationDriverTestCase.php b/tests/Tests/Mapping/AbstractAnnotationDriverTestCase.php similarity index 93% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/AbstractAnnotationDriverTestCase.php rename to tests/Tests/Mapping/AbstractAnnotationDriverTestCase.php index be73863dcc..b90e6f54f4 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AbstractAnnotationDriverTestCase.php +++ b/tests/Tests/Mapping/AbstractAnnotationDriverTestCase.php @@ -16,6 +16,7 @@ use stdClass; use function assert; +use function class_exists; abstract class AbstractAnnotationDriverTestCase extends AbstractMappingDriverTestCase { @@ -71,7 +72,6 @@ public function testFieldInheritance(): void self::assertEquals(AnnotationDriverTestParent::class, $child->fieldMappings['foo']['declared'], 'Inherited public field from Document parent is declared in Document parent'); } - /** @group DDC-268 */ public function testLoadMetadataForNonDocumentThrowsException(): void { $cm = new ClassMetadata('stdClass'); @@ -81,7 +81,6 @@ public function testLoadMetadataForNonDocumentThrowsException(): void $annotationDriver->loadMetadataForClass('stdClass', $cm); } - /** @group DDC-268 */ public function testColumnWithMissingTypeDefaultsToString(): void { $cm = new ClassMetadata(ColumnWithoutType::class); @@ -91,40 +90,15 @@ public function testColumnWithMissingTypeDefaultsToString(): void self::assertEquals('id', $cm->fieldMappings['id']['type']); } - /** @group DDC-318 */ - public function testGetAllClassNamesIsIdempotent(): void - { - $annotationDriver = $this->loadDriverForCMSDocuments(); - $original = $annotationDriver->getAllClassNames(); - - $annotationDriver = $this->loadDriverForCMSDocuments(); - $afterTestReset = $annotationDriver->getAllClassNames(); - - self::assertEquals($original, $afterTestReset); - } - - /** @group DDC-318 */ - public function testGetAllClassNamesIsIdempotentEvenWithDifferentDriverInstances(): void - { - $annotationDriver = $this->loadDriverForCMSDocuments(); - $original = $annotationDriver->getAllClassNames(); - - $annotationDriver = $this->loadDriverForCMSDocuments(); - $afterTestReset = $annotationDriver->getAllClassNames(); - - self::assertEquals($original, $afterTestReset); - } - - /** @group DDC-318 */ public function testGetAllClassNamesReturnsAlreadyLoadedClassesIfAppropriate(): void { + self::assertTrue(class_exists(CmsUser::class), 'Pre-load the class'); $annotationDriver = $this->loadDriverForCMSDocuments(); $classes = $annotationDriver->getAllClassNames(); self::assertContains(CmsUser::class, $classes); } - /** @group DDC-318 */ public function testGetClassNamesReturnsOnlyTheAppropriateClasses(): void { $extraneousClassName = ColumnWithoutType::class; @@ -252,7 +226,7 @@ public function testWrongValueForValidationValidatorShouldThrowException(): void protected function loadDriverForCMSDocuments(): MappingDriver { - $annotationDriver = static::loadDriver([__DIR__ . '/../../../../../Documents']); + $annotationDriver = static::loadDriver([__DIR__ . '/../../Documents']); assert($annotationDriver instanceof AnnotationDriver || $annotationDriver instanceof AttributeDriver); return $annotationDriver; diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AbstractMappingDriverTestCase.php b/tests/Tests/Mapping/AbstractMappingDriverTestCase.php similarity index 99% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/AbstractMappingDriverTestCase.php rename to tests/Tests/Mapping/AbstractMappingDriverTestCase.php index c4a8be3546..2b60e8d1f9 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AbstractMappingDriverTestCase.php +++ b/tests/Tests/Mapping/AbstractMappingDriverTestCase.php @@ -11,6 +11,7 @@ use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; use Doctrine\ODM\MongoDB\Mapping\MappingException; +use Doctrine\ODM\MongoDB\Mapping\PropertyAccessors\EnumPropertyAccessor; use Doctrine\ODM\MongoDB\Mapping\TimeSeries\Granularity; use Doctrine\ODM\MongoDB\Repository\DefaultGridFSRepository; use Doctrine\ODM\MongoDB\Repository\DocumentRepository; @@ -18,7 +19,6 @@ use Doctrine\ODM\MongoDB\Tests\BaseTestCase; use Doctrine\ODM\MongoDB\Types\Type; use Doctrine\Persistence\Mapping\Driver\MappingDriver; -use Doctrine\Persistence\Reflection\EnumReflectionProperty; use Documents\Card; use Documents\CustomCollection; use Documents\Suit; @@ -699,12 +699,12 @@ public function testEnumType(): void self::assertSame(Suit::class, $metadata->fieldMappings['suit']['enumType']); self::assertSame('string', $metadata->fieldMappings['suit']['type']); self::assertFalse($metadata->fieldMappings['suit']['nullable']); - self::assertInstanceOf(EnumReflectionProperty::class, $metadata->reflFields['suit']); + self::assertInstanceOf(EnumPropertyAccessor::class, $metadata->propertyAccessors['suit']); self::assertSame(Suit::class, $metadata->fieldMappings['nullableSuit']['enumType']); self::assertSame('string', $metadata->fieldMappings['nullableSuit']['type']); self::assertTrue($metadata->fieldMappings['nullableSuit']['nullable']); - self::assertInstanceOf(EnumReflectionProperty::class, $metadata->reflFields['nullableSuit']); + self::assertInstanceOf(EnumPropertyAccessor::class, $metadata->propertyAccessors['nullableSuit']); } public function testTimeSeriesDocumentWithGranularity(): void @@ -734,7 +734,8 @@ public function testTimeSeriesDocumentWithBucket(): void * @ODM\DiscriminatorMap({"default"="Doctrine\ODM\MongoDB\Tests\Mapping\AbstractMappingDriverUser"}) * @ODM\DefaultDiscriminatorValue("default") * @ODM\HasLifecycleCallbacks - * @ODM\Indexes(@ODM\Index(keys={"createdAt"="asc"},expireAfterSeconds=3600),@ODM\Index(keys={"lock"="asc"},partialFilterExpression={"version"={"$gt"=1},"discr"={"$eq"="default"}})) + * @ODM\Index(keys={"createdAt"="asc"},expireAfterSeconds=3600) + * @ODM\Index(keys={"lock"="asc"},partialFilterExpression={"version"={"$gt"=1},"discr"={"$eq"="default"}}) * @ODM\SearchIndex(dynamic=true, analyzer="lucene.standard", searchAnalyzer="lucene.standard", storedSource=true) * @ODM\SearchIndex( * name="usernameAndPhoneNumbers", diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AnnotationDriverTest.php b/tests/Tests/Mapping/AnnotationDriverTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/AnnotationDriverTest.php rename to tests/Tests/Mapping/AnnotationDriverTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/AttributeDriverTest.php b/tests/Tests/Mapping/AttributeDriverTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/AttributeDriverTest.php rename to tests/Tests/Mapping/AttributeDriverTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/BasicInheritanceMappingTest.php b/tests/Tests/Mapping/BasicInheritanceMappingTest.php similarity index 95% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/BasicInheritanceMappingTest.php rename to tests/Tests/Mapping/BasicInheritanceMappingTest.php index 832a208feb..38c787c50d 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/BasicInheritanceMappingTest.php +++ b/tests/Tests/Mapping/BasicInheritanceMappingTest.php @@ -60,16 +60,15 @@ public function testGetMetadataForSubclassWithMappedSuperclass(): void self::assertTrue(isset($class->fieldMappings['mappedRelated1'])); } - /** @group DDC-388 */ public function testSerializationWithPrivateFieldsFromMappedSuperclass(): void { $class = $this->factory->getMetadataFor(DocumentSubClass2::class); $class2 = unserialize(serialize($class)); - self::assertTrue(isset($class2->reflFields['mapped1'])); - self::assertTrue(isset($class2->reflFields['mapped2'])); - self::assertTrue(isset($class2->reflFields['mappedRelated1'])); + self::assertTrue(isset($class2->propertyAccessors['mapped1'])); + self::assertTrue(isset($class2->propertyAccessors['mapped2'])); + self::assertTrue(isset($class2->propertyAccessors['mappedRelated1'])); } public function testReadPreferenceIsInherited(): void diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataLoadEventTest.php b/tests/Tests/Mapping/ClassMetadataLoadEventTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataLoadEventTest.php rename to tests/Tests/Mapping/ClassMetadataLoadEventTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php b/tests/Tests/Mapping/ClassMetadataTest.php similarity index 98% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php rename to tests/Tests/Mapping/ClassMetadataTest.php index 5c8a780206..b6e420ff17 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/ClassMetadataTest.php +++ b/tests/Tests/Mapping/ClassMetadataTest.php @@ -8,14 +8,15 @@ use Doctrine\ODM\MongoDB\Events; use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM; use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; +use Doctrine\ODM\MongoDB\Mapping\LegacyReflectionFields; use Doctrine\ODM\MongoDB\Mapping\MappingException; +use Doctrine\ODM\MongoDB\Mapping\PropertyAccessors\EnumPropertyAccessor; use Doctrine\ODM\MongoDB\Mapping\TimeSeries\Granularity; use Doctrine\ODM\MongoDB\Repository\DocumentRepository; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; use Doctrine\ODM\MongoDB\Tests\ClassMetadataTestUtil; use Doctrine\ODM\MongoDB\Types\Type; use Doctrine\ODM\MongoDB\Utility\CollectionHelper; -use Doctrine\Persistence\Reflection\EnumReflectionProperty; use DoctrineGlobal_Article; use DoctrineGlobal_User; use Documents\Account; @@ -55,7 +56,8 @@ public function testClassMetadataInstanceSerialization(): void $cm = new ClassMetadata(CmsUser::class); // Test initial state - self::assertEmpty($cm->getReflectionProperties()); + self::assertInstanceOf(LegacyReflectionFields::class, $cm->getReflectionProperties()); + self::assertEmpty($cm->getPropertyAccessors()); self::assertInstanceOf(ReflectionClass::class, $cm->reflClass); self::assertEquals(CmsUser::class, $cm->name); self::assertEquals(CmsUser::class, $cm->rootDocumentName); @@ -90,7 +92,8 @@ public function testClassMetadataInstanceSerialization(): void $cm = unserialize($serialized); // Check state - self::assertGreaterThan(0, $cm->getReflectionProperties()); + self::assertInstanceOf(LegacyReflectionFields::class, $cm->getReflectionProperties()); + self::assertNotEmpty($cm->getPropertyAccessors()); self::assertInstanceOf(ReflectionClass::class, $cm->reflClass); self::assertEquals(CmsUser::class, $cm->name); self::assertEquals(stdClass::class, $cm->rootDocumentName); @@ -203,17 +206,17 @@ public function testEnumTypeFromReflection(): void self::assertFalse($cm->isNullable('nullableSuit')); } - public function testEnumReflectionPropertySerialization(): void + public function testEnumPropertyAccessorSerialization(): void { $cm = new ClassMetadata(Card::class); $cm->mapField(['fieldName' => 'suit']); - self::assertInstanceOf(EnumReflectionProperty::class, $cm->reflFields['suit']); + self::assertInstanceOf(EnumPropertyAccessor::class, $cm->propertyAccessors['suit']); $serialized = serialize($cm); $cm = unserialize($serialized); - self::assertInstanceOf(EnumReflectionProperty::class, $cm->reflFields['suit']); + self::assertInstanceOf(EnumPropertyAccessor::class, $cm->propertyAccessors['suit']); } public function testEnumTypeFromReflectionMustBeBacked(): void @@ -267,7 +270,6 @@ public function testEnumTypeMustPointToABackedEnum(): void ]); } - /** @group DDC-115 */ public function testMapAssocationInGlobalNamespace(): void { require_once __DIR__ . '/Documents/GlobalNamespaceDocument.php'; @@ -308,7 +310,6 @@ public function testGetAssociationTargetClassWithoutTargetDocument(): void self::assertNull($cm->getAssociationTargetClass('groups')); } - /** @group DDC-115 */ public function testSetDiscriminatorMapInGlobalNamespace(): void { require_once __DIR__ . '/Documents/GlobalNamespaceDocument.php'; @@ -320,7 +321,6 @@ public function testSetDiscriminatorMapInGlobalNamespace(): void self::assertEquals(DoctrineGlobal_User::class, $cm->discriminatorMap['foo']); } - /** @group DDC-115 */ public function testSetSubClassesInGlobalNamespace(): void { require_once __DIR__ . '/Documents/GlobalNamespaceDocument.php'; diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Documents/GlobalNamespaceDocument.php b/tests/Tests/Mapping/Documents/GlobalNamespaceDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Documents/GlobalNamespaceDocument.php rename to tests/Tests/Mapping/Documents/GlobalNamespaceDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/AbstractDriverTestCase.php b/tests/Tests/Mapping/Driver/AbstractDriverTestCase.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/AbstractDriverTestCase.php rename to tests/Tests/Mapping/Driver/AbstractDriverTestCase.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/XmlDriverTest.php b/tests/Tests/Mapping/Driver/XmlDriverTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/XmlDriverTest.php rename to tests/Tests/Mapping/Driver/XmlDriverTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/AlsoLoadDocument.php b/tests/Tests/Mapping/Driver/fixtures/AlsoLoadDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/AlsoLoadDocument.php rename to tests/Tests/Mapping/Driver/fixtures/AlsoLoadDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/EmbeddedDocument.php b/tests/Tests/Mapping/Driver/fixtures/EmbeddedDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/EmbeddedDocument.php rename to tests/Tests/Mapping/Driver/fixtures/EmbeddedDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/InvalidEmbeddedDocument.php b/tests/Tests/Mapping/Driver/fixtures/InvalidEmbeddedDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/InvalidEmbeddedDocument.php rename to tests/Tests/Mapping/Driver/fixtures/InvalidEmbeddedDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/InvalidPartialFilterDocument.php b/tests/Tests/Mapping/Driver/fixtures/InvalidPartialFilterDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/InvalidPartialFilterDocument.php rename to tests/Tests/Mapping/Driver/fixtures/InvalidPartialFilterDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/NullableFieldsDocument.php b/tests/Tests/Mapping/Driver/fixtures/NullableFieldsDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/NullableFieldsDocument.php rename to tests/Tests/Mapping/Driver/fixtures/NullableFieldsDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/PartialFilterDocument.php b/tests/Tests/Mapping/Driver/fixtures/PartialFilterDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/PartialFilterDocument.php rename to tests/Tests/Mapping/Driver/fixtures/PartialFilterDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/PrimedCollectionDocument.php b/tests/Tests/Mapping/Driver/fixtures/PrimedCollectionDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/PrimedCollectionDocument.php rename to tests/Tests/Mapping/Driver/fixtures/PrimedCollectionDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/QueryResultDocument.php b/tests/Tests/Mapping/Driver/fixtures/QueryResultDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/QueryResultDocument.php rename to tests/Tests/Mapping/Driver/fixtures/QueryResultDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/SchemaInvalidDocument.php b/tests/Tests/Mapping/Driver/fixtures/SchemaInvalidDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/SchemaInvalidDocument.php rename to tests/Tests/Mapping/Driver/fixtures/SchemaInvalidDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/SchemaValidatedDocument.php b/tests/Tests/Mapping/Driver/fixtures/SchemaValidatedDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/SchemaValidatedDocument.php rename to tests/Tests/Mapping/Driver/fixtures/SchemaValidatedDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/User.php b/tests/Tests/Mapping/Driver/fixtures/User.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/User.php rename to tests/Tests/Mapping/Driver/fixtures/User.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/View.php b/tests/Tests/Mapping/Driver/fixtures/View.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/View.php rename to tests/Tests/Mapping/Driver/fixtures/View.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/WildcardIndexDocument.php b/tests/Tests/Mapping/Driver/fixtures/WildcardIndexDocument.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/WildcardIndexDocument.php rename to tests/Tests/Mapping/Driver/fixtures/WildcardIndexDocument.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.ClientCard.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.ClientCard.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.ClientCard.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.ClientCard.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.Patient.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.Patient.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.Patient.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.Patient.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.PatientBilling.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.PatientBilling.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.PatientBilling.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.PatientBilling.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.PatientRecord.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.PatientRecord.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.PatientRecord.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.PatientRecord.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.RangeTypes.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.RangeTypes.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.RangeTypes.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/Documents.Encryption.RangeTypes.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.AlsoLoadDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.AlsoLoadDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.AlsoLoadDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.AlsoLoadDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.EmbeddedDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.EmbeddedDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.EmbeddedDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.EmbeddedDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.InvalidEmbeddedDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.InvalidEmbeddedDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.InvalidEmbeddedDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.InvalidEmbeddedDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.InvalidPartialFilterDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.InvalidPartialFilterDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.InvalidPartialFilterDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.InvalidPartialFilterDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.NullableFieldsDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.NullableFieldsDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.NullableFieldsDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.NullableFieldsDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.PartialFilterDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.PartialFilterDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.PartialFilterDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.PartialFilterDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.PrimedCollectionDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.PrimedCollectionDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.PrimedCollectionDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.PrimedCollectionDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.QueryResultDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.QueryResultDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.QueryResultDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.QueryResultDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.SchemaInvalidDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.SchemaInvalidDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.SchemaInvalidDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.SchemaInvalidDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.SchemaValidatedDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.SchemaValidatedDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.SchemaValidatedDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.SchemaValidatedDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.User.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.User.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.User.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.User.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.UserCustomIdGenerator.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.UserCustomIdGenerator.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.UserCustomIdGenerator.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.UserCustomIdGenerator.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.UserNonStringOptions.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.UserNonStringOptions.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.UserNonStringOptions.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.UserNonStringOptions.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.View.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.View.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.View.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.View.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.WildcardIndexDocument.dcm.xml b/tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.WildcardIndexDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Driver/fixtures/xml/TestDocuments.WildcardIndexDocument.dcm.xml rename to tests/Tests/Mapping/Driver/fixtures/xml/TestDocuments.WildcardIndexDocument.dcm.xml diff --git a/tests/Tests/Mapping/LegacyReflectionFieldsTest.php b/tests/Tests/Mapping/LegacyReflectionFieldsTest.php new file mode 100644 index 0000000000..860f953130 --- /dev/null +++ b/tests/Tests/Mapping/LegacyReflectionFieldsTest.php @@ -0,0 +1,75 @@ +dm->getClassMetadata(User::class); + self::assertInstanceOf(LegacyReflectionFields::class, $class->reflFields); + + $user = new User(); + $user->setUsername('Jean'); + $user->setInheritedProperty('inherited'); + $address = new Address(); + $address->setCity('Paris'); + $user->setAddress($address); + + $this->dm->persist($user); + $this->dm->flush(); + $this->dm->clear(); + + $user = $this->dm->find(User::class, $user->getId()); + + // Accessing the field directly through reflection + self::assertEquals('Jean', $class->getReflectionProperty('username')->getValue($user)); + $class->getReflectionProperty('username')->setValue($user, 'Marie'); + self::assertEquals('Marie', $class->getReflectionProperty('username')->getValue($user)); + + // Accessing a private field 'inheritedProperty' of the parent class through reflection + self::assertEquals('inherited', $class->getReflectionProperty('inheritedProperty')->getValue($user)); + $class->getReflectionProperty('inheritedProperty')->setValue($user, 'changed'); + self::assertEquals('changed', $class->getReflectionProperty('inheritedProperty')->getValue($user)); + + // Accessing a field in a related document through reflection + self::assertEquals('Paris', $class->getReflectionProperty('address')->getValue($user)->getCity()); + $class->getReflectionProperty('address')->setValue($user, $newAddress = new Address()); + self::assertSame($newAddress, $class->getReflectionProperty('address')->getValue($user)); + + // ArrayAccess and Countable interfaces + self::assertCount(32, $class->reflFields); + self::assertArrayHasKey('username', $class->reflFields); + self::assertArrayNotHasKey('nonExistentField', $class->reflFields); + } + + public function testGetSetReadonly(): void + { + $class = $this->dm->getClassMetadata(Tag::class); + self::assertInstanceOf(LegacyReflectionFields::class, $class->reflFields); + + $tag = new Tag('Important'); + $this->dm->persist($tag); + $this->dm->flush(); + + $tag = $this->dm->find(Tag::class, $tag->id); + + // Accessing the readonly property through reflection + self::assertEquals('Important', $class->getReflectionProperty('name')->getValue($tag)); + + self::expectException(LogicException::class); + self::expectExceptionMessage('Attempting to change readonly property Documents\Tag::$name'); + $class->getReflectionProperty('name')->setValue($tag, 'Very Important'); + } +} diff --git a/tests/Tests/Mapping/PropertyAccessors/EnumPropertyAccessorTest.php b/tests/Tests/Mapping/PropertyAccessors/EnumPropertyAccessorTest.php new file mode 100644 index 0000000000..1353ac57d6 --- /dev/null +++ b/tests/Tests/Mapping/PropertyAccessors/EnumPropertyAccessorTest.php @@ -0,0 +1,66 @@ +setValue($object, EnumType::A); + + $this->assertEquals($object->enum, EnumType::A); + $this->assertEquals(EnumType::A->value, $accessor->getValue($object)); + } + + public function testEnumSetDatabaseGetValue(): void + { + $object = new EnumClass(); + $accessor = PropertyAccessorFactory::createPropertyAccessor(EnumClass::class, 'enum'); + + $accessor = new EnumPropertyAccessor($accessor, EnumType::class); + + $accessor->setValue($object, EnumType::A->value); + + $this->assertEquals($object->enum, EnumType::A); + $this->assertEquals(EnumType::A->value, $accessor->getValue($object)); + } + + public function testEnumSetDatabaseArrayGetValue(): void + { + $object = new EnumClass(); + $accessor = PropertyAccessorFactory::createPropertyAccessor(EnumClass::class, 'enumList'); + + $accessor = new EnumPropertyAccessor($accessor, EnumType::class); + + $accessor->setValue($object, $values = [EnumType::A->value, EnumType::B->value, EnumType::C->value]); + + $this->assertEquals($object->enumList, [EnumType::A, EnumType::B, EnumType::C]); + $this->assertEquals($values, $accessor->getValue($object)); + } +} + +class EnumClass +{ + public EnumType $enum; + + /** @var EnumType[] */ + public array $enumList; +} + +enum EnumType: string +{ + case A = 'a'; + case B = 'b'; + case C = 'c'; +} diff --git a/tests/Tests/Mapping/PropertyAccessors/ObjectCastPropertyAccessorTest.php b/tests/Tests/Mapping/PropertyAccessors/ObjectCastPropertyAccessorTest.php new file mode 100644 index 0000000000..62563b76a7 --- /dev/null +++ b/tests/Tests/Mapping/PropertyAccessors/ObjectCastPropertyAccessorTest.php @@ -0,0 +1,85 @@ +setValue($object, 'value'); + + $this->assertEquals($object->property, 'value'); + $this->assertEquals('value', $accessor->getValue($object)); + } + + public function testSetGetPrivatePropertyValue(): void + { + $object = new ObjectClass(); + $accessor = ObjectCastPropertyAccessor::fromNames(ObjectClass::class, 'property2'); + + $accessor->setValue($object, 'value'); + + $this->assertEquals($object->getProperty2(), 'value'); + $this->assertEquals('value', $accessor->getValue($object)); + } + + public function testSetGetInternalProxyValue(): void + { + $object = new ObjectClassInternalProxy(); + $accessor = ObjectCastPropertyAccessor::fromNames(ObjectClassInternalProxy::class, 'property'); + + $accessor->setValue($object, 'value'); + + $this->assertEquals($object->property, 'value'); + $this->assertEquals('value', $accessor->getValue($object)); + $this->assertFalse($object->isInitialized); + $this->assertEquals(2, $object->counter); + } +} + +class ObjectClass +{ + /** @var string */ + public $property; + /** @var string */ + private $property2; + + public function getProperty2(): string + { + return $this->property2; + } +} + +/** @implements InternalProxy */ +class ObjectClassInternalProxy implements InternalProxy +{ + /** @var string */ + public $property; + public bool $isInitialized = false; + public int $counter = 0; + + public function __setInitialized(bool $initialized): void + { + $this->isInitialized = $initialized; + $this->counter++; + } + + public function __load(): void + { + } + + /** Returns whether this proxy is initialized or not. */ + public function __isInitialized(): bool + { + return $this->isInitialized; + } +} diff --git a/tests/Tests/Mapping/PropertyAccessors/RawValuePropertyAccessorTest.php b/tests/Tests/Mapping/PropertyAccessors/RawValuePropertyAccessorTest.php new file mode 100644 index 0000000000..bf116c16ef --- /dev/null +++ b/tests/Tests/Mapping/PropertyAccessors/RawValuePropertyAccessorTest.php @@ -0,0 +1,54 @@ += 8.4.0')] +class RawValuePropertyAccessorTest extends BaseTestCase +{ + public function testSetGetValue(): void + { + $object = new User(); + $reflection = new ReflectionObject($object); + $accessorFirst = RawValuePropertyAccessor::fromReflectionProperty($reflection->getProperty('first')); + $accessorLast = RawValuePropertyAccessor::fromReflectionProperty($reflection->getProperty('last')); + + $accessorFirst->setValue($object, 'Benjamin'); + $accessorLast->setValue($object, 'Eberlei'); + + self::assertEquals('Benjamin Eberlei', $object->fullName); + self::assertEquals('Benjamin', $accessorFirst->getValue($object)); + self::assertEquals('Eberlei', $accessorLast->getValue($object)); + + $accessorFirst->setValue($object, ''); + $accessorLast->setValue($object, ''); + + self::assertEquals('', trim($object->fullName)); + } + + public function testSetGetValueWithLanguage(): void + { + $object = new User(); + $reflection = new ReflectionObject($object); + $accessor = RawValuePropertyAccessor::fromReflectionProperty($reflection->getProperty('language')); + + $accessor->setValue($object, 'en'); + + self::assertEquals('EN', $object->language); + self::assertEquals('en', $accessor->getValue($object)); + + $accessor->setValue($object, 'EN'); + + self::assertEquals('EN', $object->language); + self::assertEquals('EN', $accessor->getValue($object)); + } +} diff --git a/tests/Tests/Mapping/PropertyAccessors/ReadOnlyAccessorTest.php b/tests/Tests/Mapping/PropertyAccessors/ReadOnlyAccessorTest.php new file mode 100644 index 0000000000..2bdbd681b6 --- /dev/null +++ b/tests/Tests/Mapping/PropertyAccessors/ReadOnlyAccessorTest.php @@ -0,0 +1,44 @@ +assertInstanceOf(ReadonlyAccessor::class, $accessor); + + $accessor->setValue($object, 1); + + $this->assertEquals($object->property, 1); + $this->assertEquals(1, $accessor->getValue($object)); + } + + public function testReadOnlyPropertyOnlyOnce(): void + { + $object = new ReadOnlyClass(); + $accessor = PropertyAccessorFactory::createPropertyAccessor(ReadOnlyClass::class, 'property'); + + $this->assertInstanceOf(ReadonlyAccessor::class, $accessor); + + $accessor->setValue($object, 1); + $this->expectException(LogicException::class); + $accessor->setValue($object, 2); + } +} + +class ReadOnlyClass +{ + // @phpstan-ignore property.uninitializedReadonly + public readonly int $property; +} diff --git a/tests/Tests/Mapping/PropertyAccessors/TypedNoDefaultPropertyAccessorTest.php b/tests/Tests/Mapping/PropertyAccessors/TypedNoDefaultPropertyAccessorTest.php new file mode 100644 index 0000000000..8138c7be8e --- /dev/null +++ b/tests/Tests/Mapping/PropertyAccessors/TypedNoDefaultPropertyAccessorTest.php @@ -0,0 +1,43 @@ +assertInstanceOf(TypedNoDefaultPropertyAccessor::class, $accessor); + + $object = new TypedClass(); + $accessor->setValue($object, 42); + $this->assertEquals(42, $accessor->getValue($object)); + } + + public function testSetNullWithoutDefault(): void + { + $accessor = PropertyAccessorFactory::createPropertyAccessor(TypedClass::class, 'property'); + + $object = new TypedClass(); + $accessor->setValue($object, null); + $this->assertNull($accessor->getValue($object)); + + $accessor->setValue($object, 42); + $this->assertEquals(42, $accessor->getValue($object)); + + $accessor->setValue($object, null); + $this->assertNull($accessor->getValue($object)); + } +} + +class TypedClass +{ + public int $property; +} diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/ShardKeyInheritanceMappingTest.php b/tests/Tests/Mapping/ShardKeyInheritanceMappingTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/ShardKeyInheritanceMappingTest.php rename to tests/Tests/Mapping/ShardKeyInheritanceMappingTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Symfony/AbstractDriverTestCase.php b/tests/Tests/Mapping/Symfony/AbstractDriverTestCase.php similarity index 98% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Symfony/AbstractDriverTestCase.php rename to tests/Tests/Mapping/Symfony/AbstractDriverTestCase.php index 9d6f7a45b6..3a827fc4b4 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Symfony/AbstractDriverTestCase.php +++ b/tests/Tests/Mapping/Symfony/AbstractDriverTestCase.php @@ -6,7 +6,6 @@ use Doctrine\Persistence\Mapping\Driver\FileDriver; use Doctrine\Persistence\Mapping\MappingException; -use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\TestCase; use RecursiveDirectoryIterator; use RecursiveIteratorIterator; @@ -17,7 +16,6 @@ use function touch; use function unlink; -#[Group('DDC-1418')] abstract class AbstractDriverTestCase extends TestCase { protected string $dir; diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Symfony/XmlDriverTest.php b/tests/Tests/Mapping/Symfony/XmlDriverTest.php similarity index 88% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/Symfony/XmlDriverTest.php rename to tests/Tests/Mapping/Symfony/XmlDriverTest.php index d234c208e0..0a98794309 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/Symfony/XmlDriverTest.php +++ b/tests/Tests/Mapping/Symfony/XmlDriverTest.php @@ -5,11 +5,9 @@ namespace Doctrine\ODM\MongoDB\Tests\Mapping\Symfony; use Doctrine\ODM\MongoDB\Mapping\Driver\SimplifiedXmlDriver; -use PHPUnit\Framework\Attributes\Group; use function array_flip; -#[Group('DDC-1418')] class XmlDriverTest extends AbstractDriverTestCase { protected function getFileExtension(): string diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/XmlMappingDriverTest.php b/tests/Tests/Mapping/XmlMappingDriverTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/XmlMappingDriverTest.php rename to tests/Tests/Mapping/XmlMappingDriverTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverDuplicateDatabaseName.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverDuplicateDatabaseName.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverDuplicateDatabaseName.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverDuplicateDatabaseName.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverDuplicateDatabaseNameNotSaved.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverDuplicateDatabaseNameNotSaved.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverDuplicateDatabaseNameNotSaved.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverDuplicateDatabaseNameNotSaved.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverFile.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverFile.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverFile.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverFile.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverFileWithCustomRepository.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverFileWithCustomRepository.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverFileWithCustomRepository.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverFileWithCustomRepository.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverSuperClass.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverSuperClass.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverSuperClass.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverSuperClass.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverTimeSeriesDocumentWithBucket.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverTimeSeriesDocumentWithBucket.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverTimeSeriesDocumentWithBucket.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverTimeSeriesDocumentWithBucket.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverTimeSeriesDocumentWithGranularity.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverTimeSeriesDocumentWithGranularity.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverTimeSeriesDocumentWithGranularity.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverTimeSeriesDocumentWithGranularity.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverUser.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverUser.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverUser.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverUser.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverView.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverView.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverView.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverView.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithNonExistingRootClass.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithNonExistingRootClass.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithNonExistingRootClass.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithNonExistingRootClass.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithWrongRepository.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithWrongRepository.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithWrongRepository.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithWrongRepository.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithoutRepository.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithoutRepository.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithoutRepository.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithoutRepository.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithoutRootClass.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithoutRootClass.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithoutRootClass.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.AbstractMappingDriverViewWithoutRootClass.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.InvalidMappingDocument.dcm.xml b/tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.InvalidMappingDocument.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.InvalidMappingDocument.dcm.xml rename to tests/Tests/Mapping/xml/Doctrine.ODM.MongoDB.Tests.Mapping.InvalidMappingDocument.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Documents.Card.dcm.xml b/tests/Tests/Mapping/xml/Documents.Card.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Documents.Card.dcm.xml rename to tests/Tests/Mapping/xml/Documents.Card.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Documents.UserTyped.dcm.xml b/tests/Tests/Mapping/xml/Documents.UserTyped.dcm.xml similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mapping/xml/Documents.UserTyped.dcm.xml rename to tests/Tests/Mapping/xml/Documents.UserTyped.dcm.xml diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mocks/ExceptionThrowingListenerMock.php b/tests/Tests/Mocks/ExceptionThrowingListenerMock.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mocks/ExceptionThrowingListenerMock.php rename to tests/Tests/Mocks/ExceptionThrowingListenerMock.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Mocks/PreUpdateListenerMock.php b/tests/Tests/Mocks/PreUpdateListenerMock.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Mocks/PreUpdateListenerMock.php rename to tests/Tests/Mocks/PreUpdateListenerMock.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/MongoCollectionTest.php b/tests/Tests/MongoCollectionTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/MongoCollectionTest.php rename to tests/Tests/MongoCollectionTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Performance/HydrationPerformanceTest.php b/tests/Tests/Performance/HydrationPerformanceTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Performance/HydrationPerformanceTest.php rename to tests/Tests/Performance/HydrationPerformanceTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Performance/InsertPerformanceTest.php b/tests/Tests/Performance/InsertPerformanceTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Performance/InsertPerformanceTest.php rename to tests/Tests/Performance/InsertPerformanceTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Performance/MemoryUsageTest.php b/tests/Tests/Performance/MemoryUsageTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Performance/MemoryUsageTest.php rename to tests/Tests/Performance/MemoryUsageTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Performance/UnitOfWorkPerformanceTest.php b/tests/Tests/Performance/UnitOfWorkPerformanceTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Performance/UnitOfWorkPerformanceTest.php rename to tests/Tests/Performance/UnitOfWorkPerformanceTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollNoReturnType.php b/tests/Tests/PersistentCollection/CollNoReturnType.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollNoReturnType.php rename to tests/Tests/PersistentCollection/CollNoReturnType.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithNullableReturnType.php b/tests/Tests/PersistentCollection/CollWithNullableReturnType.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithNullableReturnType.php rename to tests/Tests/PersistentCollection/CollWithNullableReturnType.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP80Types.php b/tests/Tests/PersistentCollection/CollWithPHP80Types.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP80Types.php rename to tests/Tests/PersistentCollection/CollWithPHP80Types.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP81Types.php b/tests/Tests/PersistentCollection/CollWithPHP81Types.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithPHP81Types.php rename to tests/Tests/PersistentCollection/CollWithPHP81Types.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithReturnType.php b/tests/Tests/PersistentCollection/CollWithReturnType.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/CollWithReturnType.php rename to tests/Tests/PersistentCollection/CollWithReturnType.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/DefaultPersistentCollectionGeneratorTest.php b/tests/Tests/PersistentCollection/DefaultPersistentCollectionGeneratorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/PersistentCollection/DefaultPersistentCollectionGeneratorTest.php rename to tests/Tests/PersistentCollection/DefaultPersistentCollectionGeneratorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/PersistentCollectionTest.php b/tests/Tests/PersistentCollectionTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/PersistentCollectionTest.php rename to tests/Tests/PersistentCollectionTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Persisters/DocumentPersisterFilterTest.php b/tests/Tests/Persisters/DocumentPersisterFilterTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Persisters/DocumentPersisterFilterTest.php rename to tests/Tests/Persisters/DocumentPersisterFilterTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Persisters/DocumentPersisterGetShardKeyQueryTest.php b/tests/Tests/Persisters/DocumentPersisterGetShardKeyQueryTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Persisters/DocumentPersisterGetShardKeyQueryTest.php rename to tests/Tests/Persisters/DocumentPersisterGetShardKeyQueryTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Persisters/PersistenceBuilderTest.php b/tests/Tests/Persisters/PersistenceBuilderTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Persisters/PersistenceBuilderTest.php rename to tests/Tests/Persisters/PersistenceBuilderTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Proxy/Factory/ProxyFactoryTest.php b/tests/Tests/Proxy/Factory/ProxyFactoryTest.php similarity index 94% rename from tests/Doctrine/ODM/MongoDB/Tests/Proxy/Factory/ProxyFactoryTest.php rename to tests/Tests/Proxy/Factory/ProxyFactoryTest.php index 7941ff50bb..a25575f1bb 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Proxy/Factory/ProxyFactoryTest.php +++ b/tests/Tests/Proxy/Factory/ProxyFactoryTest.php @@ -89,6 +89,8 @@ public function testCreateProxyForDocumentWithUnmappedProperties(): void $proxy->__setInitialized(true); } elseif ($proxy instanceof GhostObjectInterface) { $proxy->setProxyInitializer(null); + } elseif ($this->dm->getConfiguration()->isNativeLazyObjectEnabled()) { + $this->dm->getClassMetadata($proxy::class)->getReflectionClass()->markLazyObjectAsInitialized($proxy); } self::assertSame('bar', $proxy->foo); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Query/BuilderTest.php b/tests/Tests/Query/BuilderTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Query/BuilderTest.php rename to tests/Tests/Query/BuilderTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Query/CriteriaMergerTest.php b/tests/Tests/Query/CriteriaMergerTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Query/CriteriaMergerTest.php rename to tests/Tests/Query/CriteriaMergerTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Query/ExprTest.php b/tests/Tests/Query/ExprTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Query/ExprTest.php rename to tests/Tests/Query/ExprTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Query/Filter/BsonFilterTest.php b/tests/Tests/Query/Filter/BsonFilterTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Query/Filter/BsonFilterTest.php rename to tests/Tests/Query/Filter/BsonFilterTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Query/Filter/Filter.php b/tests/Tests/Query/Filter/Filter.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Query/Filter/Filter.php rename to tests/Tests/Query/Filter/Filter.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Query/FilterCollectionTest.php b/tests/Tests/Query/FilterCollectionTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Query/FilterCollectionTest.php rename to tests/Tests/Query/FilterCollectionTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Query/QueryExpressionVisitorTest.php b/tests/Tests/Query/QueryExpressionVisitorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Query/QueryExpressionVisitorTest.php rename to tests/Tests/Query/QueryExpressionVisitorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/QueryTest.php b/tests/Tests/QueryTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/QueryTest.php rename to tests/Tests/QueryTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Repository/DefaultGridFSRepositoryTest.php b/tests/Tests/Repository/DefaultGridFSRepositoryTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Repository/DefaultGridFSRepositoryTest.php rename to tests/Tests/Repository/DefaultGridFSRepositoryTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/RepositoryFactoryTest.php b/tests/Tests/RepositoryFactoryTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/RepositoryFactoryTest.php rename to tests/Tests/RepositoryFactoryTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php b/tests/Tests/SchemaManagerTest.php similarity index 99% rename from tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php rename to tests/Tests/SchemaManagerTest.php index c14c76c049..5bf4357273 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/SchemaManagerTest.php +++ b/tests/Tests/SchemaManagerTest.php @@ -43,6 +43,7 @@ use MongoDB\Model\IndexInfoIterator; use MongoDB\Model\IndexInfoIteratorIterator; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use PHPUnit\Framework\Constraint\ArrayHasKey; use PHPUnit\Framework\Constraint\Callback; use PHPUnit\Framework\Constraint\Constraint; @@ -60,6 +61,7 @@ * @phpstan-import-type IndexMapping from ClassMetadata * @phpstan-import-type IndexOptions from ClassMetadata */ +#[IgnoreDeprecations] class SchemaManagerTest extends BaseTestCase { /** @var list */ diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/Console/Command/AbstractCommandTestCase.php b/tests/Tests/Tools/Console/Command/AbstractCommandTestCase.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/Console/Command/AbstractCommandTestCase.php rename to tests/Tests/Tools/Console/Command/AbstractCommandTestCase.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/Console/Command/Schema/UpdateCommandTest.php b/tests/Tests/Tools/Console/Command/Schema/UpdateCommandTest.php similarity index 97% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/Console/Command/Schema/UpdateCommandTest.php rename to tests/Tests/Tools/Console/Command/Schema/UpdateCommandTest.php index 1f6c1fd270..27a328d793 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Tools/Console/Command/Schema/UpdateCommandTest.php +++ b/tests/Tests/Tools/Console/Command/Schema/UpdateCommandTest.php @@ -91,7 +91,7 @@ public function testDisabledValidatorsProcessing(): void private function createDriver(): MappingDriver { - $paths = [__DIR__ . '/../../../../../../../../Documents/Ecommerce']; + $paths = [__DIR__ . '/../../../../../Documents/Ecommerce']; // Available in Doctrine Persistence 4.1+ if (class_exists(ClassNames::class)) { $paths = new ClassNames([ diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php b/tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/EncryptedFieldsMapGeneratorTest.php rename to tests/Tests/Tools/EncryptedFieldsMapGeneratorTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/GH1299/BaseUser.php b/tests/Tests/Tools/GH1299/BaseUser.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/GH1299/BaseUser.php rename to tests/Tests/Tools/GH1299/BaseUser.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/GH1299/GH1299User.php b/tests/Tests/Tools/GH1299/GH1299User.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/GH1299/GH1299User.php rename to tests/Tests/Tools/GH1299/GH1299User.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/GH297/Address.php b/tests/Tests/Tools/GH297/Address.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/GH297/Address.php rename to tests/Tests/Tools/GH297/Address.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/GH297/AddressTrait.php b/tests/Tests/Tools/GH297/AddressTrait.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/GH297/AddressTrait.php rename to tests/Tests/Tools/GH297/AddressTrait.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/GH297/Admin.php b/tests/Tests/Tools/GH297/Admin.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/GH297/Admin.php rename to tests/Tests/Tools/GH297/Admin.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/GH297/User.php b/tests/Tests/Tools/GH297/User.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/GH297/User.php rename to tests/Tests/Tools/GH297/User.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Tools/ResolveTargetDocumentListenerTest.php b/tests/Tests/Tools/ResolveTargetDocumentListenerTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Tools/ResolveTargetDocumentListenerTest.php rename to tests/Tests/Tools/ResolveTargetDocumentListenerTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Types/BinaryUuidTypeTest.php b/tests/Tests/Types/BinaryUuidTypeTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Types/BinaryUuidTypeTest.php rename to tests/Tests/Types/BinaryUuidTypeTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Types/DateImmutableTypeTest.php b/tests/Tests/Types/DateImmutableTypeTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Types/DateImmutableTypeTest.php rename to tests/Tests/Types/DateImmutableTypeTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Types/DateTypeTest.php b/tests/Tests/Types/DateTypeTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Types/DateTypeTest.php rename to tests/Tests/Types/DateTypeTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Types/IdTypeTest.php b/tests/Tests/Types/IdTypeTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Types/IdTypeTest.php rename to tests/Tests/Types/IdTypeTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Types/InvalidValueExceptionTest.php b/tests/Tests/Types/InvalidValueExceptionTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Types/InvalidValueExceptionTest.php rename to tests/Tests/Types/InvalidValueExceptionTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Types/TypeTest.php b/tests/Tests/Types/TypeTest.php similarity index 81% rename from tests/Doctrine/ODM/MongoDB/Tests/Types/TypeTest.php rename to tests/Tests/Types/TypeTest.php index 25fa434917..d1219b3a29 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Types/TypeTest.php +++ b/tests/Tests/Types/TypeTest.php @@ -7,6 +7,7 @@ use DateTime; use DateTimeImmutable; use Doctrine\ODM\MongoDB\Tests\BaseTestCase; +use Doctrine\ODM\MongoDB\Types\InvalidTypeException; use Doctrine\ODM\MongoDB\Types\Type; use MongoDB\BSON\Binary; use MongoDB\BSON\Decimal128; @@ -22,6 +23,7 @@ use function get_debug_type; use function hex2bin; use function md5; +use function sprintf; use function str_pad; use function str_repeat; use function time; @@ -129,6 +131,46 @@ public function testConvertImmutableDate(): void self::assertInstanceOf(UTCDateTime::class, Type::convertPHPToDatabaseValue($date)); } + #[DataProvider('provideTypeFromPHPVariable')] + public function testGetTypeFromPHPVariable(?Type $expectedType, mixed $variable): void + { + $type = Type::getTypeFromPHPVariable($variable); + + if ($expectedType === null) { + self::assertNull($type); + } elseif ($type === null) { + self::fail(sprintf('Type is null, expected "%s"', $expectedType::class)); + } else { + self::assertInstanceOf($expectedType::class, $type, $type::class); + } + } + + public static function provideTypeFromPHPVariable(): array + { + return [ + 'null' => [null, null], + 'bool' => [Type::getType(Type::BOOL), true], + 'int' => [Type::getType(Type::INT), 1], + 'float' => [Type::getType(Type::FLOAT), 3.14], + 'string' => [Type::getType(Type::STRING), 'ohai'], + 'DateTime' => [Type::getType(Type::DATE), new DateTime()], + 'DateTimeImmutable' => [Type::getType(Type::DATE_IMMUTABLE), new DateTimeImmutable()], + 'unknown object' => [ + null, + new class () { + }, + ], + ]; + } + + public function testInvalidType(): void + { + self::expectException(InvalidTypeException::class); + self::expectExceptionMessage('Invalid type specified: "foo"'); + + Type::getType('foo'); + } + private static function assertSameTypeAndValue(mixed $expected, mixed $actual): void { self::assertSame(get_debug_type($expected), get_debug_type($actual)); diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Types/VectorTypeTest.php b/tests/Tests/Types/VectorTypeTest.php similarity index 93% rename from tests/Doctrine/ODM/MongoDB/Tests/Types/VectorTypeTest.php rename to tests/Tests/Types/VectorTypeTest.php index 77018933d8..23ab1a7e99 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/Types/VectorTypeTest.php +++ b/tests/Tests/Types/VectorTypeTest.php @@ -12,13 +12,15 @@ use PHPUnit\Framework\Attributes\RequiresPhpExtension; use PHPUnit\Framework\TestCase; +use function get_debug_type; + #[RequiresPhpExtension('mongodb', '>= 2.2')] class VectorTypeTest extends TestCase { #[DataProvider('providePhpVectors')] public function testConvertToDatabaseValue(string $name, mixed $value, mixed $expectedValue): void { - $this->assertEquals($expectedValue, Type::getType($name)->convertToDatabaseValue($value)); + $this->assertSameTypeAndValue($expectedValue, Type::getType($name)->convertToDatabaseValue($value)); } #[DataProvider('providePhpVectors')] @@ -27,7 +29,7 @@ public function testClosureToDatabase(string $name, mixed $value, mixed $expecte $return = $this; eval(Type::getType($name)->closureToMongo()); - $this->assertEquals($expectedValue, $return); + $this->assertSameTypeAndValue($expectedValue, $return); } /** @return iterable */ @@ -149,4 +151,10 @@ public static function providePHPValueException(): iterable yield [new Binary("\x03\x00\x01\x02\x03", Binary::TYPE_GENERIC), 'Invalid binary data of type 0 received for vector field']; yield [Binary::fromVector([1, 2, 3], VectorType::Int8), 'Invalid binary vector data of vector type Int8 received for vector field, expected vector type Float32']; } + + private function assertSameTypeAndValue(mixed $expected, mixed $actual): void + { + $this->assertSame(get_debug_type($expected), get_debug_type($actual)); + $this->assertEquals($expected, $actual); + } } diff --git a/tests/Doctrine/ODM/MongoDB/Tests/Types/VersionableTest.php b/tests/Tests/Types/VersionableTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/Types/VersionableTest.php rename to tests/Tests/Types/VersionableTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/UnitOfWorkCommitConsistencyTest.php b/tests/Tests/UnitOfWorkCommitConsistencyTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/UnitOfWorkCommitConsistencyTest.php rename to tests/Tests/UnitOfWorkCommitConsistencyTest.php diff --git a/tests/Doctrine/ODM/MongoDB/Tests/UnitOfWorkTest.php b/tests/Tests/UnitOfWorkTest.php similarity index 94% rename from tests/Doctrine/ODM/MongoDB/Tests/UnitOfWorkTest.php rename to tests/Tests/UnitOfWorkTest.php index 55d61fedba..ceb8e8f1a3 100644 --- a/tests/Doctrine/ODM/MongoDB/Tests/UnitOfWorkTest.php +++ b/tests/Tests/UnitOfWorkTest.php @@ -20,6 +20,7 @@ use Documents\File; use Documents\FileWithoutMetadata; use Documents\ForumAvatar; +use Documents\ForumStar; use Documents\ForumUser; use Documents\Functional\NotSaved; use Documents\User; @@ -28,6 +29,7 @@ use MongoDB\Driver\WriteConcern; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\DoesNotPerformAssertions; +use PHPUnit\Framework\Attributes\IgnoreDeprecations; use ReflectionProperty; use Throwable; @@ -37,6 +39,20 @@ class UnitOfWorkTest extends BaseTestCase { + /** Clear by class name is deprecated */ + #[IgnoreDeprecations] + public function testPartialClear(): void + { + $user = new ForumUser(); + $avatar = new ForumAvatar(); + $this->uow->persist($avatar); + $this->uow->persist($user); + + $this->uow->clear(ForumUser::class); + self::assertFalse($this->uow->isScheduledForInsert($user)); + self::assertTrue($this->uow->isScheduledForInsert($avatar)); + } + public function testIsDocumentScheduled(): void { $class = $this->dm->getClassMetadata(ForumUser::class); @@ -497,6 +513,34 @@ public function testRecomputeChangesetForUninitializedProxyDoesNotCreateChangese self::assertEquals([], $this->uow->getDocumentChangeSet($user->getAvatar())); } + /** + * Native lazy ghosts objects are marked as initialized when the last property + * is set. It appends when the document class has only one property: the id. + */ + public function testRecomputeChangesetForNativeLazyGhostWithOnlyIdDoesNotCreateChangeset(): void + { + $user = new ForumUser(); + $user->username = '12345'; + $user->setStar(new ForumStar()); + + $this->dm->persist($user); + $this->dm->flush(); + + $id = $user->getId(); + $this->dm->clear(); + + $user = $this->dm->find(ForumUser::class, $id); + self::assertInstanceOf(ForumUser::class, $user); + + self::assertTrue(self::isLazyObject($user->getStar())); + + $classMetadata = $this->dm->getClassMetadata(ForumStar::class); + + $this->uow->recomputeSingleDocumentChangeSet($classMetadata, $user->getStar()); + + self::assertEquals([], $this->uow->getDocumentChangeSet($user->getStar())); + } + public function testCommitsInProgressIsUpdatedOnException(): void { $this->dm->getEventManager()->addEventSubscriber( diff --git a/tests/Doctrine/ODM/MongoDB/Tests/UnitOfWorkTransactionalCommitConsistencyTest.php b/tests/Tests/UnitOfWorkTransactionalCommitConsistencyTest.php similarity index 100% rename from tests/Doctrine/ODM/MongoDB/Tests/UnitOfWorkTransactionalCommitConsistencyTest.php rename to tests/Tests/UnitOfWorkTransactionalCommitConsistencyTest.php