Compare commits

...

875 Commits
3.1.2 ... 3.6.x

Author SHA1 Message Date
Alexander M. Turek
27c33cf88d Merge branch '2.20.x' into 3.6.x
* 2.20.x:
  Make the data provider static
  Raise proper exception for invalid arguments in Base::add() (#12394)
2026-03-12 09:31:56 +01:00
Alexander M. Turek
6068b61a0d Make the data provider static 2026-03-12 09:24:03 +01:00
Alexander M. Turek
00024f7d88 Raise proper exception for invalid arguments in Base::add() (#12394) 2026-03-12 09:05:27 +01:00
Alexander M. Turek
331f8b52cb Merge branch '2.20.x' into 3.6.x
* 2.20.x:
  Fix code style (#12395)
  Bump actions/upload-artifact from 6 to 7 (#12387)
  Bump actions/download-artifact from 7 to 8 (#12386)
2026-03-11 16:55:13 +01:00
Alexander M. Turek
b2faba62b7 Fix code style (#12395) 2026-03-11 16:51:15 +01:00
dependabot[bot]
da426a0036 Bump actions/upload-artifact from 6 to 7 (#12387)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-05 00:34:23 +01:00
dependabot[bot]
1891a76f13 Bump actions/download-artifact from 7 to 8 (#12386)
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v7...v8)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '8'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-05 00:33:50 +01:00
vvaswani
4262eb495b fix: update index to be serialized in __sleep() (#12366)
Signed-off-by: Vikram Vaswani <2571660+vvaswani@users.noreply.github.com`>
2026-01-30 22:41:41 +01:00
Grégoire Paris
d3b47d2cbb Merge pull request #12355 from doctrine/2.20.x
Merge 2.20.x up into 3.6.x
2026-01-25 12:48:28 +01:00
Grégoire Paris
026f5bfe1b Merge pull request #12350 from greg0ire/missing-order-by
Add missing ORDER BY clause
2026-01-18 10:41:46 +01:00
Grégoire Paris
0b0f2f4d86 Add missing ORDER BY clause
This causes transient failures with PostgreSQL. Order is not guaranteed.
2026-01-17 13:39:44 +01:00
Grégoire Paris
0bd839a720 Merge pull request #12345 from greg0ire/3.6.x
Merge 2.20.x up into 3.6.x
2026-01-16 18:27:03 +01:00
Grégoire Paris
b65004fc26 Merge remote-tracking branch 'origin/2.20.x' into 3.6.x 2026-01-16 18:24:38 +01:00
Grégoire Paris
d2418ab074 Merge pull request #12344 from greg0ire/update-baseline
Update PHPStan baseline
2026-01-15 23:38:15 +01:00
Grégoire Paris
39a05e31c9 Update PHPStan baseline
This is caused by the release of doctrine/collections 2.7.0. The error
message is a bit shorter now.
2026-01-15 20:13:05 +01:00
sasezaki
ab156a551c Update phpstan-dbal2 to phpstan-dbal3 in .gitattributes (#12343) 2026-01-12 12:53:04 +01:00
Grégoire Paris
2148940290 Merge pull request #12335 from greg0ire/gh-12166
Avoid lazy object initialization when initializing read-only property
2026-01-09 06:28:15 +01:00
Grégoire Paris
d3538095fd Merge pull request #12337 from greg0ire/3.6.x
Merge 2.20.x up into 3.6.x
2026-01-09 06:26:06 +01:00
Grégoire Paris
0c1bf14729 Merge remote-tracking branch 'origin/2.20.x' into 3.6.x 2026-01-08 08:55:21 +01:00
Grégoire Paris
3b8c23c51d Merge pull request #12336 from greg0ire/dmwydo
Stop mocking EventManager
2026-01-08 07:19:16 +01:00
Grégoire Paris
60d4ea694a Stop mocking EventManager
It is defined outside this repository, so let us not mock what we do not
own.
2026-01-07 21:52:47 +01:00
Grégoire Paris
e923bbc932 Avoid lazy object initialization when initializing read-only property
Initializing e.g. a readonly ID does not require loading any data from
the database. However, calling isInitialized() on the reflection of a
readonly property triggers the native lazy object initialization.
If we have a lazy property at hand, then the property cannot be initialized
already, so it is safe to skip the call.
2026-01-07 13:04:14 +01:00
n0099
8cbd34c666 Merge pull request #12060 from n0099/patch-1
Update doc `dql-custom-walkers.rst` with an output walker to interpolate parameters into SQL
2026-01-01 18:27:48 +01:00
Vladislav Sultanov
8bdefef6d1 Handle int-backed enums for values stored as string values in MySQL ENUM columns (#12275)
* FIX: Handle int-backed enums for values stored as string values in MySQL ENUM columns

Related issue: doctrine#12274

* FIX: Apply coding standard changes

Related issue: doctrine#12274

* FIX: Add unit test cases

Related issue: doctrine#12274
2025-12-30 18:21:10 +01:00
Grégoire Paris
0f8730a6e5 Merge pull request #12331 from greg0ire/a-the
Fix grammatical errors
2025-12-24 11:39:26 +01:00
Grégoire Paris
62477b5d42 Update branch metadata (#12327)
* Update branch metadata

3.6.0 has been released. As a consequence:

- 3.7.x is the next minor branch;
- 3.6.x is the current branch;
- 3.5.x is no longer maintained.

* doc: drop old releases

We should reduce the number of versions we have, so let's remove docs
for versions that have less than 2k downloads per day.
2025-12-21 00:29:57 +01:00
HypeMC
12116aa3c2 Fix docs regarding query hints (#12328) 2025-12-21 00:29:08 +01:00
Grégoire Paris
0aeddd0592 Fix grammatical errors 2025-12-20 15:34:16 +01:00
Grégoire Paris
2491c4b20d Merge pull request #12329 from HypeMC/fix-result-cache-examples
Fix result cache examples in docs
2025-12-20 09:14:39 +01:00
HypeMC
08d6167243 Fix result cache examples in docs 2025-12-20 01:21:11 +01:00
Grégoire Paris
d4e9276e79 Merge pull request #12325 from doctrine/3.5.x
Merge 3.5.x up into 3.6.x
2025-12-19 21:36:14 +01:00
Grégoire Paris
cee74faa97 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-12-19 20:59:05 +01:00
Grégoire Paris
9ae2181185 Merge pull request #12165 from HypeMC/debug-events-commands
Add commands for inspecting configured listeners
2025-12-19 08:31:44 +01:00
HypeMC
3e25efd72b One table 2025-12-17 23:17:36 +01:00
HypeMC
47496ed882 Fixes 2025-12-17 18:52:17 +01:00
Sadetdin EYILI
492745d710 docs: add xml example for Single Table Inheritance mapping (#12169) 2025-12-17 10:40:06 +01:00
dependabot[bot]
67419cf951 Bump actions/download-artifact from 6 to 7 (#12321) 2025-12-15 07:56:29 +01:00
dependabot[bot]
1237f5c909 Bump actions/upload-artifact from 5 to 6 (#12322) 2025-12-15 07:55:38 +01:00
Grégoire Paris
609e616f2d Merge pull request #12279 from greg0ire/deprecate-conversion
Deprecate string default expressions
2025-12-10 15:05:54 +01:00
Grégoire Paris
4016d6ba4b Deprecate string default expressions
Right now, the ORM handles the conversion of strings that happen to be
default expressions for date, time and datetime columns into the
corresponding value objects.

Let us allow users to specify these value objects directly, and
deprecate relying on the aforementioned conversion.
2025-12-10 12:08:30 +01:00
dependabot[bot]
dcdd46251e Bump doctrine/.github/.github/workflows/release-on-milestone-closed.yml (#12315)
Bumps [doctrine/.github/.github/workflows/release-on-milestone-closed.yml](https://github.com/doctrine/.github) from 13.0.0 to 13.1.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/13.0.0...13.1.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/release-on-milestone-closed.yml
  dependency-version: 13.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 10:23:27 +01:00
dependabot[bot]
3d98b43561 Bump doctrine/.github/.github/workflows/composer-lint.yml (#12317)
Bumps [doctrine/.github/.github/workflows/composer-lint.yml](https://github.com/doctrine/.github) from 13.0.0 to 13.1.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/13.0.0...13.1.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/composer-lint.yml
  dependency-version: 13.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 10:22:42 +01:00
dependabot[bot]
9f3f70944a Bump doctrine/.github/.github/workflows/coding-standards.yml (#12316)
Bumps [doctrine/.github/.github/workflows/coding-standards.yml](https://github.com/doctrine/.github) from 13.0.0 to 13.1.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/13.0.0...13.1.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/coding-standards.yml
  dependency-version: 13.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 10:22:15 +01:00
dependabot[bot]
05e07c0ae0 Bump doctrine/.github/.github/workflows/documentation.yml (#12318)
Bumps [doctrine/.github/.github/workflows/documentation.yml](https://github.com/doctrine/.github) from 13.0.0 to 13.1.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/13.0.0...13.1.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/documentation.yml
  dependency-version: 13.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 10:21:12 +01:00
Grégoire Paris
fea42ab984 Merge pull request #12299 from alexislefebvre/chore-show-parameters-in-name-of-CI-jobs
chore: show parameters in name of CI jobs
2025-11-30 11:14:14 +01:00
Alexis Lefebvre
7c347b85c1 doc: do not mention InverseJoinColumn since it’s only with PHP 8.0 (#12313) 2025-11-30 00:49:09 +01:00
Alexander M. Turek
458b040d93 Remove obsolete PHPStan ignore rules 2025-11-30 00:34:10 +01:00
Alexander M. Turek
396636a2c2 Merge branch '3.5.x' into 3.6.x
* 3.5.x:
  Remove obsolete VarExporter feature detection (#12309)
  Allow Symfony 8 (#12308)
  Explicitly set a cache in testDisablingXmlValidationIsPossible (#12307)
  Removes Guides from our dependencies (#12303)
  Fix PHPStan and test errors after DBAL 4.4 and Symfony 7.4 releases (#12301)
  Support Symfony Console 8 (#12300)
  Bump doctrine/.github/.github/workflows/composer-lint.yml (#12288)
  Bump doctrine/.github/.github/workflows/documentation.yml (#12289)
  Bump doctrine/.github/.github/workflows/coding-standards.yml (#12290)
  Bump doctrine/.github/.github/workflows/release-on-milestone-closed.yml (#12291)
  Bump actions/checkout from 5 to 6 (#12292)
2025-11-30 00:29:59 +01:00
Alexander M. Turek
78dd074266 Remove obsolete VarExporter feature detection (#12309) 2025-11-30 00:11:02 +01:00
Alexander M. Turek
ff22a00fcf Allow Symfony 8 (#12308) 2025-11-30 00:10:09 +01:00
Alexander M. Turek
02e8ff9663 Explicitly set a cache in testDisablingXmlValidationIsPossible (#12307) 2025-11-29 23:16:54 +01:00
Alexis Lefebvre
01fd55e9ea chore: show parameters in name of CI jobs 2025-11-29 23:12:27 +01:00
Alexander M. Turek
2e75a7f1c1 Merge branch '2.20.x' into 3.5.x
* 2.20.x:
  Support Symfony Console 8 (#12300)
  Bump doctrine/.github/.github/workflows/composer-lint.yml (#12288)
  Bump doctrine/.github/.github/workflows/documentation.yml (#12289)
  Bump doctrine/.github/.github/workflows/coding-standards.yml (#12290)
  Bump doctrine/.github/.github/workflows/release-on-milestone-closed.yml (#12291)
  Bump actions/checkout from 5 to 6 (#12292)
2025-11-29 22:07:13 +01:00
Alexander M. Turek
152b0e3d65 Removes Guides from our dependencies (#12303) 2025-11-29 21:55:58 +01:00
Alexander M. Turek
9d11fdd3da Fix PHPStan and test errors after DBAL 4.4 and Symfony 7.4 releases (#12301)
* Fix PHPStan errors after DBAL 4.4 and Symfony 7.4 releases

* Fix PHPStan and test errors after DBAL 4.4 and Symfony 7.4 releases
2025-11-29 18:04:54 +01:00
Alexander M. Turek
87f1ba74e0 Support Symfony Console 8 (#12300) 2025-11-29 15:03:56 +01:00
Grégoire Paris
f357a33d23 Merge pull request #12293 from doctrine/3.5.x
Merge 3.5.x. up into 3.6.x
2025-11-24 20:25:07 +01:00
Grégoire Paris
ee70178314 Merge pull request #12287 from greg0ire/more-order-by
Add ORDER BY clause to more test cases
2025-11-24 09:40:48 +01:00
dependabot[bot]
ab148d3d9d Bump doctrine/.github/.github/workflows/composer-lint.yml (#12288)
Bumps [doctrine/.github/.github/workflows/composer-lint.yml](https://github.com/doctrine/.github) from 12.2.0 to 13.0.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/v12.2.0...13.0.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/composer-lint.yml
  dependency-version: 13.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 09:25:08 +01:00
dependabot[bot]
3924c38fab Bump doctrine/.github/.github/workflows/documentation.yml (#12289)
Bumps [doctrine/.github/.github/workflows/documentation.yml](https://github.com/doctrine/.github) from 12.2.0 to 13.0.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/v12.2.0...13.0.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/documentation.yml
  dependency-version: 13.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 09:24:42 +01:00
dependabot[bot]
9814078a2c Bump doctrine/.github/.github/workflows/coding-standards.yml (#12290)
Bumps [doctrine/.github/.github/workflows/coding-standards.yml](https://github.com/doctrine/.github) from 12.2.0 to 13.0.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/v12.2.0...13.0.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/coding-standards.yml
  dependency-version: 13.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 09:24:14 +01:00
dependabot[bot]
6de5684fd9 Bump doctrine/.github/.github/workflows/release-on-milestone-closed.yml (#12291)
Bumps [doctrine/.github/.github/workflows/release-on-milestone-closed.yml](https://github.com/doctrine/.github) from 12.2.0 to 13.0.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/v12.2.0...13.0.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/release-on-milestone-closed.yml
  dependency-version: 13.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 09:23:46 +01:00
dependabot[bot]
c142503a52 Bump actions/checkout from 5 to 6 (#12292) 2025-11-24 07:27:27 +01:00
Grégoire Paris
01c178b297 Add ORDER BY clause to more test cases
In https://github.com/doctrine/orm/pull/12222, I thought wrongly thought
the issue I was fixing only affected one test.
2025-11-23 19:18:20 +01:00
Grégoire Paris
ffa50a777f Merge pull request #12286 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-11-21 20:24:51 +01:00
Grégoire Paris
649048f745 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-11-21 19:46:45 +01:00
Grégoire Paris
15537bc218 Merge pull request #12285 from HypeMC/fix-is-foreign-key-composite
Fix check for composite foreign key
2025-11-21 19:29:05 +01:00
HypeMC
bc95c7c08d Fix check for composite foreign key 2025-11-21 07:27:53 +01:00
Grégoire Paris
6982c8ab9d Merge pull request #12284 from doctrine/3.5.x
Merge 3.5.x up into 3.6.x
2025-11-20 22:49:20 +01:00
Grégoire Paris
3df11d518c Merge pull request #12283 from doctrine/2.20.x
Merge 2.20.x up into 3.5.x
2025-11-20 21:31:19 +01:00
Grégoire Paris
c1becd54e6 Merge pull request #12281 from greg0ire/document-default-expressions
Fix documentation about default values
2025-11-20 17:58:48 +01:00
Grégoire Paris
e4d7df29c2 Fix documentation about default values
Saying it is not possible to get Doctrine to use the `DEFAULT` SQL
keyword is wrong.
2025-11-19 23:17:53 +01:00
Grégoire Paris
608705427e Merge pull request #12277 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-11-19 07:13:23 +01:00
Grégoire Paris
f0562f4120 Merge pull request #12273 from greg0ire/deprecate-default
Deprecate FieldMapping::$default
2025-11-19 06:50:43 +01:00
Grégoire Paris
9f19310f27 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-11-19 00:01:30 +01:00
Adrian Brajkovic
e38278bfca Fix eager fetch composite foreign key (#11397)
I think #11289 did not completely fix problem for eager fetch.
Change in that PR checked if primary key of target class is composite but that does not matter when loading collection by foreign key.
It should check if foreign key on target class is composite.

Fix from that PR did not work for me because i had entity with regular autogenerated id (single column), but foreign key referenced entity with composite primary key, like SecondLevelWithoutCompositePrimaryKey in this PR.

Checking if foreign key is composite fixed the problem for me.
2025-11-18 21:40:50 +01:00
Grégoire Paris
62f2cff218 Merge pull request #12268 from pmaasz/querybuilder-hints
Add hints to QueryBuilder
2025-11-15 09:32:24 +01:00
pmaasz
cdd774906b add member variable hints to the querybuilder for hints to be added to the query
This adds the membervariable hints to the QueryBuilder to enable setting hints
that will be applied to the query when it is created. This can help trigger
custom walker classes when the query is not adressable driectly e.g. in
Symfony Form Extensions where the quer_builder normalizer is handed the querybuilder
directly. Also see #11849
The feature mirrors the hint feature from the Query class.
This also adds tests for the hints in the QueryBuilder to ensure that those are added
correctly and applied to the query itself on creation
2025-11-14 09:11:48 +01:00
Grégoire Paris
96776e091d Deprecate FieldMapping::$default
Its purpose is unclear since there is FieldMapping::$options['default']
already.
2025-11-14 08:46:08 +01:00
Grégoire Paris
f7470d8a3f Merge pull request #12271 from greg0ire/3.6.x
Merge 3.5.x up into 3.6.x
2025-11-11 19:31:00 +01:00
Grégoire Paris
2c41cc7f1c Merge remote-tracking branch 'origin/3.5.x' into 3.6.x 2025-11-11 19:28:47 +01:00
Grégoire Paris
f18de9d569 Merge pull request #12269 from greg0ire/3.5.x
Undo merge from 3.6.x into 3.5.x
2025-11-11 19:27:40 +01:00
Grégoire Paris
37f76a8381 Undo merge from 3.6.x into 3.5.x 2025-11-11 19:11:32 +01:00
Grégoire Paris
a6c1e63a60 Merge pull request #12266 from doctrine/3.5.x-merge-up-into-3.6.x_hSSiOXm0
Merge release 3.5.6 into 3.6.x
2025-11-10 22:27:19 +01:00
Grégoire Paris
b62292256a Merge pull request #12265 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-11-10 22:11:37 +01:00
Grégoire Paris
b138395194 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-11-10 21:32:47 +01:00
Grégoire Paris
6881cdff4c Merge pull request #12264 from doctrine/3.5.x-merge-up-into-3.6.x_9GolPzTd
Merge release 3.5.5 into 3.6.x
2025-11-10 21:27:36 +01:00
Grégoire Paris
dede2d775a Merge pull request #12262 from greg0ire/address-dbal-depr
Address default expression deprecation
2025-11-10 19:49:31 +01:00
Grégoire Paris
c502190712 Address default expression deprecation
This addresses the deprecation introduced in
https://github.com/doctrine/dbal/pull/7195

A follow-up should be to deprecate not using these value objects in
field mappings, so that we do not just reproduce the same checks that
the DBAL wants to remove.
2025-11-10 19:13:28 +01:00
Grégoire Paris
5bff0919a7 Merge pull request #12254 from elliotbruneel/fix/empty-array-query
fix: handling of empty array in SQL condition generation
2025-11-10 14:35:45 +01:00
Elliot Bruneel
9ef0f5301b fix: update SQL condition for empty array to 1=0 instead of IN (NULL) 2025-11-10 10:44:48 +01:00
Elliot Bruneel
4989ca6f15 test: add test for finding by nullable field with empty array 2025-11-05 10:03:09 +01:00
Elliot Bruneel
32d1e97ce7 chore: improve empty array check in SQL condition generation 2025-11-05 09:51:33 +01:00
Grégoire Paris
ca8147b148 Merge pull request #12257 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-12.2.0
Bump doctrine/.github from 12.1.0 to 12.2.0
2025-11-03 09:32:58 +01:00
dependabot[bot]
c8ebea77f0 Bump doctrine/.github from 12.1.0 to 12.2.0
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 12.1.0 to 12.2.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/12.1.0...v12.2.0)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-version: 12.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-03 06:11:36 +00:00
Elliot Bruneel
23f22860f1 chore: update phpstan version and regenerate baseline 2025-10-31 09:04:03 +01:00
Elliot Bruneel
b24586b1b5 fix: handling of empty array in SQL condition generation 2025-10-30 17:31:04 +01:00
Grégoire Paris
9e5442a892 Merge pull request #12251 from doctrine/3.5.x
Merge 3.5.x up into 3.6.x
2025-10-29 20:41:29 +01:00
Grégoire Paris
7d8e51c934 Merge pull request #12250 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-10-29 08:33:35 +01:00
Grégoire Paris
2f8f1cfcb8 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-10-29 07:31:41 +01:00
Grégoire Paris
fe5ee705db Merge pull request #12247 from greg0ire/composer-lint
Setup composer lint workflow
2025-10-29 07:28:39 +01:00
Grégoire Paris
01774c035c Merge pull request #12065 from whataboutpereira/fix-enum-discriminator-column
Use enum values from enumType in DiscriminatorColumn and check DiscriminatorMap values against it
2025-10-29 07:28:16 +01:00
Grégoire Paris
0511a9f790 Merge pull request #12248 from greg0ire/remove-mailing-list
Drop link to mailing list
2025-10-28 22:06:18 +01:00
Grégoire Paris
0e3d5e8c82 Drop link to mailing list
Who still uses this? Not me, that's for sure!
2025-10-28 21:20:15 +01:00
Grégoire Paris
72ffb3bfbf Remove archive exclude list
It is not up-to-date, and we use .gitattributes for this purpose.
2025-10-28 21:04:43 +01:00
Grégoire Paris
2e9a1adc23 Setup composer lint workflow 2025-10-28 21:03:24 +01:00
Reio Remma
6f83166266 Extract enum cases from enumType in DiscriminatorColumn
Check DiscriminatorMap keys match enum cases.
Test values are populated from enum cases and mismatched values throw an exception.
Fixes #11794
2025-10-28 20:36:11 +02:00
Grégoire Paris
ffd3f50ad7 Merge pull request #12244 from greg0ire/3.6.x
Merge 3.5.x up into 3.6.x
2025-10-27 23:46:31 +01:00
Grégoire Paris
483b45d449 Merge remote-tracking branch 'origin/3.5.x' into 3.6.x 2025-10-27 23:20:06 +01:00
Grégoire Paris
1220edf953 Merge pull request #12241 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-10-27 23:06:52 +01:00
Grégoire Paris
7e4693d629 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-10-27 22:34:13 +01:00
Grégoire Paris
59938cae57 Merge pull request #12238 from mpdude/fix-collections-deprecation
Avoid triggering a deprecation notice in doctrine/collections
2025-10-27 22:19:59 +01:00
Grégoire Paris
298dc9bb6a Merge pull request #12183 from mpdude/paginator-confused-result-set-mapping-initialized
Paginator with output walker returns count 0 when the query has previously been executed
2025-10-27 21:54:38 +01:00
Matthias Pigulla
da67f323e0 Add PHPStan errors to persistence2 baseline file 2025-10-27 19:51:11 +01:00
Matthias Pigulla
63635cad0e Remove PHPStan error suppressions 2025-10-27 12:28:48 +01:00
Grégoire Paris
a0d401b688 Merge pull request #12239 from doctrine/dependabot/github_actions/2.20.x/actions/download-artifact-6
Bump actions/download-artifact from 5 to 6
2025-10-27 08:38:07 +01:00
Grégoire Paris
6acbadfbbe Merge pull request #12240 from doctrine/dependabot/github_actions/2.20.x/actions/upload-artifact-5
Bump actions/upload-artifact from 4 to 5
2025-10-27 08:37:52 +01:00
dependabot[bot]
c64dcb4d38 Bump actions/upload-artifact from 4 to 5
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 06:41:11 +00:00
dependabot[bot]
3304290b21 Bump actions/download-artifact from 5 to 6
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-27 06:22:30 +00:00
Matthias Pigulla
1865717721 Avoid triggering a deprecation notice in doctrine/collections
This updates the code to avoid triggering the deprecation introduced in https://github.com/doctrine/collections/pull/472.
2025-10-26 23:20:27 +01:00
Matthias Pigulla
828b06e20f Update the DQL walker cookbook example 2025-10-26 22:13:51 +01:00
Matthias Pigulla
c2b844d2e3 Update src/Tools/Pagination/Paginator.php
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2025-10-26 22:08:56 +01:00
Christophe Coevoet
dd4e8fe78f Merge pull request #12198 from stof/arbitrary_join_on
Update DQL arbitrary joins to use the ON keyword instead of WITH
2025-10-25 10:59:22 +02:00
Grégoire Paris
4f36f0129a Merge pull request #12236 from eltharin/bugfix_fieldalias_entityInDto
bugfix - add fieldAlias for entities in dto
2025-10-23 08:51:42 +02:00
dependabot[bot]
b45d5329f8 Bump doctrine/.github from 10.1.0 to 12.0.0 (#12227) 2025-10-23 08:10:27 +02:00
Grégoire Paris
c1047b30e3 Merge pull request #12216 from paulinevos/docs-builder
Use docs builder in ORM repo
2025-10-23 07:48:31 +02:00
eltharin
f71aa73ef1 bugfix - add fieldAlias for entities in dto 2025-10-22 21:14:42 +02:00
Grégoire Paris
aa62efa30a Adapt to latest coding standard 2025-10-22 21:12:17 +02:00
Pauline Vos
f71956f001 Use docs-builder to generate ORM docs
Introduces the `composer docs` command to generate the docs locally, and
uses the same tool (`docs-builder`) in the documentation GH workflow.
2025-10-22 21:09:03 +02:00
Alexander M. Turek
7cc210424c SQLFilter: replace internal array shape with class (#12232) 2025-10-22 09:20:35 +02:00
Grégoire Paris
4fd9e94819 Merge pull request #12234 from mpdude/merge-3.5.x-into-3.6.x
Merge 3.5.x up into 3.6.x
2025-10-22 08:31:52 +02:00
Christophe Coevoet
587caf88a7 Update DQL arbitrary joins to use the ON keyword instead of WITH
DQL arbitrary joins are semantically equivalent to SQL joins, so using
the same keyword reduces confusion. It also means that in next major
version, the WITH keyword will only be about applying adhoc filtering on
relations instead of having 2 responsibilities.
2025-10-21 17:42:48 +02:00
Matthias Pigulla
1e33b775d3 Merge remote-tracking branch 'upstream/3.5.x' into HEAD 2025-10-21 17:30:48 +02:00
Ali Sol
96f9b29573 Merge pull request #12233 from alisolphp/fix-docs-typos-2-20
Docs: fix typos and grammar across reference docs
2025-10-21 17:09:12 +02:00
Grégoire Paris
c6207b1793 Merge pull request #12202 from greg0ire/missing-suffix
Add missing "Test" suffix
2025-10-20 08:01:47 +02:00
Grégoire Paris
8c92903430 Specify the length of VARCHAR columns
Platforms in the MySQL/MariaDB family require that.
2025-10-18 14:26:12 +02:00
Grégoire Paris
8616a98023 Add missing "Test" suffix
That test never got executed.
2025-10-18 14:16:07 +02:00
Grégoire Paris
9a55cf4f30 Merge pull request #12190 from mpdude/criteria-matching-custom-type-retry
Fix collection filtering API for `IN`/`NOT IN` comparisons that require type conversions
2025-10-16 07:56:07 +02:00
Matthias Pigulla
9d680a6de4 Do not eagerly set metadata from ResolveTargetEntityListener (#12174)
* Do not eagerly set metadata from ResolveTargetEntityListener

When using the `ResolveTargetEntityListener` to substitute `targetEntities` in association mappings, do not eagerly put the resolved (target) entity into the class metadata cache under the class name of the original entity.

#### Motivation

I have a library that wants to distribute a MappedSuperclass as the base for some functionality. It will be necessary that clients using the library will extend the MappedSuperclass to fill in some blanks, creating the first real `#[Entity]` instance of it.

This client-provided entity will be the primary means of working with the class. Thus, I was following the [note in the documentation](https://www.doctrine-project.org/projects/doctrine-orm/en/3.5/reference/inheritance-mapping.html#mapped-superclasses:~:text=It%20is%2C%20however) and using the `ResolveTargetEntityListener` to declare that whenever an association refers to that mapped superclass, the particular entity class shall be used instead.

>  One-To-Many associations are not generally possible on a mapped superclass, since they require the "many" side to hold the foreign key.
> It is, however, possible to use the [ResolveTargetEntityListener](https://www.doctrine-project.org/projects/doctrine-orm/en/3.5/cookbook/resolve-target-entity-listener.html) to replace references to a mapped superclass with an entity class at runtime. As long as there is only one entity subclass inheriting from the mapped superclass and all references to the mapped superclass are resolved to that entity class at runtime, the mapped superclass can use One-To-Many associations and be named as the targetEntity on the owning sides.

#### Changes made

The `ResolveTargetEntityListener` primarily does what its name suggests: For newly loaded class metadata, it inspects all associations declared and replaces the `targetEntity` with new (resolved) values.

But additionally, when a loaded class is the target of such a resolution, it would also put the class metadata into the cache under the name of the original entity.

I think that extra step is wrong, and this PR removes it. It had the side effect that when other classes extending the MappedSuperclass were loaded _after_ the resolve target class has been seen for the first time, the metadata for those classes would not inherit from the mapped superclass anymore, but from the target entity class instead. In my real-life use case, this causes weird mapping errors down the road; as of ^3.0, it would throw a mapping exception asking to configure inheritance mapping. But note that there would be no inheritance between the two entity classes at all.

#### More background

The documentation [describes the use of `ResolveTargetEntityListener`](https://www.doctrine-project.org/projects/doctrine-orm/en/3.5/cookbook/resolve-target-entity-listener.html) with an interface that is resolved to an entity class. For an interface, adding the extra metadata does not make a difference, since it never interferes with actual entity or mapped superclasses.

The initial idea of adding a copy of the entity class metadata under the interface name came from commit
9c7f3f2747 in #385. The goal was to make it possible to also find entities by interface names, like so:

```
$em->find('Foo\BarBundle\Entity\PersonInterface', 1);
```

It then [turned out that this only worked when the resolution had already been applied](https://github.com/doctrine/orm/pull/385#issuecomment-6658893). So, the new `onClassMetadataNotFound` event was added and the resolution map would be checked in that case as well (#1181). The inital code stayed in place, possibly giving a small performance gain.

In my real-world use case and the test case I added in this PR, the associations are even self-referencing. That should not really be necessary for the problem to surface. I decided to keep it this way to show that the `targetEntity` need not be an interface after all, and that a MappedSuperclass can be used in the same way.
2025-10-15 16:10:51 +02:00
Grégoire Paris
7602a5341c Merge pull request #12224 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-10-13 23:12:23 +02:00
Matthias Pigulla
7a59281157 Fix collection filtering API for IN/NOT IN comparisons that require type conversions
This PR fixes the `Criteria` matching API for `IN` and `NIN` conditions with values that are arrays, by making sure that type information for the matched field is passed to the DBAL level correctly.

Passing the right parameter type to DBAL is important to make sure parameter conversions are applied before matching at the database level.

Memory-based collections (`ArrayCollection`s or initialized collection fields) would perform matching on the objects in memory where no type conversion to the database representation is required, giving correct results.

But uninitialized collections that have their conditions evaluated at the database level need to convert parameter values to the database representation before performing the comparison.

One extra challenge is that the DBAL type system does currently not support array-valued parameters for custom types. Only a [limited list of types](https://www.doctrine-project.org/projects/doctrine-dbal/en/4.2/reference/data-retrieval-and-manipulation.html#list-of-parameters-conversion) is supported.

I discussed this with @morozov at the Doctrine Hackathon and came to the conclusion that it would be best to work around this limitation at the ORM level. Thus, this fix recognizes array-valued parameters and creates multiple placeholders (like `?, ?, ?`) for them, flattening out the arrays in the parameter list and repeating the type information for each one of them.

Previous stalled attempt to fix this was in #11897.
2025-10-13 23:11:56 +02:00
Grégoire Paris
214b1ad739 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-10-13 22:53:09 +02:00
Grégoire Paris
5def068fe9 Merge pull request #12223 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-10.1.0
Bump doctrine/.github from 8.0.0 to 10.1.0
2025-10-13 08:49:34 +02:00
dependabot[bot]
693acbf812 Bump doctrine/.github from 8.0.0 to 10.1.0
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 8.0.0 to 10.1.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/8.0.0...10.1.0)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-version: 10.1.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-13 06:11:35 +00:00
Grégoire Paris
28d9472a38 Merge pull request #12196 from mpdude/deprecation-notice-parser-result
Add deprecation messages for methods that were only annotated as being `@deprecated`
2025-10-12 08:32:18 +02:00
Grégoire Paris
cf11f1e453 Add ORDER BY clause to SELECT query (#12222)
The order of results is not guaranteed unless we do so, and the test can
fail in some cases:

	There was 1 failure:

	1) Doctrine\Tests\ORM\Functional\QueryTest::testToIterableWithMixedResultArbitraryJoinsScalars
	Failed asserting that two strings are equal.
	--- Expected
	+++ Actual
	@@ @@
	-'Doctrine 2'
	+'lala 2'

	/home/runner/work/orm/orm/tests/Tests/ORM/Functional/QueryTest.php:481
2025-10-12 02:02:42 +02:00
Grégoire Paris
c6955ec056 Merge pull request #12221 from greg0ire/3.6.x
Merge 3.5.x up into 3.6.x
2025-10-12 01:54:15 +02:00
Grégoire Paris
c1ce2bb687 Merge pull request #12220 from mbeccati/fix-mysql9-library
Escape library as a table name in tests (#12170)
2025-10-11 17:08:47 +02:00
Grégoire Paris
6863272943 Merge remote-tracking branch 'origin/3.5.x' into 3.6.x 2025-10-11 17:07:11 +02:00
Grégoire Paris
eae6577ce2 Merge pull request #12219 from greg0ire/rework-upgrade-md
Move introduction outside of paragraph about 3.x
2025-10-11 17:05:17 +02:00
Matteo Beccati
5f6896a2f9 Avoid using LIBRARY as table name (#12170)
It is a reserved word since MySQL 9.2:
https://dev.mysql.com/doc/refman/9.2/en/create-library.html
2025-10-11 11:56:29 +02:00
Grégoire Paris
e3106d439d Move introduction outside of paragraph about 3.x
It is not specific to 3.x and should stay forever.
2025-10-11 09:41:24 +02:00
Grégoire Paris
930a790a5a Merge pull request #12212 from mpdude/revert-11769
Revert "Fix fields of transient classes being considered duplicate with `reportFieldsWhereDeclared` (#11769)"
2025-10-10 08:17:09 +02:00
Alexander M. Turek
40aa44914f Ignore DBAL deprecation that we cannot fix (yet) (#12218) 2025-10-09 23:48:42 +02:00
Grégoire Paris
7c8a528914 Merge pull request #12211 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-10-09 22:07:50 +02:00
Christian Flothmann
3b7de17f2e add jobs using PHP 8.5 in the CI (#12180) 2025-10-09 16:39:28 +02:00
Grégoire Paris
40fedadecf Merge pull request #12217 from derrabus/bugfix/deprecated-get-name
Fix DBAL deprecation
2025-10-09 15:42:59 +02:00
Alexander M. Turek
0d97a44f28 Fix DBAL deprecation 2025-10-09 15:24:06 +02:00
Alexander M. Turek
c472a1535d Stop using deprecated Collections constants (#12214) 2025-10-09 15:02:50 +02:00
Matthias Pigulla
8afaa63d73 Add a recommendation not to use multiple private fields of the same name in entity hierarchies 2025-10-09 11:11:51 +02:00
Matthias Pigulla
2ad720b304 Revert "Fix fields of transient classes being considered duplicate with reportFieldsWhereDeclared (#11769)"
This reverts commit 4feaa470af.
2025-10-09 10:23:55 +02:00
Grégoire Paris
64cd5cad20 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-10-09 08:05:48 +02:00
Matthias Pigulla
f1a8ee175c Add deprecation messages for two methods that were only annotated as being @deprecated 2025-10-08 23:09:14 +02:00
Alexander M. Turek
d3e1440175 Handle quoted PK columns properly on DBAL 4 (#12208) 2025-10-08 18:25:12 +02:00
Benjamin Eberlei
a9bd00a70b Improve migration docs from ORM 2 to 3. (#12207)
* Improve migration docs from ORM 2 to 3.

* Improve wording

* Hint about following deprecations.
2025-10-08 16:37:16 +02:00
Benjamin Eberlei
a939dc2e0d [GH-9219] Add support for toIterable over mixed or scalar results. (#12187)
* [GH-9219] Add support for toIterable over mixed or scalar results.

* Housekeeping: phpcs

* Update test names
2025-10-08 15:07:52 +02:00
Christophe Coevoet
f8186b1203 Merge pull request #12200 from mpdude/fix-invalid-dql-test-case
Fix DQL JOIN syntax in two test cases
2025-10-08 11:08:24 +02:00
Alexander M. Turek
28dd32790f Merge branch '3.5.x' into 3.6.x
* 3.5.x:
  Fix missing import
  Remove calls to getMockForAbstractClass() (#12003)
  Upgrade to doctrine/coding-standard 14
  Bump doctrine/.github from 7.3.0 to 8.0.0
2025-10-08 10:32:06 +02:00
Alexander M. Turek
4f3a5c5514 Merge pull request #12201 from derrabus/bugfix/missing-import 2025-10-07 22:57:47 +02:00
Alexander M. Turek
6641989e35 Fix missing import 2025-10-07 18:02:20 +02:00
Matthias Pigulla
048e308241 Fix DQL JOIN syntax in two test cases 2025-10-07 17:54:33 +02:00
Alexander M. Turek
8ca72a4e96 Merge branch '2.20.x' into 3.5.x
* 2.20.x:
  Remove calls to getMockForAbstractClass() (#12003)
2025-10-07 17:25:14 +02:00
Alexander M. Turek
daf74b74b5 Merge commit 'c1af765960bf88cb5109f74a05d24c4df9aaf76a' into 3.5.x
* commit 'c1af765960bf88cb5109f74a05d24c4df9aaf76a':
  Upgrade to doctrine/coding-standard 14
  Bump doctrine/.github from 7.3.0 to 8.0.0
2025-10-07 16:49:06 +02:00
Alexander M. Turek
4274dac8a2 Remove calls to getMockForAbstractClass() (#12003) 2025-10-07 16:34:22 +02:00
Alexander M. Turek
ac19b21a71 Merge branch '3.5.x' into 3.6.x
* 3.5.x:
  Add a CI job that fails on deprecations (#12188)
  use the empty string instead of null as an array offset (#12181)
  do not call setAccessible() on PHP >= 8.1 (#12182)
  Fix docs on final entities (#12176)
  Remove Database and Model First chapters that said little of value.
  Switch to IgnoreDeprecations
  docs: consistent PostgreSQL's name case
  docs: generation strategies differences between DBAL 3 and 4
  Check extra condition to decide if a test was skipped
  Use PHPUnit 11 when possible
  Migrate away from annotations in tests
  Migrate away from assertStringNotMatchesFormat()
  Migrate to willReturn()
  Migrate away from getMockForAbstractClass()
  Fix `IN`/`NOT IN` expression handling and support enums when matching on to-many-collections
2025-10-07 16:07:07 +02:00
Alexander M. Turek
c6db9feade Add a CI job that fails on deprecations (#12188) 2025-10-07 16:03:42 +02:00
Grégoire Paris
c1af765960 Merge pull request #12185 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-8.0.0
Bump doctrine/.github from 7.3.0 to 8.0.0
2025-10-07 15:40:44 +02:00
Alexander M. Turek
86d847edb8 Merge branch '2.20.x' into 3.5.x
* 2.20.x:
  use the empty string instead of null as an array offset (#12181)
  do not call setAccessible() on PHP >= 8.1 (#12182)
2025-10-07 15:23:19 +02:00
Christian Flothmann
5f3551852f use the empty string instead of null as an array offset (#12181) 2025-10-07 14:50:23 +02:00
Grégoire Paris
8144cad07c Upgrade to doctrine/coding-standard 14 2025-10-06 09:01:36 +02:00
dependabot[bot]
70fd68cf7f Bump doctrine/.github from 7.3.0 to 8.0.0
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 7.3.0 to 8.0.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/7.3.0...8.0.0)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-version: 8.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-06 06:14:08 +00:00
Matthias Pigulla
437259556c Fix CS 2025-10-01 19:48:04 +02:00
Matthias Pigulla
e7e2fef56c Fix creation of the count query, to that a new RSM is being created 2025-10-01 19:46:58 +02:00
Matthias Pigulla
3e34b8e86a Add a test to reproduce the issue 2025-10-01 19:35:18 +02:00
Christian Flothmann
7d950aba62 do not call setAccessible() on PHP >= 8.1 (#12182) 2025-10-01 16:17:00 +02:00
Massimiliano Arione
8ad560c34d Fix docs on final entities (#12176) 2025-09-26 00:28:08 +02:00
Grégoire Paris
ccfb620f31 Merge pull request #12175 from beberlei/Docs-RemoveDatabaseFirstChapter
Remove Database and Model First chapters that said little of value.
2025-09-21 22:00:51 +02:00
Benjamin Eberlei
94c4d48ae5 Remove Database and Model First chapters that said little of value. 2025-09-21 21:06:16 +02:00
HypeMC
cb8a76ba3a Add commands for inspecting configured listeners 2025-09-15 15:03:52 +02:00
Grégoire Paris
2ca63df90c Merge pull request #12161 from greg0ire/proper-attribute
Switch to IgnoreDeprecations
2025-09-12 08:23:02 +02:00
Grégoire Paris
0d4413c248 Switch to IgnoreDeprecations
Rather than disabling the error handler, this attribute available since
PHPUnit 10.5 allows to be more fine-grained and ignore only the deprecations.
2025-09-10 23:58:13 +02:00
Alexander Dmitryuk
a7a14cffaf Fix php doc for getPropertyAccessors method (#12159)
Co-authored-by: a.dmitryuk <a.dmitryuk@movavi.com>
2025-09-10 02:04:32 +02:00
Grégoire Paris
48434f4c53 Merge pull request #12150 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-08-28 07:45:06 +02:00
Grégoire Paris
200a505f36 Merge pull request #12148 from lucasmirloup/docs/generation-strategies-dbal-4
docs: generation strategies: differences between DBAL 3 and 4
2025-08-27 07:42:53 +02:00
Grégoire Paris
17d7814fdc Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-08-27 00:02:52 +02:00
Grégoire Paris
8fe1200edf Merge pull request #11895 from mpdude/fix-many-to-many-in-expression
Fix `IN`/`NOT IN` expression handling and support enums when matching on to-many-collections
2025-08-26 15:32:52 +02:00
Lucas Mirloup
f7d4e379bc docs: consistent PostgreSQL's name case 2025-08-26 11:37:07 +02:00
Lucas Mirloup
c164ae434f docs: generation strategies differences between DBAL 3 and 4 2025-08-26 11:03:48 +02:00
Grégoire Paris
ceb04bf3f6 Merge pull request #12131 from rela589n/3.6.x-class-locator-doctrine-persistence-4.1
Feature: add support for `ClassLocator`
2025-08-25 23:10:55 +02:00
Grégoire Paris
21e9fcbfbb Merge pull request #12146 from greg0ire/upg-phpunit
PHPUnit 11
2025-08-24 08:30:10 +02:00
Yevhen Sidelnyk
ed9ba16ff4 Feature: add support for ClassLocator
In the scope of https://github.com/doctrine/persistence/pull/433
(available from `doctrine/persistence` >= 4.1) there was added
`ColocatedMappingDriver::$classLocator` (`ClassLocator`) property,
which allows passing any instance of `ClassLocator` for the mapping
driver to use. This commit integrates those changes into `AttributeDriver`.

Since `doctrine/orm` maintains the support for `doctrine/persistence`
of older versions, tests ensure that `ClassLocator` actually exists.

The old paths' behaviour can be adapted into the new by passing
`FileClassLocator` into `AttributeDriver`
(see `FileClassLocator::createFromDirectories($directoryPaths)`).
2025-08-23 14:26:54 +03:00
Gregoire PARIS
db456976ed Check extra condition to decide if a test was skipped
It seems that this could happen with PHPUnit 10, then tearDown() would
crash when calling `clear()` on null, but then PHPUnit 10 did not show
that exception.
2025-08-21 13:40:44 +02:00
Grégoire Paris
2d9091778f Use PHPUnit 11 when possible 2025-08-21 13:39:49 +02:00
Grégoire Paris
17059e5265 Migrate away from annotations in tests 2025-08-21 13:39:49 +02:00
Grégoire Paris
680a9ef632 Migrate away from assertStringNotMatchesFormat()
It has been deprecated.
2025-08-21 13:39:48 +02:00
Grégoire Paris
9d5f112c7e Migrate to willReturn()
self::returnValue() and self::onConsecutiveCalls() has been deprecated.
2025-08-21 13:39:48 +02:00
Grégoire Paris
b7423c96cf Migrate away from getMockForAbstractClass()
It has been deprecated.
2025-08-21 13:39:46 +02:00
Grégoire Paris
fc1bf3b815 Merge pull request #12144 from greg0ire/3.6.x
Merge 3.5.x up into 3.6.x
2025-08-19 22:16:20 +02:00
Grégoire Paris
b6b342cada Merge remote-tracking branch 'origin/3.5.x' into 3.6.x 2025-08-19 21:57:35 +02:00
Grégoire Paris
28735afae3 Merge pull request #12143 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-08-19 21:56:34 +02:00
Grégoire Paris
0f229fbb4b Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-08-19 21:44:21 +02:00
Alexander M. Turek
bea4814d55 Merge branch '3.5.x' into 3.6.x
* 3.5.x:
  Prefer non-deprecated AbstractAsset API (#12142)
2025-08-19 16:46:37 +02:00
Alexander M. Turek
85c13edc80 Prefer non-deprecated AbstractAsset API (#12142)
Co-authored-by: Christian Flothmann <christian.flothmann@open.de>
2025-08-19 16:46:03 +02:00
Grégoire Paris
397358c308 Merge pull request #12133 from greg0ire/update-phpstan
PHPStan 2.1.22
2025-08-19 07:36:10 +02:00
Grégoire Paris
ac37a87a3d Merge pull request #12139 from doctrine/dependabot/github_actions/2.20.x/actions/checkout-5
Bump actions/checkout from 4 to 5
2025-08-18 17:31:47 +02:00
Christian Flothmann
238c15952c fix pull request URL (#12138) 2025-08-18 11:52:40 +02:00
dependabot[bot]
613f52db5a Bump actions/checkout from 4 to 5
Bumps [actions/checkout](https://github.com/actions/checkout) from 4 to 5.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-18 09:50:01 +00:00
Grégoire Paris
cf5503b0d8 PHPCS 3.13.2 (#12134) 2025-08-17 21:53:23 +02:00
Grégoire Paris
fdc88ba236 Merge pull request #12135 from greg0ire/missing-assertion
Add missing assertion in test
2025-08-17 21:06:21 +02:00
Grégoire Paris
c49bf58682 Add missing assertion in test
I forgot to copy it from another test.
2025-08-17 20:51:37 +02:00
Grégoire Paris
ae5e9c8c6c PHPStan 2.1.22 2025-08-17 19:24:33 +02:00
Grégoire Paris
ce844d94a0 Merge pull request #12126 from greg0ire/depr-nullable-prim-keys
Deprecate specifying nullable on primary key columns
2025-08-17 11:46:24 +02:00
Grégoire Paris
1a2826d147 Merge pull request #12053 from alexislefebvre/chore-remove-run-all.sh
chore: remove run-all.sh
2025-08-11 14:14:20 +02:00
Grégoire Paris
05760f9454 Merge pull request #12127 from doctrine/dependabot/github_actions/2.20.x/actions/download-artifact-5
Bump actions/download-artifact from 4 to 5
2025-08-11 13:06:03 +02:00
dependabot[bot]
26af013842 Bump actions/download-artifact from 4 to 5
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-08-11 10:22:17 +00:00
Max
c1f7a60c5b perf: Optimizing ScalarColumnHydrator::hydrateAllData (#12095) 2025-08-11 12:21:15 +02:00
Grégoire Paris
d1d13d5956 Deprecate specifying nullable on primary key columns
It produces no effect.
2025-08-08 22:23:32 +02:00
Grégoire Paris
4f8dde2d1e Add missing heading 2025-08-08 21:23:08 +02:00
Grégoire Paris
e3c320c705 Merge pull request #12124 from doctrine/3.5.x-merge-up-into-3.6.x_N9Rr16zf
Merge release 3.5.2 into 3.6.x
2025-08-08 19:46:47 +02:00
Grégoire Paris
5a541b8b3a Merge pull request #12121 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-08-08 19:00:40 +02:00
Grégoire Paris
9fb9cc46e4 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-08-08 09:03:30 +02:00
Grégoire Paris
c322c71cd4 Merge pull request #12120 from greg0ire/fix-broken-comments
Fix broken comments
2025-08-08 08:55:44 +02:00
Grégoire Paris
3c733a2fee Add missing phpdoc 2025-08-08 08:34:07 +02:00
Grégoire Paris
5984ad586a Fix broken phpdoc comments 2025-08-08 08:33:39 +02:00
Grégoire Paris
ee2c3a506b Merge pull request #12097 from mvorisek/add_fixed_id_insert_count_query_test
Add 2nd level cache test for insert without post-inserted ID
2025-08-08 08:26:23 +02:00
Grégoire Paris
781ed30926 Merge pull request #12108 from greg0ire/address-deprecations
Address deprecations
2025-08-08 08:25:29 +02:00
Grégoire Paris
04694a9f7b Merge pull request #11835 from gseidel/fix-pre-persist-call-persist
fix: calling scheduleForInsert twice
2025-08-07 06:25:35 +02:00
Grégoire Paris
257c5094c4 Use not nullable columns when part of the primary key
Using a nullable column that references another table as part of a
primary key makes no sense, and is ignored by DBAL. Let us ignore it at
the ORM level.
2025-08-06 23:06:28 +02:00
Alexander M. Turek
831232e05e Merge branch '3.5.x' into 3.6.x
* 3.5.x:
  Don't partially mock the AbstractPlatform class (#12114)
2025-08-06 18:18:01 +02:00
Alexander M. Turek
66e0e92816 Don't partially mock the AbstractPlatform class (#12114) 2025-08-06 18:12:23 +02:00
Alexander M. Turek
a774cedb24 Include stability in coverage file key (#12112) 2025-08-06 14:03:37 +02:00
Alexander M. Turek
6b8207bb11 Allow Symfony 8 (#12110) 2025-08-06 11:05:43 +02:00
Alexander M. Turek
3d3b5b51cd Run tests with Symfony 8 (#12102) 2025-08-06 10:46:32 +02:00
Michael Voříšek
5b2060e25f Add 2nd level cache test for insert without post-inserted ID
Inserts without post-inserted ID can be sent to DB grouped together
hence the extra test.
2025-08-06 08:22:48 +02:00
Grégoire Paris
760616291b Merge pull request #12105 from doctrine/3.5.x-merge-up-into-3.6.x_OhbrLWrh
Merge release 3.5.1 into 3.6.x
2025-08-05 08:39:23 +02:00
Grégoire Paris
64444dcfd5 Merge pull request #12088 from greg0ire/quote-parts
Quote parts of the table name
2025-08-05 08:05:51 +02:00
Alexander M. Turek
8584da8fdc Merge branch '3.5.x' into 3.6.x
* 3.5.x:
  Move LazyGhost deprecation to ProxyFactory (#12101)
  Address deprecations from doctrine/dbal (#12098)
2025-08-04 23:49:06 +02:00
Alexander M. Turek
eb2cd5375c Move LazyGhost deprecation to ProxyFactory (#12101) 2025-08-04 23:48:11 +02:00
Grégoire Paris
de7140e105 Address deprecations from doctrine/dbal (#12098)
- Non-standard flags are deprecated.
- Index::getColumns() is deprecated.
2025-08-04 23:47:55 +02:00
Grégoire Paris
07bb0def60 Merge pull request #12100 from doctrine/3.5.x
Merge 3.5.x up into 3.6.x
2025-08-04 18:11:51 +02:00
Grégoire Paris
39e35fc06c Merge pull request #12099 from alexislefebvre/2.20.x-update-supported-branches-on-README
doc: update supported branches on README (2.20.x)
2025-08-04 16:59:49 +02:00
Alexis Lefebvre
7f061c3870 doc: update supported branches on README 2025-08-04 16:38:55 +02:00
Grégoire Paris
74495711fb Merge pull request #11934 from mvorisek/fix_joined_subclass_persister_insert_of_multiple_entities
Fix JoinedSubclassPersister when multiple entities are inserted
2025-08-02 08:34:29 +02:00
Michael Voříšek
97a7cb8d2f Unify JoinedSubclassPersister dequeue
Fix JoinedSubclassPersister as BasicEntityPersister was already fixed in GH-10735.

The fix can be verified by modifying UnitOfWork to execute `BasicEntityPersister::executeInserts()` for multiple entities at once for the same entity class/persister instance - https://github.com/doctrine/orm/blob/2.20.3/src/UnitOfWork.php#L1186 - then reproducible on `Doctrine\Tests\ORM\Functional\Ticket\GH10531Test::testInserts` test.

As extending/modifying UnitOfWork in tests in not easily possible, I submit this fix for v2.x without a test.
2025-08-01 15:31:18 +02:00
Grégoire Paris
85d66de9df Improve comment
This comment is rendered useless by the phpdoc comment below it.
Instead, we can comment on what exactly "quoted" means.
2025-07-31 22:54:44 +02:00
Grégoire Paris
1b98be31ce Convert test into 2 unit tests
That test was testing too many thing and not really making it clear what
the expected output was, given some output. Instead, let us create 2
tests, each pertaining to the class under test.
2025-07-31 22:53:35 +02:00
Grégoire Paris
61f2752a80 Quote parts of the table name
In aa141bf001, I wrongly assumed that
$tableName would never contain a dot as I was not able to write a test
that caused that to happen.

The secret recipe appears to be to define a schema and to quote the
table name.

To fix it for the table name, I am calling quoteSingleIdentifier()
before doing the concatenation between schema name and table name.

To fix it for the sequence name, which seems only useful when using DBAL
3 for some reason, I reuse some of the logic of the deprecated method.

Fixes #12041
2025-07-31 21:49:43 +02:00
Grégoire Paris
f3371e1773 Merge pull request #12094 from greg0ire/simplify-test
Remove if statement
2025-07-31 17:12:39 +02:00
Grégoire Paris
6476894dc4 Remove if statement
Tests should not have conditional logic, and since a41c6d3, the else
branch of this conditional statement is dead.
2025-07-31 09:01:52 +02:00
Grégoire Paris
8cf161d8bc Merge pull request #12091 from doctrine/3.5.x
Merge 3.5.x up into 3.6.x
2025-07-30 16:30:50 +02:00
Grégoire Paris
e0052390e1 Merge pull request #12087 from mvorisek/improve_basic_entity_persister
Improve BasicEntityPersister to be more flexible and cleaner
2025-07-30 09:44:24 +02:00
Michael Voříšek
8c6419e0e0 Prefer strict empty-array comparison over empty() call 2025-07-29 15:15:31 +02:00
Michael Voříšek
6f5ce1aca2 BasicEntityPersister: refactor $values variable into $placeholders
The new variable name is much more clearer.
2025-07-29 15:15:31 +02:00
Michael Voříšek
98e7a53b42 Remove BasicEntityPersister::$insertSql cache property
When the persister is extended to do a multi update, the caching is not
wanted. The impact is minimal as the CPU/time overhead per query is
much bigger and the prepared statement is not cached anyway.
2025-07-29 15:15:31 +02:00
Gerhard Seidel
3aaaf37dfb fix: PrePersistEventTest typos and unnecessary comments 2025-07-29 14:40:20 +02:00
Grégoire Paris
154a4652ee Merge pull request #12086 from mvorisek/add_cache_rw_strict_locking_test
Add functional strict-locking 2nd level cache test
2025-07-29 11:48:25 +02:00
Michael Voříšek
ae7489ff19 Add functional strict-locking 2nd level cache test 2025-07-28 12:14:50 +02:00
Grégoire Paris
0f32569a7a Merge pull request #12083 from greg0ire/depr-reflFields
Deprecate ClassMetadata::$reflFields
2025-07-27 23:19:29 +02:00
Gregoire PARIS
d99f74c704 Deprecate ClassMetadata::$reflFields
It is replaced with property accessors since
https://github.com/doctrine/orm/pull/11659
2025-07-24 09:55:19 +02:00
Grégoire Paris
a2990e1a0a Merge pull request #12071 from stlgaits/mapping-command-json-output
Add JSON format option for orm:mapping:describe command output
2025-07-23 07:31:41 +02:00
Grégoire Paris
d355c4a990 Merge pull request #12081 from doctrine/3.5.x
Merge 3.5.x up into 3.6.x
2025-07-22 09:58:24 +02:00
stlgaits
88c395c488 Add --em option help description for orm:mapping:describe 2025-07-22 09:45:20 +02:00
stlgaits
256d6cb0d7 Add JSON format option for orm:mapping:describe command output 2025-07-22 09:43:50 +02:00
Grégoire Paris
62ca8424d8 Merge pull request #12080 from greg0ire/3.5.x
Merge 2.20.x up into 3.5.x
2025-07-22 09:35:03 +02:00
Gregoire PARIS
3f2209a571 Merge remote-tracking branch 'origin/2.20.x' into 3.5.x 2025-07-22 09:09:21 +02:00
Grégoire Paris
1ee01f4473 Merge pull request #12078 from stlgaits/2.20.x
Fix embedded classes display in orm:mapping:command output
2025-07-22 08:48:52 +02:00
stlgaits
8a9ed138a8 Fix embedded classes display in orm:mapping:command output 2025-07-21 15:44:46 +02:00
Grégoire Paris
e714b1a2fc Merge pull request #12075 from andrew-demb/patch-1
📖 Actualize code block to be compatible with DBAL v4, use modern PHP
2025-07-15 18:16:50 +02:00
Benjamin Morel
ec0bf05853 Use PHP attributes syntax in schema validator message (#12074) 2025-07-15 00:24:16 +02:00
Andrii Dembitskyi
dc58aa3ea1 📖 Actualize code block to be compatible with DBAL v4, use modern PHP 2025-07-14 20:15:18 +03:00
Grégoire Paris
23b74e4f8b Merge pull request #12063 from wmouwen/test/gh-10788
Proxy class with BackedEnum as primary key does not convert the enum
2025-07-14 10:04:21 +02:00
Willem Mouwen
d2b699e6f5 fix: Convert BackedEnum to scalar value when binding a parameter 2025-07-12 20:50:25 +02:00
Willem Mouwen
0338d69324 test: Store an entity with a proxy association that has a BackedEnum primary identifier 2025-07-12 20:50:19 +02:00
Grégoire Paris
a1fdc6eb6e Merge pull request #12073 from doctrine/3.5.x
Merge 3.5.x up into 3.6.x
2025-07-12 10:04:59 +02:00
Grégoire Paris
d583460d63 Merge pull request #12068 from janedbal/prevent-delete-limit-misuse
QueryBuilder: prevent misuse of DELETE with LIMIT
2025-07-12 09:49:12 +02:00
Grégoire Paris
2c01dac173 Merge pull request #12072 from greg0ire/update-baseline
Update baseline because of doctrine/dbal 4.3.0
2025-07-12 09:46:50 +02:00
Grégoire Paris
137ecb491a Update baseline because of doctrine/dbal 4.3.0
This should fix the build. Maybe some of the reported issues can be
addressed, but if that is the case, it should probably be done on the
next minor branch.
2025-07-11 18:42:54 +02:00
Jan Nedbal
79d4cfdce8 Prevent misuse of DELETE with LIMIT in QueryBuilder
This fixes a dangerous bug where LIMIT is silently ignored in DELETE
      operations, potentially causing developers to delete all rows instead
      of just the intended subset. The setMaxResults() method would be
      silently omitted from the final query, making operations like
      delete last entry accidentally delete entire tables.
2025-07-10 17:31:03 +02:00
Grégoire Paris
f38ee09082 Merge pull request #12062 from janedbal/binary-id-eager-fetch-reupload
Fix unhandled ParameterType case for binary PKs
2025-07-10 17:05:57 +02:00
Jan Nedbal
6ab858a5c5 Apply suggestion from @greg0ire
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2025-07-10 16:54:02 +02:00
Jan Nedbal
3dca27ce0d Fix unhandled ParameterType case for binary PKs
Add proper handling for binary primary key parameter types that were
  previously causing runtime exceptions. The existing parameter type
  switch statement was missing a case for binary types, leading to
  unhandled scenarios when working with binary primary keys.

  This ensures consistent parameter type handling across all supported
  primary key data types in the ORM.
2025-07-07 12:07:52 +02:00
Grégoire Paris
e19704e1f8 Merge pull request #12056 from greg0ire/switch-to-tags
Remove branchName from unmaintained branch
2025-07-04 07:50:39 +02:00
Alexis Lefebvre
41ea59ac66 chore: use a shorter name for CI on GitHub Actions (#12055) 2025-07-04 00:19:01 +02:00
Alexis Lefebvre
e605e6d569 doc: add links to GitHub Actions on README (#12054) 2025-07-04 00:13:51 +02:00
Grégoire Paris
9437675d3b Remove branchName from unmaintained branch
Since https://github.com/doctrine/doctrine-website/pull/372, they are no
longer necessary, it's possible to rely on tags. Once this is merged,
the branches can be removed.
2025-07-02 23:32:01 +02:00
Grégoire Paris
5301b99533 Merge pull request #12051 from greg0ire/stop-using-depr-method
Stop using QueryBuilder::getRootAlias()
2025-07-02 08:35:19 +02:00
Grégoire Paris
63409d638c Merge pull request #12048 from greg0ire/update-branch-metadata
Update branch metadata for 3.5.0
2025-07-02 08:12:04 +02:00
Alexis Lefebvre
d68c1dcd6d chore: remove run-all.sh 2025-07-02 00:14:28 +02:00
Grégoire Paris
00c7b70211 Stop using QueryBuilder::getRootAlias()
That method has been deprecated for almost 15 years, in
85d40847ac.
On top of that I'm adding a deprecation for something related that was
scheduled for deprecation at in the same commit.
2025-07-01 21:21:04 +02:00
Grégoire Paris
9b9160b206 Update branch metadata for 3.5.0
3.5.0 has been released.

- 3.6.x is the new upcoming branch;
- 3.5.x is now the current branch;
- 3.4.x is no longer maintained.
2025-07-01 19:45:42 +02:00
Grégoire Paris
6deec3655b Merge pull request #12046 from greg0ire/3.5.x
Merge 3.4.x up into 3.5.x
2025-07-01 19:40:53 +02:00
Grégoire Paris
7f40422d21 Merge remote-tracking branch 'origin/3.4.x' into 3.5.x 2025-07-01 19:13:12 +02:00
Grégoire Paris
e67fa5388b Merge pull request #12043 from beberlei/Bugfix-DisableNativeLazyLogicException
Only throw PHP 8.4 requirement exception when enabling native lazy objects.
2025-06-30 23:43:15 +02:00
Grégoire Paris
80053336c9 Merge pull request #12044 from doctrine/3.4.x
Merge branch 3.4.x into 3.5.x
2025-06-30 21:53:04 +02:00
Grégoire Paris
dddcc507ef Merge pull request #12039 from xabbuh/pr-12036
do not register the legacy proxy class name resolver with enabled native lazy ghost
2025-06-30 20:38:34 +02:00
Christian Flothmann
b41d9da88d do not register the legacy proxy class name resolver with enabled native lazy ghost 2025-06-30 19:14:11 +02:00
Benjamin Eberlei
c04bfb78b7 Only throw PHP 8.4 requirement exception when enabling native lazy objects. 2025-06-30 19:01:49 +02:00
Grégoire Paris
8a5dfc86d4 Merge pull request #12037 from stlgaits/mapping-describe-completion
Add console completion for entityName param of orm:mapping:describe c…
2025-06-29 18:26:55 +02:00
Grégoire Paris
79e103c07e Merge pull request #11978 from Ocramius/feature/#11977-batch-handling-of-inserts-with-given-ids
#11977 implemented batching of `INSERT` operations in `UnitOfWork#executeInserts()` so that `EntityPersister#executeInserts()` calls are reduced
2025-06-28 22:19:54 +02:00
stlgaits
5afadf163a Add console completion for entityName param of orm:mapping:describe command 2025-06-28 11:27:52 +02:00
Grégoire Paris
edfaa37228 Merge pull request #12036 from greg0ire/depr-proxy-autoload
Deprecate proxy autoloader and class name resolver
2025-06-28 11:09:37 +02:00
Grégoire Paris
ea056e98ba Deprecate proxy autoloader and class name resolver
These are only needed when not using native lazy objects.
2025-06-27 19:24:23 +02:00
Grégoire Paris
bab5771e98 Merge pull request #12034 from doctrine/3.4.x
Merge 3.4.x up into 3.5.x
2025-06-27 18:32:26 +02:00
Grégoire Paris
ee919d6231 Merge pull request #12030 from greg0ire/test-w-lazy-o
Rework tests and benchmarks to work with lazy objects
2025-06-27 18:13:24 +02:00
Grégoire Paris
04c390693a Merge pull request #12033 from greg0ire/remove-assert
Remove wrong assertion
2025-06-27 15:55:40 +02:00
Grégoire Paris
49293c4d48 Merge pull request #12032 from doctrine/3.4.x-merge-up-into-3.5.x_dG7qI4BR
Merge release 3.4.3 into 3.5.x
2025-06-27 14:44:44 +02:00
Gregoire PARIS
8d9e2e7d4e Remove wrong assertion
When using native lazy objects, it is plain wrong.
2025-06-27 14:42:37 +02:00
Grégoire Paris
ef607f26c2 Merge pull request #12031 from doctrine/stof-patch-1
Clean the handling of proxy initialization in the UnitOfWork
2025-06-27 14:14:15 +02:00
Gregoire PARIS
ed543a205c Rework tests and benchmarks to work with lazy objects
These tests and benchmarks are still relevant with lazy objects.
I am not setting up an extra job to test phpbench without native lazy
objects. Instead, I'm bumping the PHP version to 8.4 so that native lazy
objects are in use.
2025-06-27 14:12:58 +02:00
Christophe Coevoet
de1c28bb16 Clean the handling of proxy initialization in the UnitOfWork
Using the VarExporter Hydrator to assign default values of properties when marking an entity as initialized is needed only when using var-exporter proxies.
For lazy objects, this behavior is already provided by `ReflectionClass::markLazyObjectAsInitialized`
2025-06-27 13:58:03 +02:00
Grégoire Paris
60ff966d54 Merge pull request #12022 from greg0ire/depr-proxy-dir
Provide upgrade path to new ORMSetup::create* signature
2025-06-27 08:12:42 +02:00
Grégoire Paris
33684253c3 Merge pull request #12026 from doctrine/3.4.x-merge-up-into-3.5.x_yt3lc4tn
Merge release 3.4.2 into 3.5.x
2025-06-26 21:07:39 +02:00
Grégoire Paris
b4ca0cd5fb Merge pull request #12024 from greg0ire/3.4.x
Merge 2.20.x up into 3.4.x
2025-06-26 20:51:01 +02:00
Grégoire Paris
a49c1beb93 Merge remote-tracking branch 'origin/2.20.x' into 3.4.x 2025-06-26 20:38:31 +02:00
Grégoire Paris
76852cfef3 Provide upgrade path to new ORMSetup::create* signature
Currently we have ORMSetup::create*Configuration methods with a
$proxyDir argument that is used to configure the proxy directory, but
also as a seed for generating a namespace for cache systems.

Since these methods could be used with named arguments, renaming the
argument is not really an option and we need separate methods.
2025-06-26 00:14:59 +02:00
Grégoire Paris
3bd89caf36 use lowercase for word in upgrade guide 2025-06-25 23:27:18 +02:00
Grégoire Paris
eb2e7d959c Merge pull request #12020 from greg0ire/depr-legacy-proxy
Deprecate more proxies-related methods or calls
2025-06-25 23:17:56 +02:00
Grégoire Paris
a4b20356f4 Merge pull request #11988 from jannes-io/3.4.x
Add index mapping to column
2025-06-25 11:17:22 +02:00
Grégoire Paris
2550b2d1de Deprecate more proxies-related methods or calls 2025-06-25 00:04:27 +02:00
jannes
e94e1ab126 Add index mapping to Column
Adds a new option to Column mapping to add indexes to class fields
directly instead of having to use the Index() class attribute.
This allows users to define indexes in traits
where access to the class isn't available.
Fixes #11982
2025-06-24 19:50:47 +02:00
Grégoire Paris
6307b4fa7d Merge pull request #8012 from sgehrig/bug/#8011-ordering-with-arithmetic-expression
Bug/#8011 ordering with arithmetic expression
2025-06-24 19:50:46 +02:00
Grégoire Paris
19e1a64a91 Merge pull request #12014 from greg0ire/3.5.x
Merge 3.4.1 up into 3.5.x
2025-06-21 13:57:03 +02:00
Grégoire Paris
082e776e91 Merge remote-tracking branch 'origin/3.4.x' into 3.5.x 2025-06-21 13:14:14 +02:00
Grégoire Paris
92e2f6db83 Merge pull request #12012 from greg0ire/revert-allfields-dto
Revert "add capability to use allfields sql notation"
2025-06-21 12:44:26 +02:00
Grégoire Paris
aa624f64c1 Remove trailing whitespace 2025-06-21 11:58:51 +02:00
Grégoire Paris
e1675eb371 Revert "add capability to use allfields sql notation"
This reverts commit 12c721f528.

This feature introduces several issues:

- It adds alias.*, which is a first, for instance you cannot do
SELECT u.* FROM User u
- If introduces coupling between property order in mapping fields and
  the result.
2025-06-21 11:58:42 +02:00
Grégoire Paris
cc2b6385a1 Merge pull request #12011 from greg0ire/3.4.x
Merge 2.20.x up into 3.4.x
2025-06-21 11:48:10 +02:00
Grégoire Paris
a64bed9bbb Merge remote-tracking branch 'origin/2.20.x' into 3.4.x 2025-06-21 11:11:52 +02:00
Grégoire Paris
3272e1c0af Merge pull request #12008 from greg0ire/add-test-to-todo-list
Ensure proxies implementations behave the same on entity not found
2025-06-20 00:24:56 +02:00
Grégoire Paris
69da22d517 Ensure proxies implementations behave the same on entity not found
Both implementations are supposed to throw EntityNotFoundException
2025-06-19 10:07:06 +02:00
Grégoire Paris
06109f360f Merge pull request #12002 from greg0ire/relax-type-declarations
Make proxyDir and proxyNs nullable and optional
2025-06-19 08:00:18 +02:00
Grégoire Paris
06a9ef1127 Make proxyDir and proxyNs nullable and optional
When using native lazy objects, it should be possible to omit these
arguments, hence the default value.
Also, when using native lazy objects, one should not have to configure
the corresponding Configuration attributes, which means
EntityManager__construct() should be able to pass null to this class,
hence the nullability.

Fixes #11997
2025-06-18 23:23:30 +02:00
Alexander M. Turek
5d21bb158b Fix calls to Application::add() (#12006) 2025-06-18 08:58:26 +02:00
Grégoire Paris
bbde41f712 Merge pull request #12005 from greg0ire/depr-no-lazy-objects
Deprecate not using native lazy objects on PHP 8.4+
2025-06-18 07:24:56 +02:00
Alexander M. Turek
8c0994f35f Detect DBAL's number type (#11781) 2025-06-18 02:43:47 +02:00
Grégoire Paris
3d390bc053 Deprecate not using native lazy objects on PHP 8.4+ 2025-06-18 00:14:15 +02:00
Grégoire Paris
16f1be7f10 Merge pull request #12004 from doctrine/3.4.x
Merge 3.4.x up into 3.5.x
2025-06-18 00:12:23 +02:00
Grégoire Paris
c74df3fab3 Merge pull request #12001 from greg0ire/lazy-objects-by-default
Enable native lazy objects by default
2025-06-17 23:50:46 +02:00
Grégoire Paris
f2c902ee03 Rewrite test with native lazy ghost
I do not think this needs to be tested on all versions of PHP, using
native lazy objects allows us to remove a deprecation.
2025-06-17 23:35:47 +02:00
Grégoire Paris
4e5e3c5e50 Enable native lazy objects by default
This should make the test suite look less like a christmas tree.
2025-06-17 23:09:48 +02:00
Grégoire Paris
da697f218f Merge pull request #12000 from greg0ire/fix-var-name
Use the correct environment variable name for lazy objects and enable them by default
2025-06-17 21:15:38 +02:00
Grégoire Paris
4f47a80deb Use the correct environment variable name for lazy objects
The test suite checks for ENABLE_NATIVE_LAZY_OBJECTS
I have also renamed the matrix variable for the sake of consistency.
2025-06-17 08:35:16 +02:00
Grégoire Paris
1334162a56 Merge pull request #11989 from greg0ire/late-depr
Deprecate methods for configuring no longer configurable features
2025-06-16 08:37:59 +02:00
Grégoire Paris
ab89517093 Merge pull request #11987 from greg0ire/update-branch-metadata
Update branch metadata
2025-06-16 08:37:20 +02:00
Grégoire Paris
48a51d8470 Merge pull request #11992 from eltharin/error_doc_codeblock
repair code block bad showing
2025-06-16 08:36:13 +02:00
eltharin
ab11244f08 repair code block bad showing 2025-06-16 08:03:47 +02:00
Grégoire Paris
68ec3ebaa3 Remove trailing whitespace 2025-06-14 18:14:58 +02:00
Grégoire Paris
4f4ed2f242 Deprecate methods for configuring no longer configurable features
In 3.0.0, it is no longer possible to disable lazy ghost objects, and
likewise, it is no longer possible to disable rejecting id collisions in
the identity map, so let us deprecate the related methods.
I was supposed to do this in 3.1.0.
2025-06-14 18:14:54 +02:00
Grégoire Paris
a1c2be140d Update branch metadata
- 3.5.x has been created
- 3.4.0 has been released
- 3.3.x is no longer maintained
2025-06-14 13:50:55 +02:00
Grégoire Paris
4664373bd0 Merge pull request #11985 from doctrine/3.3.x-merge-up-into-3.4.x_KXrSCX8l
Merge release 3.3.4 into 3.4.x
2025-06-14 13:47:14 +02:00
Grégoire Paris
5ab6b74f14 Merge pull request #11984 from doctrine/2.20.x
Merge 2.20.x up into 3.3.x
2025-06-14 13:32:43 +02:00
Marco Pivetta
79cc70a62f #11977 expanded test coverage to check interleaved assigned-id vs generated-id entities
As noted by @bendavies

Ref: https://github.com/doctrine/orm/pull/11978#discussion_r2141143273
2025-06-11 23:44:24 +02:00
Marco Pivetta
4e6b5a1b0b #11977 provided method documentation / example, as per @greg0ire's feedback
Ref: https://github.com/doctrine/orm/pull/11978#discussion_r2140881217
2025-06-11 22:53:22 +02:00
Marco Pivetta
21b144fff9 #11977 removed unused type-hint, which can be completely inferred by the parameters 2025-06-11 22:50:15 +02:00
Marco Pivetta
658940de38 #11977 only perform batching if/when the AssignedGenerator is in use
The `SequenceGenerator` is potentially used for PostgreSQL table auto-generated fields, but
the `SequenceGenerator` is not a **POST**-insert generator.

Because the `SequenceGenerator` is used in the middle of `INSERT` operations performed
by persisters, we cannot rely on it in batching operations: disabling it, so we get a green
test suite on PostgreSQL.

This change makes `GH10531Test` pass on PostgreSQL: see #10531
2025-06-11 18:26:20 +02:00
Marco Pivetta
ad487370f5 #11977 hardened InsertBatchTest to check entity types of sequential batches 2025-06-11 18:16:45 +02:00
Marco Pivetta
259f83b549 #11977 added test coverage verifying that persisters are being used to batch INSERTs 2025-06-11 17:36:24 +02:00
Marco Pivetta
4a24860dcf #11977 isolated INSERT batch generation to own @internal performance-sensitive class 2025-06-11 17:18:23 +02:00
Marco Pivetta
116cdf8661 #11977 implemented simplistic (and ugly) batch handing of INSERT operations in UnitOfWork#executeInserts()
This logic also brings a minor benefit in reducing the number of times `ListenersInvoker#getSubscribedSystems`
is queried.

TODOs:

* [ ] integration test this - it is expected to reduce the number of `EntityPersister#executeInserts()` calls
* [ ] refactor this by creating a new `@internal` class for the batch, and perhaps batch via a generator
* [ ] reduce amount of repeated `getClassMetadata()` calls
* [ ] reduce overall size of `UnitOfWork` code, instead of increasing it
2025-06-11 15:43:04 +02:00
Grégoire Paris
71550106d4 Merge pull request #11975 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-7.3.0
Bump doctrine/.github from 7.2.2 to 7.3.0
2025-06-09 22:24:12 +02:00
dependabot[bot]
36011f0d0f Bump doctrine/.github from 7.2.2 to 7.3.0
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 7.2.2 to 7.3.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/7.2.2...7.3.0)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-version: 7.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-09 07:13:58 +00:00
Grégoire Paris
c97d775370 Merge pull request #11963 from dbu/update-doc-building
cleanup doc building instructions
2025-06-09 07:45:09 +02:00
Grégoire Paris
97b29bb063 Merge pull request #11973 from eltharin/add_constructor
Add constructor argument
2025-06-07 09:41:24 +02:00
Grégoire Paris
e9f0345a97 Merge pull request #11966 from greg0ire/partial-revert-10162-2
Partially revert to stdout
2025-06-07 09:41:03 +02:00
eltharin
b7fff508a4 add argument in constructor 2025-06-06 18:39:24 +02:00
Grégoire Paris
c6fa14ed52 Merge pull request #11971 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-06-06 13:05:27 +02:00
Grégoire Paris
05c8c5f114 Merge pull request #11969 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2025-06-06 12:29:34 +02:00
Gregoire PARIS
1dbdb0e895 Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2025-06-06 12:08:24 +02:00
Grégoire Paris
0feb09d0d6 Partially revert to stdout
This command's purpose is to provide structured data, except for a call
to caution() that warns the user in case they do not have any mapped
entities or they have errors.
2025-06-06 07:57:38 +02:00
Grégoire Paris
fe5f8bbaa1 Merge pull request #11965 from greg0ire/partial-revert-10162
Revert to stdout for MappingDescribeCommand
2025-06-06 00:04:07 +02:00
Grégoire Paris
ecf3cec376 chore: ignore deprecations from Symfony
Symfony 7.3 is not available to all of our users, so we cannot switch to
native lazy objects, which require a PHP version higher than the lowest
PHP version we support.
2025-06-05 23:19:32 +02:00
Grégoire Paris
0a714db4d9 Revert to stdout for MappingDescribeCommand
In f256d996cc, I did a global move to
stderr for notifications, and went a bit overboard for
MappingDescribeCommand, which purpose is to output a description.
2025-06-05 23:07:28 +02:00
David Buchmann
471fda8d0b cleanup doc building instructions 2025-06-05 07:44:37 +02:00
Grégoire Paris
dfe32c2f74 Unwrap literalinclude block (#11962)
For some reason, it does not appear to work when nested inside a
code-block directive. Anyway, if you specify the language attribute, you
get markup identical to what you obtain when using code-block and
literalinclude, so this wrapping seems unneeded.
2025-06-04 00:18:59 +02:00
Grégoire Paris
c51ba3ce6b Merge pull request #11951 from dbu/fix-doc-syntax
insert blank line before code in code-block
2025-05-27 14:08:44 +02:00
David Buchmann
fe025e8d23 insert blank line before code in code-block 2025-05-27 08:59:14 +02:00
Grégoire Paris
0a43e4af8f Merge pull request #11946 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-05-25 18:35:30 +02:00
Grégoire Paris
7111cc09f3 Merge pull request #11945 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2025-05-25 18:12:06 +02:00
Grégoire Paris
777504b9c4 Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2025-05-24 19:19:52 +02:00
Dimitri Dovgan
9d9985076a Add missing closing bracket (#11937)
Corrected a malformed attribute in the documentation.
2025-05-18 12:08:50 +02:00
Olivier Massot
35d301b052 Association Mappings: replace assertions by explicit exceptions (#11896) 2025-05-16 08:37:08 +02:00
Grégoire Paris
083b241c81 Merge pull request #11846 from eltharin/all_fields
add capability to use allfields sql notation
2025-05-08 10:55:51 +02:00
Grégoire Paris
ae2957cf7e Merge pull request #11932 from dbannik/2.20.3-issue-11931
#11931 Bug when change sql filter [Related issue #11694]
2025-05-06 07:53:48 +02:00
Dmitry Bannik
e172b3bf9c #11931 Bug when change sql filter [Related issue #11694]
This fix takes into account the invalidation of the filter sql for SingleTablePersister and JoinedSubclassPersister
2025-05-05 23:43:27 +03:00
Grégoire Paris
c9c6e8da2e Merge pull request #11834 from dbu/document-generated-columns
document how to work with generated columns
2025-05-05 10:05:55 +02:00
Grégoire Paris
528b8837e1 Merge pull request #11929 from doctrine/2.20.x-merge-up-into-2.21.x_KkdqS0u7
Merge release 2.20.3 into 2.21.x
2025-05-02 21:57:23 +02:00
Grégoire Paris
b9989555fd Merge pull request #11927 from greg0ire/3.4.x
Merge 3.3.x up into 3.4.x
2025-05-02 20:26:12 +02:00
Grégoire Paris
80a79f6d2d Merge remote-tracking branch 'origin/3.3.x' into 3.4.x 2025-05-02 19:48:18 +02:00
Grégoire Paris
1f1891d3e2 Merge pull request #11926 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2025-05-02 19:42:51 +02:00
Grégoire Paris
c9fc4d90e5 Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2025-05-02 19:17:15 +02:00
Grégoire Paris
17d28b5c4c Merge pull request #11917 from stof/lazy_ghost_postload
Fix the initialization of lazy-ghost proxies with postLoad listeners
2025-05-02 19:07:53 +02:00
Christophe Coevoet
a2d510c6f4 Fix the initialization of lazy-ghost proxies with postLoad listeners
PostLoad listeners might initialize values for transient properties, so
the proxy should not skip initialization when using transient
properties.

Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>
2025-05-02 15:27:59 +02:00
Anton
0e3cff0c6a Update composite-primary-keys.rst (#11919)
Fix examples
2025-05-01 23:56:00 +02:00
Grégoire Paris
5c50ed925a Merge pull request #11924 from xabbuh/dbal-6867
prefer primary key constraints over Index::isPrimary()
2025-05-01 13:09:32 +01:00
Christian Flothmann
5a1e560f87 prefer primary key constraints over Index::isPrimary() 2025-05-01 13:46:41 +02:00
Grégoire Paris
78e8887759 Merge pull request #11911 from xabbuh/dbal-6890
disable detecting modified indexes with DBAL 4.3
2025-04-25 11:02:23 +02:00
Grégoire Paris
9a3f5579f1 Merge pull request #11921 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-04-24 18:59:58 +02:00
Grégoire Paris
5eb298b99b Merge pull request #11914 from xabbuh/dbal-6886
do not use deprecated index features
2025-04-23 10:54:33 +02:00
Christian Flothmann
5eb0255f47 do not use deprecated index features 2025-04-23 08:01:37 +02:00
Grégoire Paris
28575f58af Merge pull request #11903 from xabbuh/dbal-6867
do not use deprecated primary key constraint features
2025-04-23 07:56:01 +02:00
Christian Flothmann
457d2d2841 do not use deprecated primary key constraint features 2025-04-23 07:07:30 +02:00
eltharin
12c721f528 add capability to use allfields sql notation
in a dto, this PR allow to call u.* to get all fileds fo u entity in one call,
2025-04-22 21:40:54 +02:00
Grégoire Paris
9a9c3e8aba Merge pull request #11847 from eltharin/newentityInDto
add capability to hydrate an entity in a dto
2025-04-22 21:00:16 +02:00
Christophe Coevoet
2a4ebca90e Refactor tests to avoid using instance properties to track postLoad
The old proxy implementation of doctrine/common was triggered by public
methods rather than access to properties (making public properties
unsupported in entities), so tests could use public instance properties
to track the state of postLoad lifecycle callbacks without triggering
the proxy initialization when reading that state (which then changes the
state of triggering the postLoad callback).
As the new proxy implementation hooks into properties instead, the tests
now use a static method (ensuring it is reset properly before loading
the instance for which we care about the tracking) instead of an
instance property.
2025-04-22 17:39:29 +02:00
Christian Flothmann
5d01c66c84 disable detecting modified indexes with DBAL 4.3 2025-04-22 12:45:20 +02:00
Yevhen Sidelnyk
a2516b67dc [DOC]: fix setFileExtension() xml mapping documentation (#11905)
* doc: fix setFileExtension() xml mapping documentation

* Update docs/en/reference/xml-mapping.rst

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

---------

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2025-04-21 22:21:43 +02:00
eltharin
46a020108d add capability to hydrate an entity in a dto
this PR allow to hydrate data in an entity  nested in a dto
2025-04-21 14:29:19 +02:00
Grégoire Paris
3d4e9b3ecf Merge pull request #11912 from xabbuh/dbal-6823
[#6823] pass unquoted identifier folding to AbstractPlatform
2025-04-20 11:09:40 +02:00
Grégoire Paris
d1ee40e7d5 Merge pull request #11908 from xabbuh/dbal-6674
use the platform to quote table names
2025-04-20 11:08:07 +02:00
Christian Flothmann
65d2720764 [#6823] pass unquoted identifier folding to AbstractPlatform 2025-04-17 23:56:20 +02:00
Grégoire Paris
3e18a58de6 Merge pull request #11907 from xabbuh/dbal-6728
do not use deprecated foreign key constraint features
2025-04-17 23:10:47 +02:00
Christian Flothmann
a9f9202c00 do not use deprecated foreign key constraint features 2025-04-17 21:18:35 +02:00
Grégoire Paris
d8cb71fe4a Merge pull request #11906 from xabbuh/dbal-6710
no longer use Table::columnsAreIndexed()
2025-04-17 08:28:28 +02:00
Christian Flothmann
d659591b6c use the platform to quote table names 2025-04-15 12:49:24 +02:00
Christian Flothmann
e2430ac9a7 no longer use Table::columnsAreIndexed() 2025-04-15 12:43:51 +02:00
Grégoire Paris
b286d6cd2c Merge pull request #11902 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-04-14 23:38:21 +02:00
Grégoire Paris
0b373f6c27 Merge pull request #11900 from xabbuh/dbal-6886
replace Index::overrules() with custom checks
2025-04-14 23:17:07 +02:00
Benjamin Eberlei
443cf92242 Merge pull request #11852 from beberlei/PropertyHookSupport
Final tests and adjustments to allow mapping properties with hooks.
Property hooks are not supported when using `symfony/var-exporter`.
2025-04-12 11:33:27 +02:00
Christian Flothmann
36b9064dbe replace Index::overrules() with custom checks 2025-04-07 08:53:18 +02:00
Matthias Pigulla
9bf407f336 Fix IN/NOT IN expression handling and support enums when matching on to-many-collections
This fixes that using a `Criteria` with an `IN` or `NIN` expression on a to-many collection currently leads to an SQL error (#6173). The `ManyToMany` persister needs to know about the slightly different SQL syntax for `[NOT] IN ()`.

In the case of `[NOT] IN` expressions, the value will be an array, which also required me to change (I guess "fix") the parameter type handling. I have pulled the necessary code from the `BasicEntityPersister` and placed it as static helper methods in `PersisterHelper`.

This is somewhat inspired by #11516, which aims at fixing #11481: By re-using the parameter type handling code, it also fixes using backed enums in `EQ`, `IN` and `NIN` expressions within `Criteria` when `matching()` on one-to-many and many-to-many collections.
2025-03-30 22:44:12 +02:00
Benjamin Eberlei
eb3b984132 Add support for PHP 8.4 Lazy Objects RFC with configuration flag (#11853)
* Introduce PHP 8.4 lazy proxy/ghost API.

* Call setRawValueWithoutLazyInitialization for support with lazy proxy.

* Refactorings

* Revert test change partially and skip with lazy objects.

* Houskeeping: phpcs

* Run with ENABLE_LAZY_PROXY=1 in php 8.4 matrix.

* Fix ci

* Transient properties are not skipping lazy initialization anymore, to expensive and could lead to errors. Adjust lifecycle test that uses transient properittes for assertions.

* Restore behavior preventing property hook use in 8.4 in unsupported coditions

* Add \ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE

Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>

* Rename isNativeLazyObjectsEnabled/enableNativeLazyObjects.

* Housekeeping: phpcs

* Update advanced-configuration docs and make proxy config variables not required anymore with native lazy objects.

* Move code around

* Apply suggestions from code review

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

* Pick suggestions

---------

Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2025-03-29 23:14:13 +01:00
Grégoire Paris
cc29ae0d36 Merge pull request #11891 from mpdude/expression-matching-caveats
Add more detailed caveats for using the Collection filtering API
2025-03-29 11:31:36 +01:00
Grégoire Paris
bd4a053d29 Merge pull request #11894 from DavidPetrasek/3.3.x
Fix URL's in xml-mapping.rst
2025-03-27 20:59:26 +01:00
David Petrásek
52fbfb3785 Revert to http for namespace name
These URLs are meant as identifiers rather than actual urls intended to
be used to perform an HTTP request.
2025-03-27 17:39:10 +01:00
Matthias Pigulla
c259371e5f Remove property hooks mention 2025-03-26 18:58:17 +01:00
Matthias Pigulla
dcdd58b642 working-with-associations.rst aktualisieren
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2025-03-26 18:14:01 +01:00
Matthias Pigulla
7b9c53854f Add more detailed caveats for using the Collection filtering API 2025-03-26 13:38:52 +01:00
Grégoire Paris
cdc5fe11dd Merge pull request #11889 from Rixafy/docs-typo-fix
Fix docs typo (nulable -> nullable)
2025-03-25 23:16:01 +01:00
Rixafy
69ece00564 Fix docs typo (nulable -> nullable) 2025-03-25 22:25:00 +01:00
Grégoire Paris
04395f98f9 Merge pull request #11887 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-03-25 16:25:25 +01:00
Grégoire Paris
4baa7bd252 Merge pull request #11882 from xabbuh/dbal-6867
favor Table::addPrimaryKeyConstraint() over Table::setPrimaryKey()
2025-03-25 16:06:32 +01:00
Christian Flothmann
c55f10e501 favor Table::addPrimaryKeyConstraint() over Table::setPrimaryKey() 2025-03-25 12:40:28 +01:00
Grégoire Paris
f3fb79658e Merge pull request #11886 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2025-03-25 08:44:22 +01:00
Grégoire Paris
10a32cb824 Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2025-03-25 07:56:47 +01:00
Grégoire Paris
c679d1b007 Merge pull request #11885 from greg0ire/no-triple-stars
Avoid triple stars
2025-03-25 07:51:08 +01:00
Grégoire Paris
1e15b22dcb Avoid triple stars
They don't have a special meaning, and are rendered like this:
<strong>*REQUIRED</strong>*.
2025-03-25 07:49:53 +01:00
Grégoire Paris
0c10010f9f Merge pull request #11884 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-03-24 22:34:05 +01:00
Grégoire Paris
d88371331d Merge pull request #11883 from xabbuh/dbal-6864
adapt assertions for new consistent PRIMARY KEY formatting
2025-03-24 22:02:26 +01:00
Christian Flothmann
b260ec8a00 adapt assertions for new consistent PRIMARY KEY formatting 2025-03-24 21:40:11 +01:00
Grégoire Paris
44057b4683 Merge pull request #11845 from lacatoire/update-message-annotation-to-attribute
Update message of `ORMInvalidArgumentException`
2025-03-24 10:58:02 +01:00
Grégoire Paris
013df03795 Upgrade to doctrine/coding-standard 13 (#11881) 2025-03-24 07:18:07 +01:00
Louis-Arnaud
2d2a34407c Use attributes in exception message 2025-03-23 16:07:31 +01:00
Grégoire Paris
be8da83aca Merge pull request #10624 from simPod/deferrable
feat: allow setting foreign key as deferrable
2025-03-23 10:09:10 +01:00
Grégoire Paris
f5ab687226 Merge pull request #11876 from greg0ire/address-reflfield-depr
Address deprecation of ClassMetadata::$reflFields
2025-03-19 15:53:29 +01:00
Grégoire Paris
742eead849 Merge pull request #11878 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-03-18 21:38:05 +01:00
Grégoire Paris
1072ea6db4 Merge pull request #11877 from greg0ire/iso-phpunit-config
Iso phpunit config
2025-03-18 20:41:25 +01:00
Grégoire Paris
baf2c60cc4 Use more similar PHPUnit configurations
The dev configuration and CI configuration should not diverge this much.
I do not think the current situation was intended. A difference that
remains after my changes is the bootstrap file, which in dev seems aimed
at helping contributors setup their environment.
2025-03-18 20:08:09 +01:00
Grégoire Paris
8e620cad40 Do not run CI jobs when changing dev PHPUnit file
This file is never used in the CI.
2025-03-18 20:08:09 +01:00
Grégoire Paris
f98e871913 Address deprecation of ClassMetadata::$reflFields
We should use the newly introduced ClassMetadata::$propertyAccessors instead.
See https://github.com/doctrine/orm/pull/11659
2025-03-18 19:39:48 +01:00
Grégoire Paris
4b0c11978e Merge pull request #11875 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-03-18 14:25:17 +01:00
Grégoire Paris
daf0f82884 Merge pull request #11874 from doctrine/2.20.x
Merge 2.20.x up into 3.3.x
2025-03-18 13:52:20 +01:00
Stefan Gehrig
067ad51b3f fixes sqlite sql inconsistency 2025-03-17 08:48:30 +01:00
Grégoire Paris
0ef5610a6c Merge pull request #11873 from beberlei/GH-11659-FollowUp1
Bugfix: Missed a spot using getUnderlyingReflector
2025-03-16 23:18:10 +01:00
Benjamin Eberlei
e29d0e977d Bugfix: Missed a spot using getUnderlyingReflector 2025-03-15 17:39:14 +01:00
Stefan Gehrig
00c77213fb fixes codesniffer violation 2025-03-15 09:42:21 +01:00
Matteo Beccati
3303cd3b5d Fix non-deterministic test (#11866) 2025-03-14 00:09:36 +01:00
Grégoire Paris
afcf91e839 Merge pull request #11863 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-7.2.2
Bump doctrine/.github from 7.2.1 to 7.2.2
2025-03-10 09:24:12 +01:00
dependabot[bot]
c61a9b3b6d Bump doctrine/.github from 7.2.1 to 7.2.2
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 7.2.1 to 7.2.2.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/7.2.1...7.2.2)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-03-10 06:43:02 +00:00
Grégoire Paris
bd0509a064 Merge pull request #11825 from eltharin/bug_arg_order
FIX - nested dto's doesn't have arguments in good order and Dto with only objects bug
2025-03-05 15:38:16 +01:00
Stefan Gehrig
c68b8f90b3 adds a test for postgres that uses a HIDDEN result variable for ordering based on arithmetic expression 2025-03-05 09:28:52 +01:00
Stefan Gehrig
aa4f9ce9e9 CS fix based on PHP_CodeSniffer report 2025-03-05 09:22:57 +01:00
Grégoire Paris
d540f73778 Merge pull request #11659 from beberlei/PropertyHooks
Necessary refactorings for Property hooks
2025-02-27 20:04:08 +01:00
Stefan Gehrig
d96fc23327 skips tests when running on postgres 2025-02-27 10:30:21 +01:00
Benjamin Eberlei
201d751a26 Allow access to underlying reflector for property accessor. 2025-02-26 00:48:30 +01:00
Benjamin Eberlei
6308b2fd86 Update tests/Tests/ORM/Mapping/PropertyAccessors/ReadOnlyAccessorTest.php
Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2025-02-26 00:38:41 +01:00
Benjamin Eberlei
8f99e84438 Update src/Mapping/PropertyAccessors/EnumPropertyAccessor.php
Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2025-02-26 00:34:12 +01:00
Benjamin Eberlei
e36b7755e9 Houskeeping: phpcs 2025-02-23 19:43:26 +01:00
Benjamin Eberlei
7b4d869b31 Merge branch '3.4.x' into PropertyHooks 2025-02-23 19:23:20 +01:00
eltharin
708bd84fe2 fix bugs
nested dto are not in good argument order
dto with only dto does'nt work
2025-02-21 10:35:19 +01:00
Louis-Arnaud
3aed6912a3 Update ORMInvalidArgumentException.php
update message to use attribute instead of annotation
2025-02-21 10:10:22 +01:00
Gerhard Seidel
4fb044d5f6 fix: cs 2025-02-20 10:01:35 +08:00
Grégoire Paris
8873109b4f Merge pull request #11840 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-02-18 23:12:40 +01:00
Grégoire Paris
36bef3f959 Merge pull request #11839 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2025-02-18 22:42:29 +01:00
Grégoire Paris
980ccc58dc Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2025-02-18 21:40:58 +01:00
Grégoire Paris
62ca4624a9 Merge pull request #11837 from greg0ire/restore-exception
Restore logic exception
2025-02-17 20:39:14 +01:00
Grégoire Paris
1aed318b7b Restore logic exception
This exception was dropped by mistake during a merge-up, and should be
present until Doctrine officially supports property hooks.
2025-02-17 19:17:20 +01:00
David Buchmann
8ce7b310c5 document how to work with generated columns 2025-02-17 15:06:18 +01:00
Gerhard Seidel
2a953c5e2b fix: PrePersistEventTest and cs 2025-02-17 14:01:08 +08:00
Benjamin Eberlei
5077ae41e5 Housekeeping 2025-02-15 23:25:34 +01:00
Benjamin Eberlei
8e1a27b8cc Explain deprecation in UPGRADE.md 2025-02-15 22:32:16 +01:00
Benjamin Eberlei
e7db1b005f Add ReadOnlyAccessorTest 2025-02-15 22:17:29 +01:00
Benjamin Eberlei
72ce662e45 Tests for ObjectCastPropertyAccessor and RawValuePropertyAccessor. 2025-02-15 22:09:36 +01:00
Benjamin Eberlei
673cf0d4d8 Add test for ObjectCastPropertyAccessor. 2025-02-15 21:45:01 +01:00
Benjamin Eberlei
1cae0534a0 Extract PropertyAccessorFactory, tests for enum and typednodefault accessors. 2025-02-15 21:38:09 +01:00
Benjamin Eberlei
6fb3083f63 Merge remote-tracking branch 'beberlei/PropertyHooks' into PropertyHooks 2025-02-15 00:02:45 +01:00
Benjamin Eberlei
68c17ca1bd Merge remote-tracking branch 'origin/3.4.x' into PropertyHooks 2025-02-15 00:01:50 +01:00
Benjamin Eberlei
82cf29407c Update src/Mapping/PropertyAccessors/PropertyAccessor.php
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2025-02-15 00:01:22 +01:00
Gerhard Seidel
abc6a40ccb fix: calling scheduleForInsert twice
If scheduleForInsert was called in prePersist hook already, then persistNew need to check this case first, otherwise a ORMInvalidArgumentException will be thrown
2025-02-14 12:45:13 +08:00
Grégoire Paris
158605bf24 Merge pull request #11833 from HypeMC/fix-dql
Fix DQL example with composite key
2025-02-13 23:49:22 +01:00
Grégoire Paris
2c2ef65817 Merge pull request #11826 from aprat84/gh-11741
Clone query hints and parameters in `LimitSubqueryOutputWalker` constructor
2025-02-12 08:52:33 +01:00
Gregor Harlan
f8fdeaf41e UPGRADE.md: fix typo (#11832) 2025-02-12 00:10:14 +01:00
HypeMC
1c33a86983 Fix DQL example with composite key 2025-02-11 16:10:59 +01:00
Albert Prat
310fe1cccb Clone query hints and parameters in LimitSubqueryOutputWalker constructor
This fixes a bug that arises when using Pagination and an entity relation is mapped with fetch-mode EAGER but setFetchMode LAZY (or anything that is not EAGER) has been used on the query. If the query use WITH condition, an exception is incorrectly raised (Associations with fetch-mode=EAGER may not be using WITH conditions).
The class LimitSubqueryOutputWalker clones the query, but not its parameters and hints, so the generated subquery does not know that fetch-mode has been overridden.

Fixes #11741
2025-02-11 10:48:14 +01:00
Grégoire Paris
a67f677747 Merge pull request #11707 from jorenMartens/2.20.x
[DDC-551] fix, add filter support in oneToOne relation 2.20.x
2025-02-07 08:23:53 +01:00
Grégoire Paris
ae74be5e9d Merge pull request #11823 from doctrine/3.3.x-merge-up-into-3.4.x_lzhu6IBq
Merge release 3.3.2 into 3.4.x
2025-02-05 08:08:57 +01:00
Grégoire Paris
c9557c588b Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2025-02-04 20:43:15 +01:00
Grégoire Paris
73e68f3c7d Merge pull request #11821 from doctrine/2.20.x-merge-up-into-2.21.x_8O8nHxqC
Merge release 2.20.2 into 2.21.x
2025-02-04 20:24:01 +01:00
Grégoire Paris
19912de927 Merge pull request #11820 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-7.2.1
Bump doctrine/.github from 7.1.0 to 7.2.1
2025-02-04 20:17:01 +01:00
dependabot[bot]
737cca5b78 Bump doctrine/.github from 7.1.0 to 7.2.1
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 7.1.0 to 7.2.1.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/7.1.0...7.2.1)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-02-04 18:23:54 +00:00
Grégoire Paris
4163efd2f2 Merge pull request #11813 from VincentLanglet/queryType
[RFC] Expose QueryBuilder::getType
2025-01-29 11:54:45 +01:00
Vincent Langlet
d7ac6123ad Expose QueryType 2025-01-29 09:27:44 +01:00
Grégoire Paris
aff82af7de Merge pull request #11811 from greg0ire/quoteIdentifier-depr
Address quoteIdentifier() deprecation
2025-01-28 23:17:29 +01:00
Grégoire Paris
9e999ea1ff Merge pull request #11792 from dbannik/11783-failure-with-indexed-relation
11783 failure with indexed relation
2025-01-28 15:32:25 +01:00
Bob van de Vijver
6755bb0c7b Fix Hydration when use ManyToMany[indexBy]
The bug related (#11694) and fixed mapping of sql column alias to field in entity (#11783) and
invalidate cache [cache/persisted/entity|cache/persisted/collection] when sql filter changes
2025-01-27 15:35:59 +03:00
Alexander M. Turek
73777d0bd4 Merge branch '2.20.x' into 2.21.x
* 2.20.x:
  Introduce testNotListedValueInEnumArray
  Fix documentation for JoinColumn nullable (#11798)
  Ignore deprecations from doctrine/common
  Fix fields of transient classes being considered duplicate with `reportFieldsWhereDeclared`
2025-01-26 19:56:20 +01:00
Simon Podlipsky
bd260d1be8 feat: allow setting foreign key as deferrable 2025-01-26 13:06:55 +01:00
Grégoire Paris
aa141bf001 Address quoteIdentifier() deprecation
We should be using quoteSingleIdentifier(), assuming we only ever pass
single identifiers here.

See https://github.com/doctrine/dbal/pull/6590
2025-01-26 12:01:14 +01:00
Grégoire Paris
cd1a52c7e4 Merge pull request #11808 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2025-01-25 11:29:59 +01:00
Grégoire Paris
cf39e00553 Merge pull request #11807 from greg0ire/display-deprecations
Display Doctrine deprecations when running PHPUnit
2025-01-25 11:09:40 +01:00
Grégoire Paris
27b47841be Display Doctrine deprecations when running PHPUnit
This will give a signal that there is work to be done without blocking
other contributions by failing the build.
2025-01-25 10:53:36 +01:00
Grégoire Paris
c2a49327a7 Merge pull request #11799 from HypeMC/enum-array-error
Fix invalid enum value in array of enums
2025-01-22 11:54:59 +01:00
Maxime COLIN
9bd7242376 Introduce testNotListedValueInEnumArray 2025-01-22 02:25:34 +01:00
pawel-slowik
fff085b63f Fix documentation for JoinColumn nullable (#11798)
Nullability is not inherited from the PHP type. The change that enabled
this feature was reversed in https://github.com/doctrine/orm/pull/8732.
2025-01-22 00:12:00 +01:00
Grégoire Paris
5ad5b11ae1 Merge pull request #11769 from HypeMC/fix-reportfieldswheredeclared
Fix fields of transient classes being considered duplicate with `reportFieldsWhereDeclared`
2025-01-20 23:48:32 +01:00
Grégoire Paris
c12fd2cb94 Merge pull request #11793 from greg0ire/doctrine-common-support
Ignore deprecations from doctrine/common
2025-01-18 22:29:13 +01:00
Grégoire Paris
44d5d4a779 Ignore deprecations from doctrine/common
These new issues are caused by doctrine/common 3.5.0, released 2 weeks
ago.
2025-01-17 08:33:24 +01:00
Grégoire Paris
5a599233c9 Merge pull request #11791 from jonnyeom/patch-2
UPGRADE: Document QueryBuilder::setParameters() Type enforcement
2025-01-17 07:55:07 +01:00
Jonny Eom
596da353c2 UPGRADE: Document QueryBuilder::setParameters() Type enforcement 2025-01-16 17:14:20 +01:00
Alexander M. Turek
0d2cb6acd1 Fix CS (#11782) 2025-01-07 09:53:43 +01:00
Stefan Gehrig
ec6d1b9f72 fixes whitespace
Signed-off-by: Stefan Gehrig <stefan.gehrig.hn@googlemail.com>
2025-01-07 08:51:19 +01:00
Stefan Gehrig
d809fed52a fixes code sniffer complaints
Signed-off-by: Stefan Gehrig <stefan.gehrig.hn@googlemail.com>
2025-01-07 08:48:42 +01:00
Alexander M. Turek
327418a4b7 Merge branch '3.3.x' into 3.4.x
* 3.3.x:
  Update working-with-objects.rst (#7553)
  changed confusing negative wording (#11775)
2025-01-06 20:51:29 +01:00
Stefan Gehrig
0e4786dfa8 adds testcases for order by items enclosed in ((...)) (double brackets - just one bracket does not work)
just one bracket (...) gives

Exception : [Doctrine\ORM\Query\QueryException] [Syntax Error] line 0, col xx: Error: Expected Doctrine\ORM\Query\Lexer::T_IDENTIFIER, got '('
2025-01-03 10:45:08 +01:00
Stefan Gehrig
c429262f02 adds detection of literals/result variables at the beginning of an order by item with arithmetic expression
Not sure whether this covers the whole problem regarding complex expressions in order by items but it fixes the provided test cases
2025-01-03 10:45:07 +01:00
Stefan Gehrig
f4fdcbcdcb adds more test cases 2025-01-03 10:44:17 +01:00
Stefan Gehrig
b0806469d5 adds test case for GH issue #8011 2025-01-03 10:44:17 +01:00
Jamie Purchase
68c87740aa Update working-with-objects.rst (#7553)
Spelling.
2025-01-02 00:25:25 +01:00
Florian Sylvain
55dc02c39f changed confusing negative wording (#11775) 2024-12-31 00:09:28 +01:00
Grégoire Paris
9f2b367081 Merge pull request #11776 from curry684/issue-9558
Respect referencedColumnName defaults in custom naming strategies
2024-12-25 00:20:07 +01:00
Niels Keurentjes
a9873c86bb Take hardcoded reference column name out of JoinColumn attribute
Previously, when using a custom naming strategy, explicitly declaring a JoinColumn required specifying the referencedColumnName always as it would default to id no matter the naming strategy. This PR changes it to be determines correctly.

Ref #9558
2024-12-23 19:44:56 +01:00
Grégoire Paris
8ebd98ee92 Merge pull request #11773 from doctrine/3.3.x-merge-up-into-3.4.x_xx7XyUCl
Merge release 3.3.1 into 3.4.x
2024-12-19 08:27:07 +01:00
Grégoire Paris
e89b58a13f Merge pull request #11771 from doctrine/2.20.x-merge-up-into-2.21.x_3Yg2ZYgM
Merge release 2.20.1 into 2.21.x
2024-12-19 08:16:04 +01:00
Grégoire Paris
b1f8253105 Merge pull request #11772 from doctrine/2.20.x
Merge 2.20.x up into 3.3.x
2024-12-19 08:08:14 +01:00
Grégoire Paris
e3cabade99 Merge pull request #11768 from pbreteche/HINT_READ_ONLY-use-its-boolean-value
Check hint value before considering instance read-only
2024-12-19 07:48:36 +01:00
HypeMC
9402f9e0f7 Fix docs examples for mappings overrides (#11770) 2024-12-18 20:41:44 +01:00
HypeMC
4feaa470af Fix fields of transient classes being considered duplicate with reportFieldsWhereDeclared 2024-12-18 15:42:12 +01:00
Pierre Bretéché
4a9101f383 Check hint value before considering instance read-only
This fixes a bug that occurs when calling setHint(Query::HINT_READ_ONLY, false) from a query object.
UnitOfWork checks if this hint exists without considering the value passed as second argument.
Handling the second parameter improves consistency with documentation.
https://www.doctrine-project.org/projects/doctrine-orm/en/2.20/reference/improving-performance.html#read-only-entities
2024-12-18 14:55:22 +01:00
Grégoire Paris
f91da5b950 Merge pull request #11767 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-7.1.0
Bump doctrine/.github from 6.0.0 to 7.1.0
2024-12-16 08:30:26 +01:00
dependabot[bot]
66f654d4e2 Bump doctrine/.github from 6.0.0 to 7.1.0
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 6.0.0 to 7.1.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/6.0.0...7.1.0)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-16 06:51:45 +00:00
Claudio Zizza
7b9c0d91f6 Create website schema validation workflow (#11763) 2024-12-12 23:43:08 +01:00
Grégoire Paris
53b51ae40e Merge pull request #11613 from alexander-schranz/patch-2
Add missing generated option to documentation
2024-12-11 19:51:14 +01:00
Alexander Schranz
95b0f5c328 Add missing generated option 2024-12-11 11:55:34 +01:00
Benjamin Eberlei
5a220078e9 Update PR with PHP Stan by fixing some and baselining other violations. 2024-12-08 21:11:41 +01:00
Grégoire Paris
2b94ec18b9 Merge pull request #11759 from doctrine/2.20.x
Merge 2.20.x up into 2.21.x
2024-12-08 14:33:31 +01:00
Grégoire Paris
a15543a2ce Merge pull request #11761 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2024-12-08 13:02:05 +01:00
Benjamin Eberlei
238fb74028 Add RawValuePropertyAccessor to see how it will look in 8.4, pre support for lazy objects. 2024-12-08 13:00:10 +01:00
Benjamin Eberlei
6ff2b130d3 Add comment to PropertyAccessor interface 2024-12-08 13:00:10 +01:00
Benjamin Eberlei
8c9bfca255 Fix wrong type, phpstan failure. 2024-12-08 13:00:10 +01:00
Benjamin Eberlei
c2a2386df9 suppress phpcs that cant be done 2024-12-08 13:00:10 +01:00
Benjamin Eberlei
2f98e11562 Remove last use of reflFields in core. 2024-12-08 13:00:10 +01:00
Benjamin Eberlei
073809cf5c Fixup EnumPropertyAccessor::toEnum 2024-12-08 13:00:10 +01:00
Benjamin Eberlei
e82690d256 More psalm to fix the errors. 2024-12-08 13:00:07 +01:00
Benjamin Eberlei
23c31aec51 Static analysis. 2024-12-08 12:57:19 +01:00
Benjamin Eberlei
622ba2dcc7 Mark all PropertyAccessor classes @internal. 2024-12-08 12:56:39 +01:00
Benjamin Eberlei
0c1cf853fc Address PHPStan issues. 2024-12-08 12:56:38 +01:00
Benjamin Eberlei
79d1f07fa2 Deprecate access to ClassMetadata::$reflFields. 2024-12-08 12:56:38 +01:00
Benjamin Eberlei
eba01f8d0e Style, missing getReflectionProperties()Property() that were renamed. 2024-12-08 12:56:38 +01:00
Benjamin Eberlei
bd292481bd Adjust test. 2024-12-08 12:56:38 +01:00
Benjamin Eberlei
fcc53b260f Use ClassMetadata::$propertyAccessors in all places. 2024-12-08 12:56:34 +01:00
Benjamin Eberlei
7d61a1e73f Fixes in LegacyReflectionFields. 2024-12-08 12:56:08 +01:00
Benjamin Eberlei
b3cffe2d12 Introduce LegacyReflectionFields abstraction, deriving from propertyAccessors at runtime. 2024-12-08 12:56:06 +01:00
Grégoire Paris
46c94e3729 Merge pull request #11760 from greg0ire/fix-merge-up
Run SA checks with PHP 8.4
2024-12-08 12:55:58 +01:00
Benjamin Eberlei
052c7d7698 Add all necessary accessors, adapting doctrine/persistence and ORM internal reflection properties. no tests. 2024-12-08 12:55:14 +01:00
Benjamin Eberlei
c2713adebc property hooks. 2024-12-08 12:55:10 +01:00
Grégoire Paris
4e01567816 Run tests with PHP 8.4
This change was accidentally dropped during a merge up.
2024-12-08 12:47:41 +01:00
Grégoire Paris
51a984be3d Merge pull request #11758 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2024-12-08 12:42:02 +01:00
Grégoire Paris
f7f3104451 Merge pull request #11755 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2024-12-08 12:16:15 +01:00
Grégoire Paris
a5c80a4c75 Provide XSD for phpcs file (#11752)
It unlocks autocompletion and validation in some IDEs.
2024-12-07 23:21:04 +01:00
Grégoire Paris
417444d4b5 Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2024-12-07 22:31:38 +01:00
Grégoire Paris
6fd26a3933 Order result (#11757)
This avoids a test flakyness observed when using PostgreSQL in the CI.
2024-12-07 22:07:23 +01:00
Grégoire Paris
8ef9253999 Upgrade to PHPStan 2 (#11756)
Some calls to assert() are no longer necessary.
2024-12-07 20:42:54 +01:00
Grégoire Paris
360b80afab Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2024-12-07 16:17:12 +01:00
Grégoire Paris
2a662149f4 Merge pull request #11754 from doctrine/2.20.x
Merge 2.20.x up into 2.21.x
2024-12-07 15:39:29 +01:00
Grégoire Paris
0ed0be089c Run static analysis checks on PHP 8.4 (#11753)
* Run static analysis checks on PHP 8.4

* Remove forgotten references to Psalm

* Remove invalid annotation

I do not think it achieves anything.
2024-12-07 13:36:37 +01:00
Grégoire Paris
8fb1043e96 Merge pull request #11704 from beberlei/DropPsalm-2.20
Drop Psalm
2024-12-07 12:43:18 +01:00
Benjamin Eberlei
fd041fbe80 Drop Psalm 2024-12-07 12:29:58 +01:00
Grégoire Paris
6007154484 Merge pull request #11746 from greg0ire/3.4.x
Merge 2.21.x up into 3.4.x
2024-12-04 07:52:51 +01:00
Grégoire Paris
22ce0aff37 Merge remote-tracking branch 'origin/2.21.x' into 3.4.x 2024-12-03 23:44:05 +01:00
Grégoire Paris
5d73458f0b Merge pull request #11745 from greg0ire/3.4.x
Merge 3.3.x up into 3.4.x
2024-12-03 23:43:43 +01:00
Grégoire Paris
6c70d11f4e Merge remote-tracking branch 'origin/3.3.x' into 3.4.x 2024-12-03 23:04:46 +01:00
Grégoire Paris
eadf96c879 Merge pull request #11743 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-6.0.0
Bump doctrine/.github from 5.3.0 to 6.0.0
2024-12-02 08:07:33 +01:00
dependabot[bot]
0d770c89d6 Bump doctrine/.github from 5.3.0 to 6.0.0
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 5.3.0 to 6.0.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/5.3.0...6.0.0)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-12-02 06:07:53 +00:00
Grégoire Paris
0a635c1ece Merge pull request #11740 from doctrine/2.20.x
Merge 2.20.x up into 3.3.x
2024-11-28 08:53:49 +01:00
Grégoire Paris
37051d57ce Merge pull request #11739 from doctrine/2.20.x
Merge 2.20.x up into 2.21.x
2024-11-28 08:23:12 +01:00
Grégoire Paris
69a4199434 Merge pull request #11738 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2024-11-28 07:54:42 +01:00
Grégoire Paris
4bda5147f3 Merge pull request #11736 from greg0ire/avoid-coverage-upload
Avoid coverage upload for merge up pull requests
2024-11-28 07:54:05 +01:00
Grégoire Paris
cbda7e2322 Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2024-11-27 22:27:07 +01:00
Grégoire Paris
4563f2f9a7 Merge pull request #11737 from doctrine/2.20.x
Merge 2.20.x up into 2.21.x
2024-11-27 22:10:21 +01:00
Grégoire Paris
38c6569645 Avoid coverage upload for merge up pull requests
When there are no conflicts between branches, we create pull requests
where the head branch is a branch on the origin repository. That branch
points to a commit that should already have coverage information
provided by the build that happens after merging a regular pull request.

The thing is, coverage information provided by builds that happen before
merging a pull request are associated with the commit of the head
repository. This means that when merging up 1.2 into 1.3, the build
produces coverage information that is the result of a merge between 1.2
and 1.3, and associates it with 1.2, although it is run on with a
codebase that is much closer to 1.3 (and is in fact supposed to become
1.3 after the merge).

This means that when we create a merge up PR from 1.2 to anything else,
the coverage information is going to be wrong until a PR targeting 1.2
gets merged.

I do not think we need coverage about conflictless merge up PRs more
than we need accurate numbers, so I propose we disable the upload for
those instead of, say, trying to associate them with the temporary merge
commit.
2024-11-27 21:39:44 +01:00
Grégoire Paris
7c0eebe90a Merge pull request #11733 from doctrine/dependabot/github_actions/2.20.x/doctrine/dot-github-5.3.0
Bump doctrine/.github from 5.2.0 to 5.3.0
2024-11-25 09:11:24 +01:00
dependabot[bot]
8784f2bce9 Bump doctrine/.github from 5.2.0 to 5.3.0
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 5.2.0 to 5.3.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/5.2.0...5.3.0)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-25 06:38:50 +00:00
Grégoire Paris
fbcac42ebd Merge pull request #11732 from greg0ire/phpstan-lvl-7
Raise PHPStan level to 7
2024-11-24 23:44:33 +01:00
Grégoire Paris
619302dc9a Raise PHPStan level to 7
We have a plan to drop Psalm. Before we do that, let us ensure we run
PHPStan at the level we agreed upon during the Hackathon.
2024-11-24 21:50:03 +01:00
Grégoire Paris
50d7a0f95e Merge pull request #11727 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2024-11-23 22:01:13 +01:00
Grégoire Paris
d7f13a82ef Merge pull request #11726 from greg0ire/use-properties-minor
Use properties over array keys
2024-11-23 21:41:29 +01:00
Grégoire Paris
9e1038075e Merge pull request #11725 from greg0ire/use-properties
Use properties over array keys
2024-11-23 21:28:02 +01:00
Grégoire Paris
dd3604f523 Use properties over array keys
Using array access is deprecated.
2024-11-23 21:06:56 +01:00
Grégoire Paris
65e9f607e5 Use properties over array keys
Using array access is deprecated.
2024-11-23 21:05:10 +01:00
Grégoire Paris
a42134ccee Merge pull request #11724 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2024-11-23 20:43:44 +01:00
Grégoire Paris
71e038c81d Merge pull request #11723 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2024-11-23 19:56:58 +01:00
Grégoire Paris
91201c094a Merge pull request #11722 from doctrine/2.20.x
Merge 2.20.x up into 2.21.x
2024-11-23 19:35:45 +01:00
Grégoire Paris
2ff998da0e Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2024-11-23 19:31:41 +01:00
Grégoire Paris
82e2c981da Merge pull request #11556 from k00ni/patch-1
[Docs] unitofwork.rst: php => PHP
2024-11-19 13:07:44 +01:00
Konrad Abicht
8422a41423 unitofwork.rst: php => PHP 2024-11-19 13:06:17 +01:00
Grégoire Paris
58ad1d9678 Merge pull request #11709 from lyrixx/fix-event-doc
Fix `Events::onFlush` and `PostFlush()` documentation: events are always raised
2024-11-18 22:06:18 +01:00
Grégoire Pineau
346c49832c Fix Events::onFlush and PostFlush() documentation: events are always raised
see 9e2bfa8169/src/UnitOfWork.php (L399-L413)
2024-11-18 21:51:27 +01:00
Grégoire Paris
f140651ff0 Merge pull request #11719 from greg0ire/ignore-deprecation
Ignore deprecation about StaticReflectionService
2024-11-18 21:50:12 +01:00
Grégoire Paris
bb5b2a3300 Ignore deprecation about StaticReflectionService
It is from a class that is deprecated and removed in later branches.
2024-11-18 21:46:52 +01:00
Grégoire Paris
5013d5dbef Merge pull request #9760 from beberlei/GH-3519-UniqueDiscriminatorValues
[GH-3519] Deprecate passing the same class with different discriminator values.
2024-11-18 12:18:06 +01:00
Grégoire Paris
ba11851ac4 Merge pull request #11718 from doctrine/dependabot/github_actions/2.20.x/codecov/codecov-action-5
Bump codecov/codecov-action from 4 to 5
2024-11-18 08:42:38 +01:00
dependabot[bot]
4fbce94999 Bump codecov/codecov-action from 4 to 5
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4 to 5.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v4...v5)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-11-18 06:30:54 +00:00
Grégoire Paris
486e406236 Merge pull request #10065 from goetas/lazy-eager-collection-refresh
Lazy and eager collection refresh inconsistency
2024-11-14 23:43:20 +01:00
Asmir Mustafic
7d1b24f3b1 attempt a fix 2024-11-14 20:15:56 +01:00
Asmir Mustafic
43ce0bef78 lazy and eager collection refresh 2024-11-14 20:06:32 +01:00
Benjamin Eberlei
da51234d5a [GH-3519] Deprecate passing the same class with different discriminator values. 2024-11-14 08:34:48 +01:00
Grégoire Paris
d9aa6ef6dc Merge pull request #11716 from acasademont/patch-1
Add `isEmpty()` method to the Extra Lazy Associations tutorial
2024-11-14 08:03:31 +01:00
Albert Casademont
ff3ccff36a Add isEmpty() method to the Extra Lazy Associations tutorial
Extra lazy support for it was added a long time ago
(see https://github.com/doctrine/orm/pull/912) but was never properly
documented.
2024-11-13 23:59:12 +01:00
Mohamed Attia
4b03ec7789 Refine Explanations of Doctrine orm Package Structure (#11710)
* Update architecture.rst

* Update architecture.rst
2024-11-12 00:02:38 +01:00
Joren Martens
14866461c5 [DDC-551] fix, add filter support in oneToOne relation 2024-11-07 10:48:16 +01:00
Grégoire Paris
f41dc4a503 Merge pull request #11533 from greg0ire/persistence-4-compat
Implement compatibility with Persistence 4
2024-11-04 12:30:26 +01:00
Grégoire Paris
81c0d599c9 Implement compatibility with Persistence 4 2024-11-04 12:15:30 +01:00
Indra Gunawan
9e2bfa8169 Run tests against PostgreSQL 17 (#11697)
* Run tests against PostgreSQL 17

* remove pgsql 15
2024-10-25 14:57:39 +02:00
Grégoire Paris
44fa8bbde8 Merge pull request #11344 from d-ph/patch-2
Change the lock mode in the "Aggregate Fields" cookbook (aggregate-fields.rst) article.
2024-10-24 08:55:49 +02:00
Grégoire Paris
3ca9529c32 Merge pull request #11694 from dbannik/Bug-join-sql-when-change-sqlFilter-parameters
BUG: When changing SQLFilter parameter, resulting SQL query is not generated correctly
2024-10-23 21:23:17 +02:00
Dzmitry Bannik
439b4dacf4 Is not correctly generated sql when changed/switched sqlFilter parameters
CachedPersisterContext::$selectJoinSql should be clear or regenerated when sqlFilter changed
The problem reproduce when in use fetch=EAGER and use additional sql filter on this property
2024-10-23 12:02:03 +03:00
Grégoire Paris
05f54860f7 Merge pull request #11549 from doctrine/feature/allow-overriding-cascade
Allow overriding association's cascade
2024-10-22 19:51:34 +02:00
Jan Nedbal
021a9cce3d UPGRADE: mention SqlWalker deprecations in 3.3 (#11693) 2024-10-22 15:54:18 +02:00
Grégoire Paris
0f11a97c8e Merge pull request #11035 from kbond/feat/lazy-first
Make `PersistentCollection::first()` "extra" lazy
2024-10-21 11:28:22 +02:00
Kevin Bond
c9253ef64b feat: make PersistentCollection::first() "extra" lazy 2024-10-20 19:24:21 -04:00
Grégoire Paris
af54a1696c Merge pull request #11692 from greg0ire/inherit-issue-templates
Remove config.yml
2024-10-20 12:16:44 +02:00
Grégoire Paris
4d821cb139 Remove config.yml
It causes the template inheritance to fail.
2024-10-20 12:15:32 +02:00
Grégoire Paris
85fc95060f Merge pull request #11691 from greg0ire/inherit-issue-templates
Inherit issue templates
2024-10-20 12:15:05 +02:00
Grégoire Paris
039b03255a Inherit issue templates 2024-10-20 11:58:56 +02:00
Benjamin Eberlei
e7efdede15 Update README.md 2024-10-18 09:13:20 +02:00
Grégoire Paris
74155c8672 Merge pull request #11688 from doctrine/3.3.x
Merge 3.3.x up into 3.4.x
2024-10-16 23:44:13 +02:00
Grégoire Paris
a4a15ad243 Merge pull request #11687 from doctrine/2.20.x
Merge 2.20.x up into 2.21.x
2024-10-16 23:37:08 +02:00
Grégoire Paris
9c0e62ad44 Merge pull request #11686 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2024-10-16 23:16:09 +02:00
Grégoire Paris
94702d14b9 Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2024-10-16 23:02:36 +02:00
Grégoire Paris
5aad44cff6 Merge pull request #11685 from greg0ire/fix-merge-up
Remove YAML doc example
2024-10-16 23:00:52 +02:00
Grégoire Paris
182469b346 Fix copy/paste/adapt mistake (#11684)
The last step was missing.
2024-10-16 22:59:19 +02:00
Grégoire Paris
0893d8511e Remove YAML doc example
It was wrongly added during a merge up
2024-10-16 22:58:27 +02:00
Grégoire Paris
e47398ecc5 Remove leftovers from Sphinx (#11683)
We use phpDocumentor/guides now, no need for this.
2024-10-16 22:08:16 +02:00
Grégoire Paris
9e884ccf1f Merge pull request #11453 from MatteoFeltrin/allow-fqcn-in-value-attribute-of-discriminator-mapping
Allow classname in 'value' attribute of xml discriminator-mapping field
2024-10-16 08:06:49 +02:00
Alexander M. Turek
fac0899ef7 Tell dependabot to target 2.20.x (#11681) 2024-10-14 09:52:23 +02:00
Alexander M. Turek
d5c400e8d1 Remove annotations example 2024-10-14 09:32:55 +02:00
Alexander M. Turek
6648d68ddf Merge branch '2.20.x' into 3.3.x
* 2.20.x:
  Bump doctrine/.github from 5.1.0 to 5.2.0 (#11680)
  Psalm 5.26.1 (#11677)
  Update README (#11673)
  Fix PHPUnit deprecations
  Bump doctrine/.github from 5.1.0 to 5.2.0 (#11671)
  Experiment with literalinclude
2024-10-14 09:31:18 +02:00
dependabot[bot]
982d6060a3 Bump doctrine/.github from 5.1.0 to 5.2.0 (#11680) 2024-10-14 08:56:04 +02:00
Grégoire Paris
013f850c76 Merge pull request #11676 from derrabus/chore/phpunit-deprecations
Fix PHPUnit deprecations
2024-10-14 08:17:49 +02:00
Grégoire Paris
ef4508e52f Merge pull request #11667 from greg0ire/literalinclude
Experiment with literalinclude
2024-10-14 08:15:17 +02:00
Grégoire Paris
6dae89ce0d Merge pull request #11678 from derrabus/improvement/stale
Close stale pull requests
2024-10-14 08:14:36 +02:00
Alexander M. Turek
f53350934f Psalm 5.26.1 (#11677) 2024-10-13 22:04:07 +02:00
Alexander M. Turek
efaba02ef5 CI: Close stale pull requests 2024-10-13 21:55:29 +02:00
Grégoire Paris
4ff909044e Update README (#11673) 2024-10-13 21:45:35 +02:00
Alexander M. Turek
32682aa14d Fix PHPUnit deprecations 2024-10-13 21:17:33 +02:00
Alexander M. Turek
e9f3ca2a45 Drop DBAL 2 compat code (#11674) 2024-10-13 20:48:11 +02:00
Grégoire Paris
737aee7d98 Update branch metadata (#11672)
3.3.0 was just released.
2024-10-13 20:47:57 +02:00
dependabot[bot]
bd20df1043 Bump doctrine/.github from 5.1.0 to 5.2.0 (#11671) 2024-10-13 12:47:29 +02:00
Grégoire Paris
69958152e6 Merge pull request #11653 from beberlei/GH-8471-RevertPartialObjects2
[GH-8471] Undeprecate PARTIAL for objects in DQL
2024-10-12 22:07:18 +02:00
Benjamin Eberlei
cf8f5f9f93 Apply suggestions from code review
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2024-10-12 21:01:04 +02:00
Alexander M. Turek
60c245413d Auto-detect values for EnumType columns (#11666) 2024-10-12 17:35:44 +02:00
Benjamin Eberlei
7c9b74221f fix phpbench tests. 2024-10-12 16:31:02 +02:00
Grégoire Paris
2ec2030ab2 Experiment with literalinclude
I think it would be great to use literalinclude for big code snippets,
because our IDEs could warn us about issues, and it would be easily to
showcase our coding standard. Before we do that though, let us validate
that it renders as expected. I have picked a complex example where we
have a configuration block.
2024-10-12 15:46:50 +02:00
Benjamin Eberlei
c7e5605d11 Fix test 2024-10-12 15:43:46 +02:00
Benjamin Eberlei
c19afa1529 Merge 3.3.x 2024-10-12 15:42:38 +02:00
Benjamin Eberlei
516b593193 Fix phpcs 2024-10-12 15:41:31 +02:00
Benjamin Eberlei
e2b971d7c5 Merge branch '3.3.x' into GH-8471-RevertPartialObjects2 2024-10-12 15:40:18 +02:00
Grégoire Paris
19d9244a88 Merge pull request #11575 from eltharin/named_arguments
Allow named Arguments to be passed to Dto
2024-10-12 12:07:20 +02:00
Grégoire Paris
10a5a3ff73 Merge pull request #11665 from doctrine/3.2.x-merge-up-into-3.3.x_pbOwHc2w
Merge release 3.2.3 into 3.3.x
2024-10-12 11:58:33 +02:00
Benjamin Eberlei
f5fb400d0f Address review comments. 2024-10-12 02:32:15 +02:00
Grégoire Paris
a321331c89 Merge origin/2.20.x into 3.3.x (using imerge) 2024-10-11 22:11:52 +02:00
Grégoire Paris
522863116a Update branch metadata (#11663)
2.20.0 just got released
2024-10-11 20:23:33 +02:00
Benjamin Eberlei
5bfb744967 The MySQL/Maria EnumType added in DBAL 4.2 has a new known option "values". (#11657) 2024-10-11 15:29:19 +02:00
Grégoire Paris
8ed6c2234a Merge pull request #11661 from doctrine/2.19.x
Merge 2.19.x up into 2.20.x
2024-10-11 13:47:24 +02:00
Grégoire Paris
ff612b9678 Merge pull request #11660 from simPod/test-method
test: cover all transactional methods in `EntityManagerTest::testItPreservesTheOriginalExceptionOnRollbackFailure()`
2024-10-11 13:11:31 +02:00
Simon Podlipsky
ee0d7197dd test: cover all transactional methods in EntityManagerTest::testItPreservesTheOriginalExceptionOnRollbackFailure() 2024-10-11 13:00:52 +02:00
Matthias Pigulla
39d2136f46 Fix different first/max result values taking up query cache space (#11188)
* Add a test covering the #11112 issue

* Add new OutputWalker and SqlFinalizer interfaces

* Add a SingleSelectSqlFinalizer that can take care of adding offset/limit as well as locking mode statements to a given SQL query.

Add a FinalizedSelectExecutor that executes given, finalized SQL statements.

* In SqlWalker, split SQL query generation into the two parts that shall happen before and after the finalization phase.

Move the part that generates "pre-finalization" SQL into a dedicated method. Use a side channel in SingleSelectSqlFinalizer to access the "finalization" logic and avoid duplication.

* Fix CS violations

* Skip the GH11112 test while applying refactorings

* Avoid a Psalm complaint due to invalid (?) docblock syntax

* Establish alternate code path - queries can obtain the sql executor through the finalizer, parser knows about output walkers yielding finalizers

* Remove a possibly premature comment

* Re-enable the #11112 test

* Fix CS

* Make RootTypeWalker inherit from SqlOutputWalker so it becomes finalizer-aware

* Update QueryCacheTest, since first/max results no longer need extra cache entries

* Fix ParserResultSerializationTest by forcing the parser to produce a ParserResult of the old kind (with the executor already constructed)

* Fix WhereInWalkerTest

* Update lib/Doctrine/ORM/Query/Exec/PreparedExecutorFinalizer.php

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>

* Fix tests

* Fix a Psalm complaint

* Fix a test

* Fix CS

* Make the NullSqlWalker an instance of SqlOutputWalker

* Avoid multiple cache entries caused by LimitSubqueryOutputWalker

* Fix Psalm complaints

* Fix static analysis complaints

* Remove experimental code that I committed accidentally

* Remove unnecessary baseline entry

* Make AddUnknownQueryComponentWalker subclass SqlOutputWalker

That way, we have no remaining classes in the codebase subclassing SqlWalker but not SqlOutputWalker

* Use more expressive exception classes

* Add a deprecation message

* Move SqlExecutor creation to ParserResult, to minimize public methods available on it

* Avoid keeping the SqlExecutor in the Query, since it must be generated just in time (e. g. in case Query parameters change)

* Address PHPStan complaints

* Fix tests

* Small refactorings

* Add an upgrade notice

* Small refactorings

* Update the Psalm baseline

* Add a missing namespace import

* Update Psalm baseline

* Fix CS

* Fix Psalm baseline

---------

Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2024-10-10 15:15:08 +02:00
eltharin
c223b8f635 Allow named Arguments to be passed to Dto
Allow to change argument order or use variadic argument in dto constructor using new named keyword
2024-10-10 14:33:16 +02:00
Benjamin Eberlei
bea454eefc [GH-8471] undeprecate partials completly (#11647)
* [GH-8471] Undeprecate all PARTIAL object usage.
2024-10-10 13:54:34 +02:00
Grégoire Paris
14f2572e4e Merge pull request #11656 from doctrine/2.19.x
Merge 2.19.x up into 2.20.x
2024-10-10 13:53:05 +02:00
Grégoire Paris
c2c500077b Merge pull request #11646 from greg0ire/finally-fix-bug
Run risky code in finally block
2024-10-10 11:46:49 +02:00
Grégoire Paris
6281c2b79f Merge pull request #11655 from greg0ire/submodule-cleanup
Submodule cleanup
2024-10-10 11:12:12 +02:00
Grégoire Paris
bac1c17eab Remove submodule remnant
This should make a warning we have in the CI go away.

>  fatal: No url found for submodule path 'docs/en/_theme' in .gitmodules
2024-10-10 11:07:38 +02:00
Grégoire Paris
b6137c8911 Add guard clause
It maybe happen that the SQL COMMIT statement is successful, but then
something goes wrong. In that kind of case, you do not want to attempt a
rollback.

This was implemented in UnitOfWork::commit(), but for some reason not in
the similar EntityManager methods.
2024-10-10 10:58:24 +02:00
Benjamin Eberlei
da7854f586 Fix imports 2024-10-10 10:41:04 +02:00
Benjamin Eberlei
5f4ecfd1d8 Fix imports 2024-10-10 10:38:33 +02:00
Grégoire Paris
51be1b1d52 Run risky code in finally block
catch blocks are not supposed to fail. If you want to do something
despite an exception happening, you should do it in a finally block.

Closes #7545
2024-10-10 10:06:12 +02:00
Alexander M. Turek
5f39343bfd Merge branch '2.20.x' into 3.3.x
* 2.20.x:
  Remove vendor prefix of PHPDoc referencing class-string (#11643)
  Deprecate the `\Doctrine\ORM\Query\Parser::setCustomOutputTreeWalker()` method (#11641)
2024-10-09 22:37:30 +02:00
Benjamin Eberlei
7ef1f0a379 Phpcs fixes 2024-10-09 22:14:01 +02:00
Alexander M. Turek
488a5dd3bf Remove vendor prefix of PHPDoc referencing class-string (#11643) 2024-10-09 21:58:37 +02:00
Alexander M. Turek
30795559dc Merge branch '2.20.x' into 3.3.x
* 2.20.x:
  Stop recommending vendor-prefixed PHPDoc (#11640)
  Let PHPStan detect deprecated usages (#11639)
  Add upgrade note about property hooks (#11636)
  Prepare PHP 8.4 support: Prevent property hooks from being used (#11628)
  Use E_ALL instead of E_ALL | E_STRICT
  Add CI job for PHP 8.4
  fix generating duplicate method stubs
2024-10-09 21:32:07 +02:00
Benjamin Eberlei
f71725575c Revert undprecate PARTIAL for objects in DQL. 2024-10-09 17:34:59 +02:00
Benjamin Eberlei
4a3c7f05bf Revert "Remove unused exception"
This reverts commit 689da1f251.
2024-10-09 17:13:58 +02:00
Matthias Pigulla
896c65504d Deprecate the \Doctrine\ORM\Query\Parser::setCustomOutputTreeWalker() method (#11641)
We use this method only from within one of our own test cases, and I don't see how it would be useful to anybody else outside – it has to be called on the `Parser` instance which exists internally in the `Query` only.

Deprecating and removing it in 3.x allows for a slight simplification in the `Parser` there, since we do no longer need the field (it can be a local variable).
2024-10-09 16:12:41 +02:00
Matthias Pigulla
16a8f10fd2 Remove a misleading comment (#11644) 2024-10-09 15:37:04 +02:00
Alexander M. Turek
498de4c564 Merge branch '3.2.x' into 3.3.x
* 3.2.x:
  PHPStan 1.12.6 (#11635)
2024-10-09 15:06:48 +02:00
Alexander M. Turek
d80a831157 Stop recommending vendor-prefixed PHPDoc (#11640) 2024-10-09 14:48:42 +02:00
Alexander M. Turek
52660297ab Let PHPStan detect deprecated usages (#11639) 2024-10-09 14:47:57 +02:00
Alexander M. Turek
b44774285b Merge branch '2.19.x' into 3.2.x
* 2.19.x:
  PHPStan 1.12.6 (#11635)
2024-10-09 11:09:19 +02:00
Alexander M. Turek
58287bb731 Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  PHPStan 1.12.6 (#11635)
2024-10-09 11:08:42 +02:00
Alexander M. Turek
bc37f75b41 PHPStan 1.12.6 (#11635) 2024-10-09 11:08:02 +02:00
Grégoire Paris
8a25b264f7 Add upgrade note about property hooks (#11636)
People that might have experimented with property hooks while still
using ORM < 2.20.0 need to know that they need to remove their
experiment or upgrade to a version that explicitly supports them.
2024-10-09 11:05:58 +02:00
Benjamin Eberlei
0e48b19cd3 Prepare PHP 8.4 support: Prevent property hooks from being used (#11628)
Prevent property hooks from being used as they currently would work on external non-raw values without explicit code.
2024-10-09 10:36:21 +02:00
Grégoire Paris
d2978303f0 Merge remote-tracking branch 'origin/3.2.x' into 3.3.x 2024-10-09 10:13:04 +02:00
Grégoire Paris
109042e5af Merge pull request #11631 from greg0ire/php84-ci
Add CI job for PHP 8.4
2024-10-09 09:42:08 +02:00
Grégoire Paris
08328adc6c Use E_ALL instead of E_ALL | E_STRICT
E_STRICT is deprecated as of PHP 8.4
2024-10-09 09:19:32 +02:00
Grégoire Paris
191a5366b1 Merge pull request #11629 from greg0ire/3.2.x
Merge 2.19.x up into 3.2.x
2024-10-08 17:57:30 +02:00
Grégoire Paris
65806884b0 Add CI job for PHP 8.4
For now doctrine/common generates proxies that trigger deprecation, so
let us only test with lazy ghosts only.
2024-10-08 17:56:38 +02:00
Alexander M. Turek
ad80e8281a Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  Replace custom directives with native option
2024-10-08 15:54:57 +02:00
Grégoire Paris
44dddb2eee Merge remote-tracking branch 'origin/2.19.x' into 3.2.x 2024-10-08 15:37:53 +02:00
Grégoire Paris
0c0c61c51b Merge pull request #11627 from greg0ire/no-custom-directives
Replace custom directives with native option
2024-10-08 15:26:44 +02:00
Grégoire Paris
cc28fed9f5 Replace custom directives with native option 2024-10-08 14:43:18 +02:00
Alexander M. Turek
2245149588 Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  Make nullable parameters explicit in generated entities (#11625)
  Update attributes-reference.rst
  Bump doctrine/.github from 5.0.1 to 5.1.0 (#11616)
  Move orphan metadata to where it belongs
  PHPStan 1.12 (#11585)
2024-10-08 12:26:50 +02:00
Alexander M. Turek
b13564c6c0 Make nullable parameters explicit in generated entities (#11625) 2024-10-08 12:25:31 +02:00
Max Mustermann
91709c1275 fix generating duplicate method stubs
When adding the same lifecycle event callback to two or more lifecycle events, the generator will create a stub for each event resulting in fatal 'Cannot redeclare' errors. That is, only if the callback name contains uppercase letters.
2024-10-05 13:40:04 +02:00
Grégoire Paris
434b7cee2a Merge pull request #11619 from eltharin/change_EBNF
add nested new in EBNF documentation
2024-10-04 18:53:50 +02:00
eltharin
7f0a181e39 add nested new in EBNF documentation 2024-10-02 09:48:08 +02:00
Grégoire Paris
d18126aac5 Merge pull request #11618 from n0099/patch-1
unclosed `]` in attributes-reference.rst
2024-10-01 17:27:04 +02:00
n0099
b7fd8241cf Update attributes-reference.rst 2024-10-01 21:19:44 +08:00
dependabot[bot]
2432939e4f Bump doctrine/.github from 5.0.1 to 5.1.0 (#11616)
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 5.0.1 to 5.1.0.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/5.0.1...5.1.0)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-30 09:04:06 +02:00
Grégoire Paris
93ce84fa6e Merge pull request #11614 from greg0ire/guides-as-dep
Guides as dev dependency
2024-09-29 09:23:14 +02:00
Grégoire Paris
1bf4603422 Merge pull request #11615 from greg0ire/move-orphan
Move orphan metadata to where it belongs
2024-09-29 09:22:54 +02:00
Grégoire Paris
e6961bd968 Install guides-cli as a dev requirement
It is better if contributors can check the docs by themselves.
2024-09-27 19:44:34 +02:00
Grégoire Paris
25d5bc5b46 Move orphan metadata to where it belongs
The goal here was to retain compatibility with doctrine/rst-parser,
which is no longer in use in the website.
2024-09-27 19:42:13 +02:00
Grégoire Paris
5724e6279e Merge pull request #11596 from doctrine/3.2.x
Merge 3.2.x up into 3.3.x
2024-09-05 22:03:08 +02:00
Alexander M. Turek
cfc0655a1c Fix compatibility with DBAL 4.2 (#11592) 2024-09-03 18:44:06 +02:00
Alexander M. Turek
6cde337777 PHPStan 1.12 (#11585) 2024-08-27 12:10:07 +02:00
Vincent Langlet
c6b2d89748 Precise EntityRepository::count (#11579) 2024-08-24 07:29:36 +02:00
Grégoire Paris
e1dc94d1c2 Merge pull request #11583 from doctrine/3.2.x-merge-up-into-3.3.x_lYlOLiIT
Merge release 3.2.2 into 3.3.x
2024-08-23 12:31:30 +02:00
Grégoire Paris
74ef28295a Merge pull request #11582 from doctrine/2.19.x-merge-up-into-2.20.x_0oKsBvVN
Merge release 2.19.7 into 2.20.x
2024-08-23 12:29:43 +02:00
Grégoire Paris
831a1eb7d2 Merge pull request #11581 from greg0ire/3.2.x
Merge 2.19.x up into 3.2.x
2024-08-23 12:03:52 +02:00
Grégoire Paris
3a82b153f3 Merge remote-tracking branch 'origin/2.19.x' into 3.2.x 2024-08-23 09:07:18 +02:00
Grégoire Paris
168ac31084 Merge pull request #11109 from mcurland/Fix11108
Original entity data resolves inverse 1-1 joins
2024-08-23 08:54:57 +02:00
Grégoire Paris
6f93cebe6e Merge pull request #11576 from eltharin/newnestedDto
Re: Re: Add support for using nested DTOs
2024-08-19 22:52:53 +02:00
eltharin
8c582a49d3 Add support for using nested DTOs
This feature allow use of nested new operators

Co-authored-by: Tomas Norkūnas <norkunas.tom@gmail.com>
Co-authored-by: Sergey Protko <fesors@gmail.com>
Co-authored-by: Łukasz Zakrzewski <contact@lzakrzewski.com>

Update docs/en/reference/dql-doctrine-query-language.rst

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2024-08-19 22:36:10 +02:00
Grégoire Paris
5f1fe1587c Merge pull request #11557 from d-ph/feature/make-count-walker-use-count-star-query-sometimes
Make CountWalker use COUNT(*) when $distinct is explicitly set to false (#11552)
2024-08-19 22:31:49 +02:00
Matthew Curland
fe4a2e83cf Original entity data resolves inverse 1-1 joins
If the source entity for an inverse (non-owning) 1-1 relationship is
identified by an association then the identifying association may not
be set when an inverse one-to-one association is resolved. This means
that no data is available in the entity to resolve the needed column
value for the join query.

The original entity data can be retrieved from the unit of work and
is used as a fallback to populate the query condition.

Fixes #11108
2024-08-17 11:50:56 +02:00
Grégoire Paris
205b2f5f20 Merge pull request #11550 from janedbal/patch-1
DQL custom functions: document TypedExpression
2024-08-09 22:50:14 +02:00
Jan Nedbal
3f550c19e3 DQL custom functions: document TypedExpression
Partially related to https://github.com/doctrine/orm/issues/11537

Co-authored-by: Claudio Zizza <859964+SenseException@users.noreply.github.com>
2024-08-06 09:16:45 +02:00
Grégoire Paris
8ac6a13ca0 Merge pull request #11564 from gitbugr/GH11501_fix_o2m_persister_single_inheritence_parent_relation_bugfix
GH11551 - fix OneToManyPersister::deleteEntityCollection case where single-inheritence table parent entity is targetEntity.
2024-08-05 07:47:46 +02:00
gitbugr
2707b09a07 fix spacing
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2024-08-03 21:38:49 +01:00
Kyron Taylor
121158f92c GH11551 - fix OneToManyPersister::deleteEntityCollection when using
single-inheritence entity parent as targetEntity.

When using the parent entity for a single-inheritence table as the
targetEntity for a property, the discriminator value should be all
of the values in the discriminator map.
OneToManyPersister::deleteEntityCollection has been amended to
reflect this.
2024-08-03 16:55:14 +01:00
Marc Eichenseher
56cd688c4a Remove unused $pkColumns when gathering columns (#11560) 2024-08-02 01:01:23 +02:00
Grégoire Paris
96546caceb Merge pull request #11365 from beberlei/ReintroducePartialForArrayHydration
Reintroduce PARTIAL, but only for non-object hydration.
2024-07-24 09:28:05 +02:00
d-ph
57247ed6ca Make CountWalker use COUNT(*) when $distinct is explicitly set to false (#11552)
This change makes CountWalker use COUNT(*) instead of
COUNT(tbl.id), when the user declared that their query
does not need to use (SELECT) DISTINCT, which is
commonly the case when there are no JOINs in the query,
or when the JOINs are only *ToOne.

Research showed that COUNT(*) allows databases to use
index(-only) scans more eagerly from any of the
indexed columns, especially when the query is using
a WHERE-condition that filters on an indexed column.
2024-07-22 10:22:51 +01:00
Grégoire Paris
12817076c3 Merge pull request #11528 from norkunas/namedparams
Add `createNamedParameter` to `QueryBuilder`
2024-07-11 23:53:20 +02:00
Maciej Malarz
129553da90 Allow overriding association's cascade 2024-07-11 11:50:04 +02:00
Grégoire Paris
4c2f104d42 Merge pull request #11547 from greg0ire/3.3.x
Merge 2.20.x up into 3.3.x
2024-07-10 09:00:45 +02:00
Grégoire Paris
ef64cf7c33 Merge remote-tracking branch 'origin/2.20.x' into 3.3.x 2024-07-10 08:57:09 +02:00
Tomas
0983d3a4af Add createNamedParameter to QueryBuilder 2024-07-08 06:54:02 +03:00
Grégoire Paris
51ad860a25 Merge pull request #11543 from stof/fix_native_query_parameter_type
Fix the support for custom parameter types in native queries
2024-07-04 20:12:59 +02:00
Christophe Coevoet
9bd51aaeb6 Fix the support for custom parameter types in native queries
The Query class (used for DQL queries) takes care of using the value and
type as is when a type was specified for a parameter instead of going
through the default processing of values.
The NativeQuery class was missing the equivalent check, making the
custom type work only if the default processing of values does not
convert the value to a different one.
2024-07-04 16:25:34 +02:00
Xesau
1fe1a6a048 Fix incorrect exception message for ManyToOne attribute in embeddable class (#11536)
When a ManyToOne attribute is encountered on an Embeddable class, the exception message reads "Attribute "Doctrine\ORM\Mapping\OneToMany" on embeddable [class] is not allowed.". This should be "Doctrine\ORM\Mapping\ManyToOne" on embeddable [class] is not allowed.".
2024-07-01 21:57:36 +02:00
Grégoire Paris
c37b115450 Merge pull request #11534 from k00ni/patch-1
working-with-objects.rst: added missing white space
2024-06-28 09:03:54 +02:00
Konrad Abicht
19129e9f8a working-with-objects.rst: added missing white space 2024-06-28 09:00:12 +02:00
Grégoire Paris
efe62e3f0b Merge pull request #11532 from doctrine/3.2.x-merge-up-into-3.3.x_ws8Fgk2X
Merge release 3.2.1 into 3.3.x
2024-06-27 17:57:03 +02:00
Grégoire Paris
7d01f19667 Merge pull request #11531 from doctrine/2.19.x-merge-up-into-2.20.x_QMtlHSin
Merge release 2.19.6 into 2.20.x
2024-06-27 17:50:50 +02:00
Grégoire Paris
722cea6536 Merge pull request #11525 from greg0ire/3.2.x
Merge 2.19.x up into 3.2.x
2024-06-26 23:48:58 +02:00
Grégoire Paris
c1bb2ccf4b Merge pull request #11526 from GromNaN/patch-1
doc: Use modern array syntax in getting started
2024-06-26 19:24:40 +02:00
Jérôme Tamarelle
e3d7c6076c Use modern array syntax in the doc 2024-06-26 19:18:32 +02:00
Grégoire Paris
ce7d93f14d Merge remote-tracking branch 'origin/2.19.x' into 3.2.x 2024-06-26 16:53:24 +02:00
Alexander M. Turek
a139a1b63c Merge branch '3.2.x' into 3.3.x
* 3.2.x:
  Fix deprecated array access usage (#11517)
  Address doctrine/persistence 3.3.3 release
  Add the propoer void return type on the __load method of proxies
  Remove unneeded CS rule
2024-06-21 13:32:17 +02:00
Alexander M. Turek
1153b9468c Fix deprecated array access usage (#11517) 2024-06-21 13:31:45 +02:00
Grégoire Paris
40f299f1eb Merge pull request #11506 from michalbundyra/composite-key-relations-3
[2.19.x] Fetching entities with Composite Key Relations and null values
2024-06-21 08:12:27 +02:00
Grégoire Paris
d0e9177121 Merge pull request #11514 from doctrine/2.19.x
Merge 2.19.x up into 2.20.x
2024-06-20 22:51:33 +02:00
Grégoire Paris
428032ca7c Merge remote-tracking branch 'origin/2.19.x' into HEAD 2024-06-20 22:18:24 +02:00
Grégoire Paris
68af854f46 Merge pull request #11513 from greg0ire/address-persistence-3.3.3-release
Address doctrine/persistence 3.3.3 release
2024-06-20 22:14:52 +02:00
Grégoire Paris
77467cd824 Address doctrine/persistence 3.3.3 release
FileDriver became templatable, and some very wrong phpdoc has been
fixed, causing Psalm to better understand the 2 FileDriver classes in
this project.
2024-06-20 22:00:33 +02:00
Grégoire Paris
f666aa641e Merge pull request #11512 from greg0ire/deprecate-db-driver
Deprecate DatabaseDriver
2024-06-20 21:31:58 +02:00
Grégoire Paris
ca3319c2f6 Merge pull request #11511 from doctrine/stof-patch-1
Add the proper void return type on the __load method of proxies
2024-06-20 11:46:52 +02:00
Christophe Coevoet
c06f6b9376 Add the propoer void return type on the __load method of proxies
When using ghost objects, the method was leaking a `static` return type due to the way it was implemented, which is incompatible with the native return type that will be added in doctrine/persistence v4.
2024-06-20 09:08:10 +02:00
Grégoire Paris
802f20b8e7 Merge pull request #11509 from greg0ire/remove-unneeded-rule
Remove unneeded CS rule
2024-06-19 23:49:15 +02:00
Michał Bundyra
96d13ac62a Fetching entities with Composite Key Relations and null values
Remove redundant condition to check if target class contains foreign
identifier in order to allow fetching a null for relations with
composite keys, when part of the key value is null.
2024-06-19 21:54:02 +01:00
Grégoire Paris
ed53defaa1 Deprecate DatabaseDriver
It was used for the reverse engineering feature, which has been removed.
2024-06-19 21:59:29 +02:00
Grégoire Paris
2ea6a1a5fb Remove unneeded CS rule 2024-06-19 21:47:55 +02:00
Alexander M. Turek
41cb5fbbbf Merge branch '2.19.x' into 3.2.x
* 2.19.x:
  Fix OneToManyPersister::deleteEntityCollection missing discriminator column/value. (GH-11500)
  Skip joined entity creation for empty relation (#10889)
  ci: maintained and stable mariadb version (11.4 current lts) (#11490)
  fix(docs): use string value in `addAttribute`
  Replace assertion with exception (#11489)
  Use ramsey/composer-install in PHPBench workflow
  update EntityManager#transactional to EntityManager#wrapInTransaction
  Fix cloning entities
  Consider usage of setFetchMode when checking for simultaneous usage of fetch-mode EAGER and WITH condition.
2024-06-19 12:21:35 +02:00
Alexander M. Turek
83851a9716 Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  Fix OneToManyPersister::deleteEntityCollection missing discriminator column/value. (GH-11500)
  Skip joined entity creation for empty relation (#10889)
  ci: maintained and stable mariadb version (11.4 current lts) (#11490)
  fix(docs): use string value in `addAttribute`
  Replace assertion with exception (#11489)
  Use ramsey/composer-install in PHPBench workflow
  update EntityManager#transactional to EntityManager#wrapInTransaction
  Fix cloning entities
  Consider usage of setFetchMode when checking for simultaneous usage of fetch-mode EAGER and WITH condition.
2024-06-18 14:19:19 +02:00
Alexander M. Turek
066ec1ac81 Fix upgrade guide for 2.20 (#11504) 2024-06-18 14:18:37 +02:00
Benjamin Eberlei
68744489f0 Undeprecate PARTIAL for array hydration. (#11366)
* Undeprecate PARTIAL for array hydration.

* note about undeprecate partial in UPGRADE.md
2024-06-18 14:15:31 +02:00
Grégoire Paris
cc2ad1993c Merge pull request #11501 from gitbugr/2.19.x
Fix OneToManyPersister::deleteEntityCollection missing discriminator column/value. (GH-11500)
2024-06-17 21:40:07 +02:00
Kyron Taylor
e4d46c4276 Fix OneToManyPersister::deleteEntityCollection missing discriminator column/value. (GH-11500) 2024-06-15 21:58:08 +01:00
Grégoire Paris
858a1adc3b Merge pull request #11194 from noemi-salaun/fix/gh10889
Skip joined entity creation for empty relation (#10889)
2024-06-14 20:06:59 +02:00
Noemi Salaun
3b499132d9 Skip joined entity creation for empty relation (#10889) 2024-06-14 14:34:04 +02:00
Daniel Black
39153fd88a ci: maintained and stable mariadb version (11.4 current lts) (#11490)
Also use MARIADB env names and the healthcheck.sh included in the container.
2024-06-13 19:34:46 +02:00
Grégoire Paris
bdc9679e37 Merge pull request #11493 from SamMousa/fix-docs-11492
fix(docs): use string value in `addAttribute`
2024-06-11 15:26:45 +01:00
Sam Mousa
87a8ee21c9 fix(docs): use string value in addAttribute 2024-06-11 16:21:28 +02:00
Grégoire Paris
59c8bc09ab Replace assertion with exception (#11489) 2024-06-03 23:08:27 +02:00
Grégoire Paris
3a7d7c9f57 Merge pull request #11484 from greg0ire/backport-ramsey
Use ramsey/composer-install in PHPBench workflow
2024-06-02 15:26:00 +02:00
Grégoire Paris
06eca40134 Use ramsey/composer-install in PHPBench workflow
It will handle caching for us.
2024-06-02 15:22:59 +02:00
Grégoire Paris
23b35e9554 Merge pull request #11475 from nicolas-grekas/fix-clone
Fix cloning entities
2024-06-01 22:47:57 +02:00
Grégoire Paris
e063926cbd Merge pull request #11445 from aprat84/gh-11128
Consider usage of setFetchMode when checking for simultaneous usage of fetch-mode EAGER and WITH condition
2024-05-30 17:24:11 +02:00
Grégoire Paris
4a01a76a17 Merge pull request #11460 from IndraGunawan/update-transactional-doc
docs: update EntityManager#transactional to EntityManager#wrapInTransaction
2024-05-28 14:07:06 +02:00
Indra Gunawan
93c2dd9d4b update EntityManager#transactional to EntityManager#wrapInTransaction
One has been deprecated in favor of the other.
2024-05-28 13:59:17 +02:00
Nicolas Grekas
75bc22980e Fix cloning entities 2024-05-27 14:53:58 +02:00
Alix Mauro
9696c3434d Consider usage of setFetchMode when checking for simultaneous usage of fetch-mode EAGER and WITH condition.
This fixes a bug that arises when an entity relation is mapped with
fetch-mode EAGER but setFetchMode LAZY (or anything that is not EAGER)
has been used on the query. If the query use WITH condition, an
exception is incorrectly raised (Associations with fetch-mode=EAGER may
not be using WITH conditions).

Fixes #11128

Co-Authored-By: Albert Prat <albert.prat@interactiu.cat>
2024-05-25 14:22:20 +02:00
Grégoire Paris
9d4f54b9a4 Update branch metadata (#11474) 2024-05-24 00:25:01 +02:00
Grégoire Paris
37946d3a21 Merge pull request #11472 from nicolas-grekas/no-readonly
Remove readonly modifier from EntityManager
2024-05-23 16:27:52 +02:00
Nicolas Grekas
baf96cdad4 Remove readonly modifier from EntityManager 2024-05-23 14:33:01 +02:00
Alexander M. Turek
ce09c96427 Deprecate the NotSupported exception (#11470) 2024-05-22 21:53:12 +02:00
Alexander M. Turek
ae659fe650 Deprecate SequenceGenerator implementing Serializable (#11468) 2024-05-22 10:48:46 +02:00
Alexander M. Turek
0a177d5074 Merge branch '3.1.x' into 3.2.x
* 3.1.x:
  Psalm 5.24.0 (#11467)
  PHPStan 1.11.1 (#11466)
2024-05-21 14:24:54 +02:00
Alexander M. Turek
dbfe47b07b Merge branch '2.19.x' into 3.1.x
* 2.19.x:
  Psalm 5.24.0 (#11467)
  PHPStan 1.11.1 (#11466)
2024-05-21 14:24:20 +02:00
Alexander M. Turek
bf3e082c00 Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  Psalm 5.24.0 (#11467)
  PHPStan 1.11.1 (#11466)
  Test with actual lock modes (#11465)
  Backport test for Query::setLockMode() (#11463)
2024-05-21 14:22:18 +02:00
Alexander M. Turek
d31aabb40c Psalm 5.24.0 (#11467) 2024-05-21 14:21:50 +02:00
Alexander M. Turek
22b1f52c1c Merge branch '3.1.x' into 3.2.x
* 3.1.x:
  Fix failed merge (#11464)
  Test with actual lock modes (#11465)
  Backport test for Query::setLockMode() (#11463)
  Fix return type of Query::getLockMode() (#11462)
2024-05-21 14:04:38 +02:00
Alexander M. Turek
d66884403f PHPStan 1.11.1 (#11466) 2024-05-21 13:32:25 +02:00
Alexander M. Turek
a90ee5c495 Merge branch '2.19.x' into 3.1.x
* 2.19.x:
  Test with actual lock modes (#11465)
  Backport test for Query::setLockMode() (#11463)
2024-05-21 12:52:03 +02:00
Alexander M. Turek
11270425e5 Fix failed merge (#11464) 2024-05-21 12:30:56 +02:00
Alexander M. Turek
552eae37a3 Test with actual lock modes (#11465) 2024-05-21 12:30:36 +02:00
Alexander M. Turek
ee4b03aa78 Backport test for Query::setLockMode() (#11463) 2024-05-21 12:30:16 +02:00
Alexander M. Turek
f1246d57c2 Fix return type of Query::getLockMode() (#11462)
… for DBAL 4
2024-05-21 12:30:01 +02:00
Alexander M. Turek
a14ef7c279 Merge branch '3.1.x' into 3.2.x
* 3.1.x:
  Using an integer as discriminator value with ORM v3
  Using an integer as discriminator value with ORM v3
  Bump ramsey/composer-install from 2 to 3 (#11442)
  Use ramsey/composer-install in PHPBench workflow (#11444)
  Bump doctrine/.github from 3.0.0 to 5.0.1
  Upgrade codecov/codecov-action
  Setup Dependabot
2024-05-21 08:42:44 +02:00
Alexander M. Turek
54c29140fa Merge branch '2.19.x' into 3.1.x
* 2.19.x:
  Bump ramsey/composer-install from 2 to 3 (#11442)
  Bump doctrine/.github from 3.0.0 to 5.0.1
  Upgrade codecov/codecov-action
2024-05-21 08:42:11 +02:00
Alexander M. Turek
eb49f66926 Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  Bump ramsey/composer-install from 2 to 3 (#11442)
  Bump doctrine/.github from 3.0.0 to 5.0.1
  Upgrade codecov/codecov-action
2024-05-21 08:40:37 +02:00
MatteoFeltrin
73e30df52b allow classname in 'value' attribute of xml discriminator-mapping field 2024-05-20 11:00:23 +02:00
Grégoire Paris
daa99f197b Merge pull request #11456 from prohalexey/IntegerDescriminatorInInstanceOf
Using an integer as discriminator value with ORM v3
2024-05-17 08:19:34 +02:00
Alexey Prohorov
2b04cc2e3f Using an integer as discriminator value with ORM v3
This fixes a bug that occurred when configuring integers as discriminator values and using DQL instanceOf function in the queries. Doctrine throws a type error whenever the application generates these queries.
2024-05-16 11:53:29 +03:00
Grégoire Paris
3d9af3187f Merge pull request #11425 from prohalexey/FixForIntegerDescriminatorValue
Discriminator value could be an integer
2024-05-15 11:31:09 +02:00
Alexey Prohorov
e83d8a80ba Using an integer as discriminator value with ORM v3
This fixes a bug that occurred when configuring integers as discriminator values. Doctrine throws a type error whenever the application generates queries.
2024-05-15 10:42:04 +03:00
dependabot[bot]
c5291b4de8 Bump ramsey/composer-install from 2 to 3 (#11442)
Bumps [ramsey/composer-install](https://github.com/ramsey/composer-install) from 2 to 3.
- [Release notes](https://github.com/ramsey/composer-install/releases)
- [Commits](https://github.com/ramsey/composer-install/compare/v2...v3)

---
updated-dependencies:
- dependency-name: ramsey/composer-install
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-05 23:47:43 +02:00
Grégoire Paris
029ca611f0 Use ramsey/composer-install in PHPBench workflow (#11444)
It will handle caching for us.
2024-05-05 23:38:41 +02:00
Grégoire Paris
831d86548c Merge pull request #11441 from doctrine/dependabot/github_actions/2.19.x/doctrine/dot-github-5.0.1
Bump doctrine/.github from 3.0.0 to 5.0.1
2024-05-05 23:23:39 +02:00
dependabot[bot]
f26b3b9cf9 Bump doctrine/.github from 3.0.0 to 5.0.1
Bumps [doctrine/.github](https://github.com/doctrine/.github) from 3.0.0 to 5.0.1.
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/3.0.0...5.0.1)

---
updated-dependencies:
- dependency-name: doctrine/.github
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-05-05 21:17:24 +00:00
Grégoire Paris
9e7715f678 Merge pull request #11439 from greg0ire/setup-dependabot
Setup Dependabot
2024-05-05 23:16:51 +02:00
Grégoire Paris
9ab84f7478 Merge pull request #11440 from greg0ire/update-codecov
Upgrade codecov/codecov-action
2024-05-05 22:56:55 +02:00
Grégoire Paris
e6bb4ef20e Upgrade codecov/codecov-action 2024-05-05 22:43:51 +02:00
Grégoire Paris
0e26e3ed50 Setup Dependabot
Targeting 2.19.x, since we want the updates to bubble up. Since
Dependabot has had no effect on doctrine/dbal yet, I suppose that means
that "dependabot.yml" must be present on the default branch.
2024-05-05 22:41:40 +02:00
Grégoire Paris
63315c8e4a Merge pull request #11434 from doctrine/3.1.x-merge-up-into-3.2.x_sjLAVzN7
Merge release 3.1.3 into 3.2.x
2024-04-30 09:57:38 +02:00
Grégoire Paris
8ca99fdfdc Merge pull request #11433 from greg0ire/3.1.x
Merge 3.0.x up into 3.1.x
2024-04-30 09:14:13 +02:00
Grégoire Paris
8b6a58fa0e Merge pull request #11432 from doctrine/2.19.x-merge-up-into-2.20.x_IfraK93L
Merge release 2.19.5 into 2.20.x
2024-04-30 09:04:52 +02:00
Grégoire Paris
2d8e466636 Merge remote-tracking branch 'origin/2.19.x' into 3.1.x 2024-04-30 09:00:59 +02:00
Grégoire Paris
94986af284 Merge pull request #11430 from W0rma/fix-deprecation-layer-orm-exception
Fix deprecation layer of Doctrine\ORM\ORMException
2024-04-30 08:49:54 +02:00
W0rma
ad5c8e4bdc Make test compatible with PHP 7.1 2024-04-30 08:35:06 +02:00
W0rma
c363f55ad1 Fix deprecation layer 2024-04-29 14:48:36 +02:00
Grégoire Paris
c973a62272 Merge pull request #11429 from SenseException/unused-test-group
Remove unused test group
2024-04-27 11:42:05 +02:00
Grégoire Paris
8d3446015a Merge pull request #11428 from xificurk/keep-removed-entity-in-identity-map
Prevent creation of new MANAGED entity instance by reloading REMOVED entity from database
2024-04-27 11:40:56 +02:00
Claudio Zizza
4e335f4044 Remove unused test group 2024-04-27 10:46:19 +02:00
Petr Morávek
bb36d49b38 Keep entities in identity map until the scheduled deletions are executed.
If the entity gets reloaded from database before the deletions are
executed UnitOfWork needs to be able to return the original instance in
REMOVED state.
2024-04-26 21:54:02 +02:00
Grégoire Paris
2b81a8e260 Merge pull request #11426 from nasimic/patch-1
Update association-mapping.rst
2024-04-26 21:27:07 +02:00
Nasimi Mammadov
7d3b3f28e9 Update association-mapping.rst
Changed capitalized column names to lowercase for consistency. Other occurances of column names mentioned as lowercase several times at this same page.
2024-04-26 21:24:28 +02:00
Simon Podlipsky
cbec236e8b fix: always cleanup in AbstractHydrator::toIterable() (#11101)
Previously it didn't cleanup anything as long as the iteration hasn't reached the final row.

Co-authored-by: Oleg Andreyev <oleg.andreyev@lampa.lv>
2024-04-25 10:32:40 +02:00
Grégoire Paris
306963fe79 Merge pull request #11422 from tomasz-ryba/bugfix/fetch-eager-order-by
Bugfix: respect orderBy for fetch EAGER mode
2024-04-25 00:09:43 +02:00
Tomasz Ryba
fb4578406f Respect orderBy for EAGER fetch mode
EAGER fetch mode ignores orderBy as of changes introduced with #8391

Fixes #11163
Fixes #11381
2024-04-24 22:44:16 +02:00
Grégoire Paris
bdc41e2b5e Merge pull request #11420 from tyteen4a03/patch-1
fix(docs): typo
2024-04-22 15:40:39 +02:00
Timothy Choi
90376a6431 fix(docs): typo 2024-04-22 15:30:56 +02:00
Alexander M. Turek
97634ae6a1 Merge branch '3.1.x' into 3.2.x
* 3.1.x:
  Revert "Merge pull request #11399 from ThomasLandauer/issue-11377" (#11415)
  Fix BIGINT validation (#11414)
  docs: update PHP version in doc
  Fix fromMappingArray definition
  Fix templated phpdoc return type (#11407)
  [Documentation] Merging "Query Result Formats" with "Hydration Modes"
  SchemaValidator: Changing mapping of BIGINT to string|int
  Fix psalm errors: remove override of template type
  Update dql-doctrine-query-language.rst
  Adding `NonUniqueResultException`
  [Documentation] Query Result Formats
2024-04-15 16:31:08 +02:00
Alexander M. Turek
b725908c83 Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  Fix BIGINT validation (#11414)
  Fix templated phpdoc return type (#11407)
  [Documentation] Merging "Query Result Formats" with "Hydration Modes"
  Fix psalm errors: remove override of template type
  Update dql-doctrine-query-language.rst
  Adding `NonUniqueResultException`
  [Documentation] Query Result Formats
2024-04-15 16:26:53 +02:00
Alexander M. Turek
be307edba8 Merge release 2.19.3 into 2.20.x (#11398) 2024-03-22 12:11:39 +01:00
Alexander M. Turek
4672d284ff Merge branch '3.1.x' into 3.2.x
* 3.1.x:
  Adjust PHPBench mocks
  Set column length explicitly (#11393)
  Add missing import
  Remove unused variable (#11391)
  Fixed proxy initialization for EnumReflectionProperty
  Remove older versions from the docs (#11383)
  [Documentation] Removing "Doctrine Mapping Types" ... (#11384)
  [GH-11185] Bugfix: do not use collection batch loading for indexBy assocations. (#11380)
  Improve lazy ghost performance by avoiding self-referencing closure. (#11376)
  Remove outdated git metadata files (#11362)
  Switch join columns around, otherwise index doesnt match
  Key on fk
  Fix entities and mapping.
  Minor code style fix in AbstractRemoteControl
  Do not schedule batch loading for target classes with composite identifier.
  Cleanup tests not to use model sets.
  provides a test case for github issue 11154
2024-03-21 14:44:21 +01:00
Alexander M. Turek
083f642cfa Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  Remove unused variable (#11391)
2024-03-21 10:33:34 +01:00
Alexander M. Turek
716da7e538 Merge branch '2.19.x' into 2.20.x
* 2.19.x:
  [Documentation] Removing "Doctrine Mapping Types" ... (#11384)
  [GH-11185] Bugfix: do not use collection batch loading for indexBy assocations. (#11380)
  Improve lazy ghost performance by avoiding self-referencing closure. (#11376)
2024-03-21 10:12:37 +01:00
Grégoire Paris
bcdc5bdaf4 Merge pull request #11378 from doctrine/2.19.x-merge-up-into-2.20.x_eyF2lMAL
Merge release 2.19.2 into 2.20.x
2024-03-18 20:22:04 +01:00
Grégoire Paris
69f51cc794 Merge pull request #11371 from doctrine/3.1.x
Merge 3.1.x up into 3.2.x
2024-03-17 10:43:23 +01:00
Grégoire Paris
f9331ee2b9 Merge pull request #11369 from doctrine/3.1.x
Merge 3.1.x up into 3.2.x
2024-03-17 09:34:02 +01:00
Benjamin Eberlei
80278c545e Update docs/en/reference/partial-hydration.rst
Co-authored-by: Grégoire Paris <postmaster@greg0ire.fr>
2024-03-16 23:36:13 +01:00
Grégoire Paris
cb05f1aadf Merge pull request #11357 from DaDeather/11351-add-deprecation-for-obsolete-indexes-and-unique-constraint-properties-of-table-attribute
Deprecate obsolete and unnecessary properties from Table attribute (#11351)
2024-03-16 23:24:55 +01:00
Grégoire Paris
ab616f1a1d Merge pull request #11364 from doctrine/3.1.x
Merge 3.1.x up into 3.2.x
2024-03-16 23:24:34 +01:00
Benjamin Eberlei
90962f060a Use id dynamically in array hydration test. 2024-03-16 22:39:38 +01:00
Benjamin Eberlei
758f0d7605 Remove Query::HINT_FORCE_PARTIAL_LOAD constant, not needed to be reintroduced. 2024-03-16 22:36:21 +01:00
Benjamin Eberlei
eb8510ff5c Add tests for adjusted functionality. 2024-03-16 22:34:54 +01:00
Benjamin Eberlei
d5fdd676f4 Reintroduce PARTIAL, but only for non-object hydration. 2024-03-16 22:20:34 +01:00
Grégoire Paris
a3e3a3bbf3 Merge pull request #11360 from doctrine/2.19.x-merge-up-into-2.20.x_aXnS7Xw9
Merge release 2.19.1 into 2.20.x
2024-03-16 21:32:18 +01:00
Ismail Özgün Turan
7d1444e5b6 Deprecate obsolete and unnecessary properties from Table attribute (#11351)
The properties `indexes` and `uniqueConstraints` were used by the
`AnnotationDriver` but were never implemented for the `AttributeDriver`.
Since the `AnnotationDriver` doesn't exist anymore these can become
deprecated and will then be removed afterwards.
2024-03-15 12:23:03 +01:00
Grégoire Paris
25d5936337 Merge pull request #11354 from greg0ire/depr--complete
Deprecate --complete option of orm:schema-tool:update
2024-03-15 07:42:35 +01:00
Grégoire Paris
68f9bf5dfa Deprecate --complete option of orm:schema-tool:update
It achieves nothing anymore.
2024-03-14 13:14:55 +01:00
d-ph
0a49274f9b Update aggregate-fields.rst
Change `PESSIMISTIC_READ` to `PESSIMISTIC_WRITE`. Otherwise, the solution to the race condition at the bottom of the article would allow concurrent reads, which would not solve the presented race condition problem.
2024-03-08 09:36:42 +00:00
647 changed files with 20836 additions and 5292 deletions

View File

@@ -12,88 +12,58 @@
"upcoming": true
},
{
"name": "3.2",
"branchName": "3.2.x",
"slug": "3.2",
"name": "3.7",
"branchName": "3.7.x",
"slug": "3.7",
"upcoming": true
},
{
"name": "3.1",
"branchName": "3.1.x",
"slug": "3.1",
"name": "3.6",
"branchName": "3.6.x",
"slug": "3.6",
"current": true
},
{
"name": "3.0",
"branchName": "3.0.x",
"slug": "3.0",
"maintained": false
"name": "2.21",
"branchName": "2.21.x",
"slug": "2.21",
"upcoming": true
},
{
"name": "2.20",
"branchName": "2.20.x",
"slug": "2.20",
"upcoming": true
},
{
"name": "2.19",
"branchName": "2.19.x",
"slug": "2.19",
"maintained": true
},
{
"name": "2.19",
"slug": "2.19",
"maintained": false
},
{
"name": "2.18",
"branchName": "2.18.x",
"slug": "2.18",
"maintained": false
},
{
"name": "2.17",
"branchName": "2.17.x",
"slug": "2.17",
"maintained": false
},
{
"name": "2.16",
"branchName": "2.16.x",
"slug": "2.16",
"maintained": false
},
{
"name": "2.15",
"branchName": "2.15.x",
"slug": "2.15",
"maintained": false
},
{
"name": "2.14",
"branchName": "2.14.x",
"slug": "2.14",
"maintained": false
},
{
"name": "2.13",
"branchName": "2.13.x",
"slug": "2.13",
"maintained": false
},
{
"name": "2.12",
"branchName": "2.12.x",
"slug": "2.12",
"maintained": false
},
{
"name": "2.11",
"branchName": "2.11.x",
"slug": "2.11",
"maintained": false
},
{
"name": "2.10",
"branchName": "2.10.x",
"slug": "2.10",
"maintained": false
}
]
}

5
.gitattributes vendored
View File

@@ -11,13 +11,10 @@ build.properties.dev export-ignore
build.xml export-ignore
CONTRIBUTING.md export-ignore
phpunit.xml.dist export-ignore
run-all.sh export-ignore
phpcs.xml.dist export-ignore
phpbench.json export-ignore
phpstan.neon export-ignore
phpstan-baseline.neon export-ignore
phpstan-dbal2.neon export-ignore
phpstan-dbal3.neon export-ignore
phpstan-params.neon export-ignore
phpstan-persistence2.neon export-ignore
psalm.xml export-ignore
psalm-baseline.xml export-ignore

View File

@@ -1,37 +0,0 @@
---
name: 💥 BC Break
about: Have you encountered an issue during upgrade? 💣
---
<!--
Before reporting a BC break, please consult the upgrading document to make sure it's not an expected change: https://github.com/doctrine/orm/blob/2.9.x/UPGRADE.md
-->
### BC Break Report
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| BC Break | yes
| Version | x.y.z
#### Summary
<!-- Provide a summary describing the problem you are experiencing. -->
#### Previous behavior
<!-- What was the previous (working) behavior? -->
#### Current behavior
<!-- What is the current (broken) behavior? -->
#### How to reproduce
<!--
Provide steps to reproduce the BC break.
If possible, also add a code snippet with relevant configuration, entity mappings, DQL etc.
Adding a failing Unit or Functional Test would help us a lot - you can submit it in a Pull Request separately, referencing this bug report.
-->

View File

@@ -1,34 +0,0 @@
---
name: 🐞 Bug Report
about: Something is broken? 🔨
---
### Bug Report
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| BC Break | yes/no
| Version | x.y.z
#### Summary
<!-- Provide a summary describing the problem you are experiencing. -->
#### Current behavior
<!-- What is the current (buggy) behavior? -->
#### How to reproduce
<!--
Provide steps to reproduce the bug.
If possible, also add a code snippet with relevant configuration, entity mappings, DQL etc.
Adding a failing Unit or Functional Test would help us a lot - you can submit one in a Pull Request separately, referencing this bug report.
-->
#### Expected behavior
<!-- What was the expected (correct) behavior? -->

View File

@@ -1,18 +0,0 @@
---
name: 🎉 Feature Request
about: You have a neat idea that should be implemented? 🎩
---
### Feature Request
<!-- Fill in the relevant information below to help triage your issue. -->
| Q | A
|------------ | ------
| New Feature | yes
| RFC | yes/no
| BC Break | yes/no
#### Summary
<!-- Provide a summary of the feature you would like to see implemented. -->

View File

@@ -1,6 +0,0 @@
---
name: ❓ Support Question
about: Have a problem that you can't figure out? 🤔
---
Please use https://github.com/doctrine/orm/discussions instead.

9
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,9 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "CI"
target-branch: "2.20.x"

View File

@@ -24,4 +24,4 @@ on:
jobs:
coding-standards:
uses: "doctrine/.github/.github/workflows/coding-standards.yml@3.0.0"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@13.1.0"

20
.github/workflows/composer-lint.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
name: "Composer Lint"
on:
pull_request:
branches:
- "*.x"
paths:
- ".github/workflows/composer-lint.yml"
- "composer.json"
push:
branches:
- "*.x"
paths:
- ".github/workflows/composer-lint.yml"
- "composer.json"
jobs:
composer-lint:
name: "Composer Lint"
uses: "doctrine/.github/.github/workflows/composer-lint.yml@13.1.0"

View File

@@ -1,4 +1,4 @@
name: "Continuous Integration"
name: "CI: PHPUnit"
on:
pull_request:
@@ -9,7 +9,6 @@ on:
- ci/**
- composer.*
- src/**
- phpunit.xml.dist
- tests/**
push:
branches:
@@ -19,7 +18,6 @@ on:
- ci/**
- composer.*
- src/**
- phpunit.xml.dist
- tests/**
env:
@@ -27,7 +25,14 @@ env:
jobs:
phpunit-smoke-check:
name: "PHPUnit with SQLite"
name: >
SQLite -
${{ format('PHP {0} - DBAL {1} - ext. {2} - proxy {3}',
matrix.php-version || 'Ø',
matrix.dbal-version || 'Ø',
matrix.extension || 'Ø',
matrix.proxy || 'Ø'
) }}
runs-on: "ubuntu-22.04"
strategy:
@@ -36,6 +41,8 @@ jobs:
- "8.1"
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dbal-version:
- "default"
- "3.7"
@@ -44,21 +51,43 @@ jobs:
- "pdo_sqlite"
deps:
- "highest"
stability:
- "stable"
native_lazy:
- "0"
include:
- php-version: "8.2"
dbal-version: "4@dev"
extension: "pdo_sqlite"
stability: "stable"
native_lazy: "0"
- php-version: "8.2"
dbal-version: "4@dev"
extension: "sqlite3"
stability: "stable"
native_lazy: "0"
- php-version: "8.1"
dbal-version: "default"
deps: "lowest"
extension: "pdo_sqlite"
stability: "stable"
native_lazy: "0"
- php-version: "8.4"
dbal-version: "default"
deps: "highest"
extension: "pdo_sqlite"
stability: "stable"
native_lazy: "1"
- php-version: "8.4"
dbal-version: "default"
deps: "highest"
extension: "sqlite3"
stability: "dev"
native_lazy: "1"
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
uses: "actions/checkout@v6"
with:
fetch-depth: 2
@@ -70,12 +99,24 @@ jobs:
coverage: "pcov"
ini-values: "zend.assertions=1, apc.enable_cli=1"
- name: "Allow dev dependencies"
run: |
composer config minimum-stability dev
composer remove --no-update --dev phpbench/phpbench phpdocumentor/guides-cli
composer require --no-update symfony/console:^8 symfony/var-exporter:^8 doctrine/dbal:^4.4
composer require --dev --no-update symfony/cache:^8
if: "${{ matrix.stability == 'dev' }}"
- name: "Require specific DBAL version"
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Downgrade VarExporter"
run: 'composer require --no-update "symfony/var-exporter:^6.4 || ^7.4"'
if: "${{ matrix.native_lazy == '0' }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v2"
uses: "ramsey/composer-install@v3"
with:
composer-options: "--ignore-platform-req=php+"
dependency-versions: "${{ matrix.deps }}"
@@ -84,21 +125,79 @@ jobs:
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage-no-cache.xml"
env:
ENABLE_SECOND_LEVEL_CACHE: 0
ENABLE_NATIVE_LAZY_OBJECTS: ${{ matrix.native_lazy }}
- name: "Run PHPUnit with Second Level Cache"
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --exclude-group performance,non-cacheable,locking_functional --coverage-clover=coverage-cache.xml"
- name: "Run PHPUnit with Second Level Cache and PHPUnit 10"
run: |
vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml \
--exclude-group=performance,non-cacheable,locking_functional \
--coverage-clover=coverage-cache.xml
if: "${{ matrix.php-version == '8.1' }}"
env:
ENABLE_SECOND_LEVEL_CACHE: 1
ENABLE_NATIVE_LAZY_OBJECTS: ${{ matrix.native_lazy }}
- name: "Run PHPUnit with Second Level Cache and PHPUnit 11+"
run: |
vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml \
--exclude-group=performance \
--exclude-group=non-cacheable \
--exclude-group=locking_functional \
--coverage-clover=coverage-cache.xml
if: "${{ matrix.php-version != '8.1' }}"
env:
ENABLE_SECOND_LEVEL_CACHE: 1
ENABLE_NATIVE_LAZY_OBJECTS: ${{ matrix.native_lazy }}
- name: "Upload coverage file"
uses: "actions/upload-artifact@v4"
uses: "actions/upload-artifact@v7"
with:
name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.deps }}-coverage"
name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.deps }}-${{ matrix.stability }}-${{ matrix.native_lazy }}-coverage"
path: "coverage*.xml"
phpunit-deprecations:
name: "PHPUnit (fail on deprecations)"
runs-on: "ubuntu-24.04"
steps:
- name: "Checkout"
uses: "actions/checkout@v5"
with:
fetch-depth: 2
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
php-version: "8.5"
extensions: "apcu, pdo, sqlite3"
coverage: "pcov"
ini-values: "zend.assertions=1, apc.enable_cli=1"
- name: "Allow dev dependencies"
run: composer config minimum-stability dev
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
with:
composer-options: "--ignore-platform-req=php+"
dependency-versions: "highest"
- name: "Run PHPUnit"
run: "vendor/bin/phpunit -c ci/github/phpunit/sqlite3.xml --fail-on-deprecation"
env:
ENABLE_SECOND_LEVEL_CACHE: 0
ENABLE_NATIVE_LAZY_OBJECTS: 1
phpunit-postgres:
name: "PHPUnit with PostgreSQL"
name: >
${{ format('PostgreSQL {0} - PHP {1} - DBAL {2} - ext. {3}',
matrix.postgres-version || 'Ø',
matrix.php-version || 'Ø',
matrix.dbal-version || 'Ø',
matrix.extension || 'Ø'
) }}
runs-on: "ubuntu-22.04"
needs: "phpunit-smoke-check"
@@ -107,11 +206,13 @@ jobs:
php-version:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dbal-version:
- "default"
- "3.7"
postgres-version:
- "15"
- "17"
extension:
- pdo_pgsql
- pgsql
@@ -139,7 +240,7 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
uses: "actions/checkout@v6"
with:
fetch-depth: 2
@@ -156,7 +257,7 @@ jobs:
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v2"
uses: "ramsey/composer-install@v3"
with:
composer-options: "--ignore-platform-req=php+"
@@ -164,14 +265,20 @@ jobs:
run: "vendor/bin/phpunit -c ci/github/phpunit/pdo_pgsql.xml --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v4"
uses: "actions/upload-artifact@v7"
with:
name: "${{ github.job }}-${{ matrix.postgres-version }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.extension }}-coverage"
path: "coverage.xml"
phpunit-mariadb:
name: "PHPUnit with MariaDB"
name: >
${{ format('MariaDB {0} - PHP {1} - DBAL {2} - ext. {3}',
matrix.mariadb-version || 'Ø',
matrix.php-version || 'Ø',
matrix.dbal-version || 'Ø',
matrix.extension || 'Ø'
) }}
runs-on: "ubuntu-22.04"
needs: "phpunit-smoke-check"
@@ -180,12 +287,14 @@ jobs:
php-version:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dbal-version:
- "default"
- "3.7"
- "4@dev"
mariadb-version:
- "10.9"
- "11.4"
extension:
- "mysqli"
- "pdo_mysql"
@@ -194,18 +303,18 @@ jobs:
mariadb:
image: "mariadb:${{ matrix.mariadb-version }}"
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: "doctrine_tests"
MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: yes
MARIADB_DATABASE: "doctrine_tests"
options: >-
--health-cmd "mysqladmin ping --silent"
--health-cmd "healthcheck.sh --connect --innodb_initialized"
ports:
- "3306:3306"
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
uses: "actions/checkout@v6"
with:
fetch-depth: 2
@@ -222,7 +331,7 @@ jobs:
extensions: "${{ matrix.extension }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v2"
uses: "ramsey/composer-install@v3"
with:
composer-options: "--ignore-platform-req=php+"
@@ -230,14 +339,20 @@ jobs:
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage.xml"
- name: "Upload coverage file"
uses: "actions/upload-artifact@v4"
uses: "actions/upload-artifact@v7"
with:
name: "${{ github.job }}-${{ matrix.mariadb-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage.xml"
phpunit-mysql:
name: "PHPUnit with MySQL"
name: >
${{ format('MySQL {0} - PHP {1} - DBAL {2} - ext. {3}',
matrix.mysql-version || 'Ø',
matrix.php-version || 'Ø',
matrix.dbal-version || 'Ø',
matrix.extension || 'Ø'
) }}
runs-on: "ubuntu-22.04"
needs: "phpunit-smoke-check"
@@ -246,6 +361,8 @@ jobs:
php-version:
- "8.2"
- "8.3"
- "8.4"
- "8.5"
dbal-version:
- "default"
- "3.7"
@@ -279,7 +396,7 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
uses: "actions/checkout@v6"
with:
fetch-depth: 2
@@ -296,7 +413,7 @@ jobs:
if: "${{ matrix.dbal-version != 'default' }}"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v2"
uses: "ramsey/composer-install@v3"
with:
composer-options: "--ignore-platform-req=php+"
@@ -305,13 +422,27 @@ jobs:
env:
ENABLE_SECOND_LEVEL_CACHE: 0
- name: "Run PHPUnit with Second Level Cache"
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --exclude-group performance,non-cacheable,locking_functional --coverage-clover=coverage-no-cache.xml"
- name: "Run PHPUnit with Second Level Cache and PHPUnit 10"
run: |
vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml \
--exclude-group=performance,non-cacheable,locking_functional \
--coverage-clover=coverage-no-cache.xml"
if: "${{ matrix.php-version == '8.1' }}"
env:
ENABLE_SECOND_LEVEL_CACHE: 1
- name: "Run PHPUnit with Second Level Cache and PHPUnit 11+"
run: |
vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml \
--exclude-group=performance \
--exclude-group=non-cacheable \
--exclude-group=locking_functional \
--coverage-clover=coverage-no-cache.xml
if: "${{ matrix.php-version != '8.1' }}"
env:
ENABLE_SECOND_LEVEL_CACHE: 1
- name: "Upload coverage files"
uses: "actions/upload-artifact@v4"
uses: "actions/upload-artifact@v7"
with:
name: "${{ github.job }}-${{ matrix.mysql-version }}-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-coverage"
path: "coverage*.xml"
@@ -319,6 +450,8 @@ jobs:
upload_coverage:
name: "Upload coverage to Codecov"
runs-on: "ubuntu-22.04"
# Only run on PRs from forks
if: "github.event.pull_request.head.repo.full_name != github.repository"
needs:
- "phpunit-smoke-check"
- "phpunit-postgres"
@@ -327,16 +460,18 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
uses: "actions/checkout@v6"
with:
fetch-depth: 2
- name: "Download coverage files"
uses: "actions/download-artifact@v4"
uses: "actions/download-artifact@v8"
with:
path: "reports"
- name: "Upload to Codecov"
uses: "codecov/codecov-action@v3"
uses: "codecov/codecov-action@v5"
with:
directory: reports
env:
CODECOV_TOKEN: "${{ secrets.CODECOV_TOKEN }}"

View File

@@ -5,45 +5,16 @@ on:
branches:
- "*.x"
paths:
- .github/workflows/documentation.yml
- docs/**
- ".github/workflows/documentation.yml"
- "docs/**"
push:
branches:
- "*.x"
paths:
- .github/workflows/documentation.yml
- docs/**
- ".github/workflows/documentation.yml"
- "docs/**"
jobs:
validate-with-guides:
name: "Validate documentation with phpDocumentor/guides"
runs-on: "ubuntu-22.04"
steps:
- name: "Checkout code"
uses: "actions/checkout@v4"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "8.3"
- name: "Remove existing composer file"
run: "rm composer.json"
- name: "Require phpdocumentor/guides-cli"
run: "composer require --dev phpdocumentor/guides-cli --no-update"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v2"
with:
dependency-versions: "highest"
- name: "Add orphan metadata where needed"
run: |
printf '%s\n\n%s\n' ":orphan:" "$(cat docs/en/sidebar.rst)" > docs/en/sidebar.rst
printf '%s\n\n%s\n' ":orphan:" "$(cat docs/en/reference/installation.rst)" > docs/en/reference/installation.rst
- name: "Run guides-cli"
run: "vendor/bin/guides -vvv --no-progress docs/en 2>&1 | grep -v 'No template found for rendering directive' | ( ! grep WARNING )"
documentation:
name: "Documentation"
uses: "doctrine/.github/.github/workflows/documentation.yml@13.1.0"

View File

@@ -36,7 +36,7 @@ jobs:
steps:
- name: "Checkout"
uses: "actions/checkout@v4"
uses: "actions/checkout@v6"
with:
fetch-depth: 2
@@ -47,15 +47,8 @@ jobs:
coverage: "pcov"
ini-values: "zend.assertions=1, apc.enable_cli=1"
- name: "Cache dependencies installed with composer"
uses: "actions/cache@v3"
with:
path: "~/.composer/cache"
key: "php-${{ matrix.php-version }}-composer-locked-${{ hashFiles('composer.lock') }}"
restore-keys: "php-${{ matrix.php-version }}-composer-locked-"
- name: "Install dependencies with composer"
run: "composer update --no-interaction --no-progress"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
- name: "Run PHPBench"
run: "vendor/bin/phpbench run --report=default"

View File

@@ -7,7 +7,7 @@ on:
jobs:
release:
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@4.0.0"
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@13.1.0"
secrets:
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}

24
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
name: 'Close stale pull requests'
on:
schedule:
- cron: '0 3 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
stale-pr-message: >
There hasn't been any activity on this pull request in the past 90 days, so
it has been marked as stale and it will be closed automatically if no
further activity occurs in the next 7 days.
If you want to continue working on it, please leave a comment.
close-pr-message: >
This pull request was closed due to inactivity.
days-before-stale: -1
days-before-pr-stale: 90
days-before-pr-close: 7

View File

@@ -9,7 +9,6 @@ on:
- composer.*
- src/**
- phpstan*
- psalm*
- tests/StaticAnalysis/**
push:
branches:
@@ -19,7 +18,6 @@ on:
- composer.*
- src/**
- phpstan*
- psalm*
- tests/StaticAnalysis/**
jobs:
@@ -37,13 +35,13 @@ jobs:
steps:
- name: "Checkout code"
uses: "actions/checkout@v4"
uses: "actions/checkout@v6"
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
coverage: none
php-version: "8.3"
php-version: "8.4"
tools: cs2pr
- name: Require specific DBAL version
@@ -56,34 +54,3 @@ jobs:
- name: Run static analysis with phpstan/phpstan
run: "vendor/bin/phpstan analyse -c ${{ matrix.config }} --error-format=checkstyle | cs2pr"
static-analysis-psalm:
name: Static Analysis with Psalm
runs-on: ubuntu-22.04
strategy:
matrix:
dbal-version:
- default
- 3.8.2
steps:
- name: "Checkout code"
uses: "actions/checkout@v4"
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
coverage: none
php-version: "8.3"
tools: cs2pr
- name: Require specific DBAL version
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
if: "${{ matrix.dbal-version != 'default' }}"
- name: Install dependencies with Composer
uses: ramsey/composer-install@v2
- name: Run static analysis with Vimeo Psalm
run: vendor/bin/psalm --shepherd

21
.github/workflows/website-schema.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: "Website config validation"
on:
pull_request:
branches:
- "*.x"
paths:
- ".doctrine-project.json"
- ".github/workflows/website-schema.yml"
push:
branches:
- "*.x"
paths:
- ".doctrine-project.json"
- ".github/workflows/website-schema.yml"
jobs:
json-validate:
name: "Validate JSON schema"
uses: "doctrine/.github/.github/workflows/website-schema.yml@7.1.0"

View File

@@ -1,9 +1,7 @@
| [4.0.x][4.0] | [3.2.x][3.2] | [3.1.x][3.1] | [2.20.x][2.20] | [2.19.x][2.19] |
| [4.0.x][4.0] | [3.7.x][3.7] | [3.6.x][3.6] | [2.21.x][2.21] | [2.20.x][2.20] |
|:------------------------------------------------------:|:------------------------------------------------------:|:------------------------------------------------------:|:--------------------------------------------------------:|:--------------------------------------------------------:|
| [![Build status][4.0 image]][4.0] | [![Build status][3.2 image]][3.2] | [![Build status][3.1 image]][3.1] | [![Build status][2.20 image]][2.20] | [![Build status][2.19 image]][2.19] |
| [![Coverage Status][4.0 coverage image]][4.0 coverage] | [![Coverage Status][3.2 coverage image]][3.2 coverage] | [![Coverage Status][3.1 coverage image]][3.1 coverage] | [![Coverage Status][2.20 coverage image]][2.20 coverage] | [![Coverage Status][2.19 coverage image]][2.19 coverage] |
[<h1 align="center">🇺🇦 UKRAINE NEEDS YOUR HELP NOW!</h1>](https://www.doctrine-project.org/stop-war.html)
| [![Build status][4.0 image]][4.0 workflow] | [![Build status][3.7 image]][3.7 workflow] | [![Build status][3.6 image]][3.6 workflow] | [![Build status][2.21 image]][2.21 workflow] | [![Build status][2.20 image]][2.20 workflow] |
| [![Coverage Status][4.0 coverage image]][4.0 coverage] | [![Coverage Status][3.7 coverage image]][3.7 coverage] | [![Coverage Status][3.6 coverage image]][3.6 coverage] | [![Coverage Status][2.21 coverage image]][2.21 coverage] | [![Coverage Status][2.20 coverage image]][2.20 coverage] |
Doctrine ORM is an object-relational mapper for PHP 8.1+ that provides transparent persistence
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
@@ -20,21 +18,26 @@ without requiring unnecessary code duplication.
[4.0 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=4.0.x
[4.0]: https://github.com/doctrine/orm/tree/4.0.x
[4.0 workflow]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml?query=branch%3A4.0.x
[4.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/4.0.x/graph/badge.svg
[4.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/4.0.x
[3.2 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.2.x
[3.2]: https://github.com/doctrine/orm/tree/3.2.x
[3.2 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.2.x/graph/badge.svg
[3.2 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.2.x
[3.1 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.1.x
[3.1]: https://github.com/doctrine/orm/tree/3.1.x
[3.1 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.1.x/graph/badge.svg
[3.1 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.1.x
[3.7 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.7.x
[3.7]: https://github.com/doctrine/orm/tree/3.7.x
[3.7 workflow]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml?query=branch%3A3.7.x
[3.7 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.7.x/graph/badge.svg
[3.7 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.7.x
[3.6 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.6.x
[3.6]: https://github.com/doctrine/orm/tree/3.6.x
[3.6 workflow]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml?query=branch%3A3.6.x
[3.6 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.6.x/graph/badge.svg
[3.6 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.6.x
[2.21 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.21.x
[2.21]: https://github.com/doctrine/orm/tree/2.21.x
[2.21 workflow]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml?query=branch%3A2.21.x
[2.21 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.21.x/graph/badge.svg
[2.21 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.21.x
[2.20 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.20.x
[2.20]: https://github.com/doctrine/orm/tree/2.20.x
[2.20 workflow]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml?query=branch%3A2.20.x
[2.20 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.20.x/graph/badge.svg
[2.20 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.20.x
[2.19 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.19.x
[2.19]: https://github.com/doctrine/orm/tree/2.19.x
[2.19 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.19.x/graph/badge.svg
[2.19 coverage]: https://codecov.io/gh/doctrine/orm/branch/2.19.x

View File

@@ -1,5 +1,301 @@
Note about upgrading: Doctrine uses static and runtime mechanisms to raise
awareness about deprecated code.
- Use of `@deprecated` docblock that is detected by IDEs (like PHPStorm) or
Static Analysis tools (like Psalm, phpstan)
- Use of our low-overhead runtime deprecation API, details:
https://github.com/doctrine/deprecations/
# Upgrade to 3.x General Notes
We recommend you upgrade to DBAL 3 first before upgrading to ORM 3. See
the DBAL upgrade docs: https://github.com/doctrine/dbal/blob/3.10.x/UPGRADE.md
Rather than doing several major upgrades at once, we recommend you do the following:
- upgrade to DBAL 3
- deploy and monitor
- upgrade to ORM 3
- deploy and monitor
- upgrade to DBAL 4
- deploy and monitor
If you are using Symfony, the recommended minimal Doctrine Bundle version is 2.15
to run with ORM 3.
At this point, we recommend upgrading to PHP 8.4 first and then directly from
ORM 2.19 to 3.5 and up so that you can skip the lazy ghost proxy generation
and directly start using native lazy objects.
# Upgrade to 3.6
## Deprecate using string expression for default values in mappings
Using a string expression for default values in field mappings is deprecated.
Use `Doctrine\DBAL\Schema\DefaultExpression` instances instead.
Here is how to address this deprecation when mapping entities using PHP attributes:
```diff
use DateTime;
+use Doctrine\DBAL\Schema\DefaultExpression\CurrentDate;
+use Doctrine\DBAL\Schema\DefaultExpression\CurrentTime;
+use Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
final class TimeEntity
{
#[ORM\Id]
#[ORM\Column]
public int $id;
- #[ORM\Column(options: ['default' => 'CURRENT_TIMESTAMP'], insertable: false, updatable: false)]
+ #[ORM\Column(options: ['default' => new CurrentTimestamp()], insertable: false, updatable: false)]
public DateTime $createdAt;
- #[ORM\Column(options: ['default' => 'CURRENT_TIME'], insertable: false, updatable: false)]
+ #[ORM\Column(options: ['default' => new CurrentTime()], insertable: false, updatable: false)]
public DateTime $createdTime;
- #[ORM\Column(options: ['default' => 'CURRENT_DATE'], insertable: false, updatable: false)]
+ #[ORM\Column(options: ['default' => new CurrentDate()], insertable: false, updatable: false)]
public DateTime $createdDate;
}
```
Here is how to do the same when mapping entities using XML:
```diff
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\ORM\Functional\XmlTimeEntity">
<id name="id" type="integer" column="id">
<generator strategy="AUTO"/>
</id>
<field name="createdAt" type="datetime" insertable="false" updatable="false">
<options>
- <option name="default">CURRENT_TIMESTAMP</option>
+ <option name="default">
+ <object class="Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp"/>
+ </option>
</options>
</field>
<field name="createdAtImmutable" type="datetime_immutable" insertable="false" updatable="false">
<options>
- <option name="default">CURRENT_TIMESTAMP</option>
+ <option name="default">
+ <object class="Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp"/>
+ </option>
</options>
</field>
<field name="createdTime" type="time" insertable="false" updatable="false">
<options>
- <option name="default">CURRENT_TIME</option>
+ <option name="default">
+ <object class="Doctrine\DBAL\Schema\DefaultExpression\CurrentTime"/>
+ </option>
</options>
</field>
<field name="createdDate" type="date" insertable="false" updatable="false">
<options>
- <option name="default">CURRENT_DATE</option>
+ <option name="default">
+ <object class="Doctrine\DBAL\Schema\DefaultExpression\CurrentDate"/>
+ </option>
</options>
</field>
</entity>
</doctrine-mapping>
```
## Deprecate `FieldMapping::$default`
The `default` property of `Doctrine\ORM\Mapping\FieldMapping` is deprecated and
will be removed in 4.0. Instead, use `FieldMapping::$options['default']`.
## Deprecate specifying `nullable` on columns that end up being used in a primary key
Specifying `nullable` on join columns that are part of a primary key is
deprecated and will be an error in 4.0.
This can happen when using a join column mapping together with an id mapping,
or when using a join column mapping or an inverse join column mapping on a
many-to-many relationship.
```diff
class User
{
#[ORM\Id]
#[ORM\Column(type: 'integer')]
private int $id;
#[ORM\Id]
#[ORM\ManyToOne(targetEntity: Family::class, inversedBy: 'users')]
- #[ORM\JoinColumn(name: 'family_id', referencedColumnName: 'id', nullable: true)]
+ #[ORM\JoinColumn(name: 'family_id', referencedColumnName: 'id')]
private ?Family $family;
#[ORM\ManyToMany(targetEntity: Group::class)]
#[ORM\JoinTable(name: 'user_group')]
- #[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id', nullable: true)]
- #[ORM\InverseJoinColumn(name: 'group_id', referencedColumnName: 'id', nullable: true)]
+ #[ORM\JoinColumn(name: 'user_id', referencedColumnName: 'id')]
+ #[ORM\InverseJoinColumn(name: 'group_id', referencedColumnName: 'id')]
private Collection $groups;
}
```
## Deprecate `Doctrine\ORM\QueryBuilder::add('join', ...)` with a list of join parts
Using `Doctrine\ORM\QueryBuilder::add('join', ...)` with a list of join parts
is deprecated in favor of using an associative array of join parts with the
root alias as key.
## Deprecate using the `WITH` keyword for arbitrary DQL joins
Using the `WITH` keyword to specify the condition for an arbitrary DQL join is
deprecated in favor of using the `ON` keyword (similar to the SQL syntax for
joins).
The `WITH` keyword is now meant to be used only for filtering conditions in
association joins.
# Upgrade to 3.5
See the General notes to upgrading to 3.x versions above.
## Deprecate not using native lazy objects on PHP 8.4+
Having native lazy objects disabled on PHP 8.4+ is deprecated and will not be
possible in 4.0.
You can enable them through configuration:
```php
$config->enableNativeLazyObjects(true);
```
As a consequence, methods, parameters and commands related to userland lazy
objects have been deprecated on PHP 8.4+:
- `Doctrine\ORM\Tools\Console\Command\GenerateProxiesCommand`
- `Doctrine\ORM\Configuration::getAutoGenerateProxyClasses()`
- `Doctrine\ORM\Configuration::getProxyDir()`
- `Doctrine\ORM\Configuration::getProxyNamespace()`
- `Doctrine\ORM\Configuration::setAutoGenerateProxyClasses()`
- `Doctrine\ORM\Configuration::setProxyDir()`
- `Doctrine\ORM\Configuration::setProxyNamespace()`
- Passing more than one argument to `Doctrine\ORM\Proxy\ProxyFactory::__construct()`
Additionally, some methods of ORMSetup have been deprecated in favor of a new
counterpart.
- `Doctrine\ORM\ORMSetup::createAttributeMetadataConfiguration()` is deprecated in favor of
`Doctrine\ORM\ORMSetup::createAttributeMetadataConfig()`
- `Doctrine\ORM\ORMSetup::createXMLMetadataConfiguration()` is deprecated in favor of
`Doctrine\ORM\ORMSetup::createXMLMetadataConfig()`
- `Doctrine\ORM\ORMSetup::createConfiguration()` is deprecated in favor of
`Doctrine\ORM\ORMSetup::createConfig()`
## Deprecate methods for configuring no longer configurable features
Since 3.0, lazy ghosts are enabled unconditionally, and so is rejecting ID
collisions in the identity map.
As a consequence, the following methods are deprecated and will be removed in 4.0:
* `Doctrine\ORM\Configuration::setLazyGhostObjectEnabled()`
* `Doctrine\ORM\Configuration::isLazyGhostObjectEnabled()`
* `Doctrine\ORM\Configuration::setRejectIdCollisionInIdentityMap()`
* `Doctrine\ORM\Configuration::isRejectIdCollisionInIdentityMapEnabled()`
# Upgrade to 3.4.1
## BC BREAK: You can no longer use the `.*` notation to get all fields of an entity in a DTO
This feature was introduced in 3.4.0, and introduces several issues, so we
decide to remove it before it is used too widely.
# Upgrade to 3.4
See the General notes to upgrading to 3.x versions above.
## Discriminator Map class duplicates
Using the same class several times in a discriminator map is deprecated.
In 4.0, this will be an error.
## `Doctrine\ORM\Mapping\ClassMetadata::$reflFields` deprecated
To better support property hooks and lazy proxies in the future, `$reflFields` had to
be deprecated because we cannot use the PHP internal reflection API directly anymore.
The property was changed from an array to an object of type `LegacyReflectionFields`
that implements `ArrayAccess`.
Use the new `Doctrine\ORM\Mapping\PropertyAccessors\PropertyAccessor` API and access
through `Doctrine\ORM\Mapping\ClassMetadata::$propertyAccessors` instead.
Companion accessor methods are deprecated as well.
# Upgrade to 3.3
See the General notes to upgrading to 3.x versions above.
## Deprecate `DatabaseDriver`
The class `Doctrine\ORM\Mapping\Driver\DatabaseDriver` is deprecated without replacement.
## Add `Doctrine\ORM\Query\OutputWalker` interface, deprecate `Doctrine\ORM\Query\SqlWalker::getExecutor()`
Output walkers should implement the new `\Doctrine\ORM\Query\OutputWalker` interface and create
`Doctrine\ORM\Query\Exec\SqlFinalizer` instances instead of `Doctrine\ORM\Query\Exec\AbstractSqlExecutor`s.
The output walker must not base its workings on the query `firstResult`/`maxResult` values, so that the
`SqlFinalizer` can be kept in the query cache and used regardless of the actual `firstResult`/`maxResult` values.
Any operation dependent on `firstResult`/`maxResult` should take place within the `SqlFinalizer::createExecutor()`
method. Details can be found at https://github.com/doctrine/orm/pull/11188.
# Upgrade to 3.2
See the General notes to upgrading to 3.x versions above.
## Deprecate the `NotSupported` exception
The class `Doctrine\ORM\Exception\NotSupported` is deprecated without replacement.
## Deprecate remaining `Serializable` implementation
Relying on `SequenceGenerator` implementing the `Serializable` is deprecated
because that interface won't be implemented in ORM 4 anymore.
The following methods are deprecated:
* `SequenceGenerator::serialize()`
* `SequenceGenerator::unserialize()`
## `orm:schema-tool:update` option `--complete` is deprecated
That option behaves as a no-op, and is deprecated. It will be removed in 4.0.
## Deprecate properties `$indexes` and `$uniqueConstraints` of `Doctrine\ORM\Mapping\Table`
The properties `$indexes` and `$uniqueConstraints` have been deprecated since they had no effect at all.
The preferred way of defining indices and unique constraints is by
using the `\Doctrine\ORM\Mapping\UniqueConstraint` and `\Doctrine\ORM\Mapping\Index` attributes.
# Upgrade to 3.1
See the General notes to upgrading to 3.x versions above.
## Deprecate `Doctrine\ORM\Mapping\ReflectionEnumProperty`
This class is deprecated and will be removed in 4.0.
@@ -23,6 +319,8 @@ Using array access on instances of the following classes is deprecated:
# Upgrade to 3.0
See the General notes to upgrading to 3.x versions above.
## BC BREAK: Calling `ClassMetadata::getAssociationMappedByTargetField()` with the owning side of an association now throws an exception
Previously, calling
@@ -48,6 +346,9 @@ so `$targetEntity` is a first argument now. This change affects only non-named a
When using the `AUTO` strategy to let Doctrine determine the identity generation mechanism for
an entity, and when using `doctrine/dbal` 4, PostgreSQL now uses `IDENTITY`
instead of `SEQUENCE` or `SERIAL`.
There are three ways to handle this change.
* If you want to upgrade your existing tables to identity columns, you will need to follow [migration to identity columns on PostgreSQL](https://www.doctrine-project.org/projects/doctrine-dbal/en/4.0/how-to/postgresql-identity-migration.html)
* If you want to keep using SQL sequences, you need to configure the ORM this way:
```php
@@ -60,6 +361,27 @@ $configuration->setIdentityGenerationPreferences([
PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_SEQUENCE,
]);
```
* You can change individual entities to use the `SEQUENCE` strategy instead of `AUTO`:
```php
diff --git a/src/Entity/Example.php b/src/Entity/Example.php
index 28be8df378..3b7d61bda6 100644
--- a/src/Entity/Example.php
+++ b/src/Entity/Example.php
@@ -38,7 +38,7 @@ class Example
#[ORM\Id]
#[ORM\Column(type: 'integer')]
- #[ORM\GeneratedValue(strategy: 'AUTO')]
+ #[ORM\GeneratedValue(strategy: 'SEQUENCE')]
private int $id;
#[Assert\Length(max: 255)]
```
The later two options require a small database migration that will remove the default
expression fetching the next value from the sequence. It's not strictly necessary to
do this migration because the code will work anyway. A benefit of this approach is
that you can just make and roll out the code changes first and then migrate the database later.
## BC BREAK: Throw exceptions when using illegal attributes on Embeddable
@@ -69,12 +391,44 @@ now they throw an exception.
## BC BREAK: Partial objects are removed
- The `PARTIAL` keyword in DQL no longer exists.
- `Doctrine\ORM\Query\AST\PartialObjectExpression`is removed.
- `Doctrine\ORM\Query\SqlWalker::HINT_PARTIAL` and
WARNING: This was relaxed in ORM 3.2 when partial was re-allowed for array-hydration.
- The `PARTIAL` keyword in DQL no longer exists (reintroduced in ORM 3.2)
- `Doctrine\ORM\Query\AST\PartialObjectExpression` is removed. (reintroduced in ORM 3.2)
- `Doctrine\ORM\Query\SqlWalker::HINT_PARTIAL` (reintroduced in ORM 3.2) and
`Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD` are removed.
- `Doctrine\ORM\EntityManager*::getPartialReference()` is removed.
## BC BREAK: Enforce ArrayCollection Type on `\Doctrine\ORM\QueryBuilder::setParameters(ArrayCollection $parameters)`
The argument $parameters can no longer be a key=>value array. Only ArrayCollection types are allowed.
### Before
```php
$qb = $em->createQueryBuilder()
->select('u')
->from('User', 'u')
->where('u.id = :user_id1 OR u.id = :user_id2')
->setParameters(array(
'user_id1' => 1,
'user_id2' => 2
));
```
### After
```php
$qb = $em->createQueryBuilder()
->select('u')
->from('User', 'u')
->where('u.id = :user_id1 OR u.id = :user_id2')
->setParameters(new ArrayCollection(array(
new Parameter('user_id1', 1),
new Parameter('user_id2', 2)
)));
```
## BC BREAK: `Doctrine\ORM\Persister\Entity\EntityPersister::executeInserts()` return type changed to `void`
Implementors should adapt to the new signature, and should call
@@ -697,6 +1051,42 @@ following classes and methods:
Use `toIterable()` instead.
# Upgrade to 2.20
## Add `Doctrine\ORM\Query\OutputWalker` interface, deprecate `Doctrine\ORM\Query\SqlWalker::getExecutor()`
Output walkers should implement the new `\Doctrine\ORM\Query\OutputWalker` interface and create
`Doctrine\ORM\Query\Exec\SqlFinalizer` instances instead of `Doctrine\ORM\Query\Exec\AbstractSqlExecutor`s.
The output walker must not base its workings on the query `firstResult`/`maxResult` values, so that the
`SqlFinalizer` can be kept in the query cache and used regardless of the actual `firstResult`/`maxResult` values.
Any operation dependent on `firstResult`/`maxResult` should take place within the `SqlFinalizer::createExecutor()`
method. Details can be found at https://github.com/doctrine/orm/pull/11188.
## Explictly forbid property hooks
Property hooks are not supported yet by Doctrine ORM. Until support is added,
they are explicitly forbidden because the support would result in a breaking
change in behavior.
Progress on this is tracked at https://github.com/doctrine/orm/issues/11624 .
## PARTIAL DQL syntax is undeprecated
Use of the PARTIAL keyword is not deprecated anymore in DQL, because we will be
able to support PARTIAL objects with PHP 8.4 Lazy Objects and
Symfony/VarExporter in a better way. When we decided to remove this feature
these two abstractions did not exist yet.
WARNING: If you want to upgrade to 3.x and still use PARTIAL keyword in DQL
with array or object hydrators, then you have to directly migrate to ORM 3.3.x or higher.
PARTIAL keyword in DQL is not available in 3.0, 3.1 and 3.2 of ORM.
## Deprecate `\Doctrine\ORM\Query\Parser::setCustomOutputTreeWalker()`
Use the `\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER` query hint to set the output walker
class instead of setting it through the `\Doctrine\ORM\Query\Parser::setCustomOutputTreeWalker()` method
on the parser instance.
# Upgrade to 2.19
## Deprecate calling `ClassMetadata::getAssociationMappedByTargetField()` with the owning side of an association
@@ -1911,7 +2301,7 @@ from 2.0 have to configure the annotation driver if they don't use `Configuratio
## Scalar mappings can now be omitted from DQL result
You are now allowed to mark scalar SELECT expressions as HIDDEN an they are not hydrated anymore.
You are now allowed to mark scalar SELECT expressions as HIDDEN and they are not hydrated anymore.
Example:
SELECT u, SUM(a.id) AS HIDDEN numArticles FROM User u LEFT JOIN u.Articles a ORDER BY numArticles DESC HAVING numArticles > 10

View File

@@ -3,6 +3,11 @@
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnNotice="true"
failOnWarning="true"
failOnRisky="true"
cacheDirectory=".phpunit.cache"
>
@@ -19,6 +24,7 @@
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
<env name="DOCTRINE_DEPRECATIONS" value="trigger"/>
</php>
<testsuites>
@@ -27,7 +33,7 @@
</testsuite>
</testsuites>
<source>
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory suffix=".php">../../../src</directory>
</include>

View File

@@ -3,6 +3,11 @@
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnNotice="true"
failOnWarning="true"
failOnRisky="true"
cacheDirectory=".phpunit.cache"
>
@@ -19,6 +24,7 @@
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
<env name="DOCTRINE_DEPRECATIONS" value="trigger"/>
</php>
<testsuites>
@@ -27,7 +33,7 @@
</testsuite>
</testsuites>
<source>
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory suffix=".php">../../../src</directory>
</include>

View File

@@ -3,6 +3,11 @@
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnNotice="true"
failOnWarning="true"
failOnRisky="true"
cacheDirectory=".phpunit.cache"
>
@@ -16,6 +21,7 @@
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
<env name="DOCTRINE_DEPRECATIONS" value="trigger"/>
</php>
<testsuites>
@@ -24,7 +30,7 @@
</testsuite>
</testsuites>
<source>
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory suffix=".php">../../../src</directory>
</include>

View File

@@ -3,6 +3,11 @@
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnNotice="true"
failOnWarning="true"
failOnRisky="true"
cacheDirectory=".phpunit.cache"
>
@@ -14,6 +19,7 @@
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
<env name="DOCTRINE_DEPRECATIONS" value="trigger"/>
</php>
<testsuites>
@@ -22,7 +28,7 @@
</testsuite>
</testsuites>
<source>
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory suffix=".php">../../../src</directory>
</include>

View File

@@ -3,6 +3,11 @@
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnNotice="true"
failOnWarning="true"
failOnRisky="true"
cacheDirectory=".phpunit.cache"
>
@@ -16,6 +21,7 @@
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
<env name="DOCTRINE_DEPRECATIONS" value="trigger"/>
</php>
<testsuites>
@@ -24,7 +30,7 @@
</testsuite>
</testsuites>
<source>
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory suffix=".php">../../../src</directory>
</include>

View File

@@ -3,6 +3,11 @@
xsi:noNamespaceSchemaLocation="../../../vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnNotice="true"
failOnWarning="true"
failOnRisky="true"
cacheDirectory=".phpunit.cache"
>
@@ -14,6 +19,7 @@
<!-- necessary change for some CLI/console output test assertions -->
<env name="COLUMNS" value="120"/>
<env name="DOCTRINE_DEPRECATIONS" value="trigger"/>
</php>
<testsuites>
@@ -22,7 +28,7 @@
</testsuite>
</testsuites>
<source>
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory suffix=".php">../../../src</directory>
</include>

View File

@@ -1,28 +1,39 @@
{
"name": "doctrine/orm",
"type": "library",
"description": "Object-Relational-Mapper for PHP",
"keywords": ["orm", "database"],
"homepage": "https://www.doctrine-project.org/projects/orm.html",
"license": "MIT",
"authors": [
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
{"name": "Marco Pivetta", "email": "ocramius@gmail.com"}
"type": "library",
"keywords": [
"orm",
"database"
],
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true
"authors": [
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
"sort-packages": true
},
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com"
}
],
"homepage": "https://www.doctrine-project.org/projects/orm.html",
"require": {
"php": "^8.1",
"composer-runtime-api": "^2",
"ext-ctype": "*",
"composer-runtime-api": "^2",
"doctrine/collections": "^2.2",
"doctrine/dbal": "^3.8.2 || ^4",
"doctrine/deprecations": "^0.5.3 || ^1",
@@ -30,36 +41,46 @@
"doctrine/inflector": "^1.4 || ^2.0",
"doctrine/instantiator": "^1.3 || ^2",
"doctrine/lexer": "^3",
"doctrine/persistence": "^3.3.1",
"doctrine/persistence": "^3.3.1 || ^4",
"psr/cache": "^1 || ^2 || ^3",
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/var-exporter": "^6.3.9 || ^7.0"
"symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0",
"symfony/var-exporter": "^6.3.9 || ^7.0 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^12.0",
"doctrine/coding-standard": "^14.0",
"phpbench/phpbench": "^1.0",
"phpstan/phpstan": "1.10.59",
"phpunit/phpunit": "^10.4.0",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "2.1.23",
"phpstan/phpstan-deprecation-rules": "^2",
"phpunit/phpunit": "^10.5.0 || ^11.5",
"psr/log": "^1 || ^2 || ^3",
"squizlabs/php_codesniffer": "3.7.2",
"symfony/cache": "^5.4 || ^6.2 || ^7.0",
"vimeo/psalm": "5.22.2"
"symfony/cache": "^5.4 || ^6.2 || ^7.0 || ^8.0"
},
"suggest": {
"ext-dom": "Provides support for XSD validation for XML mapping files",
"symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0"
},
"autoload": {
"psr-4": { "Doctrine\\ORM\\": "src" }
"psr-4": {
"Doctrine\\ORM\\": "src"
}
},
"autoload-dev": {
"psr-4": {
"Doctrine\\Tests\\": "tests/Tests",
"Doctrine\\Performance\\": "tests/Performance",
"Doctrine\\StaticAnalysis\\": "tests/StaticAnalysis",
"Doctrine\\Performance\\": "tests/Performance"
"Doctrine\\Tests\\": "tests/Tests"
}
},
"archive": {
"exclude": ["!vendor", "tests", "*phpunit.xml", "build.xml", "build.properties", "composer.phar", "vendor/satooshi", "lib/vendor", "*.swp"]
"config": {
"allow-plugins": {
"composer/package-versions-deprecated": true,
"dealerdirect/phpcodesniffer-composer-installer": true,
"phpstan/extension-installer": true
},
"sort-packages": true
},
"scripts": {
"docs": "composer --working-dir docs update && ./docs/vendor/bin/build-docs.sh @additional_args"
}
}

3
docs/.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
composer.lock
vendor/
output/

View File

@@ -1,18 +1,18 @@
# Doctrine ORM Documentation
The documentation is written in [ReStructured Text](https://docutils.sourceforge.io/rst.html).
## How to Generate:
Using Ubuntu 14.04 LTS:
1. Run ./bin/install-dependencies.sh
2. Run ./bin/generate-docs.sh
In the project root, run
It will generate the documentation into the build directory of the checkout.
composer docs
This will generate the documentation into the `docs/output` subdirectory.
## Theme issues
To browse the documentation, you need to run a webserver:
If you get a "Theme error", check if the `en/_theme` subdirectory is empty,
in which case you will need to run:
cd docs/output
php -S localhost:8000
1. git submodule init
2. git submodule update
Now the documentation is available at [http://localhost:8000](http://localhost:8000).

View File

@@ -1,10 +0,0 @@
#!/bin/bash
EXECPATH=`dirname $0`
cd $EXECPATH
cd ..
rm build -Rf
sphinx-build en build
sphinx-build -b latex en build/pdf
rubber --into build/pdf --pdf build/pdf/Doctrine2ORM.tex

View File

@@ -1,2 +0,0 @@
#!/bin/bash
sudo apt-get update && sudo apt-get install -y python2.7 python-sphinx python-pygments

9
docs/composer.json Normal file
View File

@@ -0,0 +1,9 @@
{
"name": "doctrine/orm-docs",
"description": "Documentation for the Object-Relational Mapper\"",
"type": "library",
"license": "MIT",
"require-dev": {
"doctrine/docs-builder": "^1.0"
}
}

View File

@@ -1,89 +0,0 @@
# Makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Doctrine2ORM.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Doctrine2ORM.qhc"
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
"run these through (pdf)latex."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

View File

@@ -1,91 +0,0 @@
#Copyright (c) 2010 Fabien Potencier
#
#Permission is hereby granted, free of charge, to any person obtaining a copy
#of this software and associated documentation files (the "Software"), to deal
#in the Software without restriction, including without limitation the rights
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#copies of the Software, and to permit persons to whom the Software is furnished
#to do so, subject to the following conditions:
#
#The above copyright notice and this permission notice shall be included in all
#copies or substantial portions of the Software.
#
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
#THE SOFTWARE.
from docutils.parsers.rst import Directive, directives
from docutils import nodes
from string import upper
class configurationblock(nodes.General, nodes.Element):
pass
class ConfigurationBlock(Directive):
has_content = True
required_arguments = 0
optional_arguments = 0
final_argument_whitespace = True
option_spec = {}
formats = {
'html': 'HTML',
'xml': 'XML',
'php': 'PHP',
'jinja': 'Twig',
'html+jinja': 'Twig',
'jinja+html': 'Twig',
'php+html': 'PHP',
'html+php': 'PHP',
'ini': 'INI',
}
def run(self):
env = self.state.document.settings.env
node = nodes.Element()
node.document = self.state.document
self.state.nested_parse(self.content, self.content_offset, node)
entries = []
for i, child in enumerate(node):
if isinstance(child, nodes.literal_block):
# add a title (the language name) before each block
#targetid = "configuration-block-%d" % env.new_serialno('configuration-block')
#targetnode = nodes.target('', '', ids=[targetid])
#targetnode.append(child)
innernode = nodes.emphasis(self.formats[child['language']], self.formats[child['language']])
para = nodes.paragraph()
para += [innernode, child]
entry = nodes.list_item('')
entry.append(para)
entries.append(entry)
resultnode = configurationblock()
resultnode.append(nodes.bullet_list('', *entries))
return [resultnode]
def visit_configurationblock_html(self, node):
self.body.append(self.starttag(node, 'div', CLASS='configuration-block'))
def depart_configurationblock_html(self, node):
self.body.append('</div>\n')
def visit_configurationblock_latex(self, node):
pass
def depart_configurationblock_latex(self, node):
pass
def setup(app):
app.add_node(configurationblock,
html=(visit_configurationblock_html, depart_configurationblock_html),
latex=(visit_configurationblock_latex, depart_configurationblock_latex))
app.add_directive('configuration-block', ConfigurationBlock)

Submodule docs/en/_theme deleted from 6f1bc8bead

View File

@@ -352,7 +352,7 @@ the database using a FOR UPDATE.
use Bank\Entities\Account;
use Doctrine\DBAL\LockMode;
$account = $em->find(Account::class, $accId, LockMode::PESSIMISTIC_READ);
$account = $em->find(Account::class, $accId, LockMode::PESSIMISTIC_WRITE);
Keeping Updates and Deletes in Sync
-----------------------------------

View File

@@ -40,7 +40,8 @@ Now this is all awfully technical, so let me come to some use-cases
fast to keep you motivated. Using walker implementation you can for
example:
- Modify the Output walker to get the raw SQL via ``Query->getSQL()``
with interpolated parameters.
- Modify the AST to generate a Count Query to be used with a
paginator for any given DQL query.
- Modify the Output Walker to generate vendor-specific SQL
@@ -50,7 +51,7 @@ example:
- Modify the Output walker to pretty print the SQL for debugging
purposes.
In this cookbook-entry I will show examples of the first two
In this cookbook-entry I will show examples of the first three
points. There are probably much more use-cases.
Generic count query for pagination
@@ -101,8 +102,16 @@ The ``Paginate::count(Query $query)`` looks like:
{
static public function count(Query $query)
{
/** @var Query $countQuery */
$countQuery = clone $query;
/*
To avoid changing the $query passed into the method and to make sure a possibly existing
ResultSetMapping is discarded, we create a new query object any copy relevant data over.
*/
$countQuery = new Query($query->getEntityManager());
$countQuery->setDQL($query->getDQL());
$countQuery->setParameters(clone $query->getParameters());
foreach ($query->getHints() as $name => $value) {
$countQuery->setHint($name, $value);
}
$countQuery->setHint(Query::HINT_CUSTOM_TREE_WALKERS, array('DoctrineExtensions\Paginate\CountSqlWalker'));
$countQuery->setFirstResult(null)->setMaxResults(null);
@@ -111,7 +120,7 @@ The ``Paginate::count(Query $query)`` looks like:
}
}
It clones the query, resets the limit clause first and max results
This resets the limit clause first and max results
and registers the ``CountSqlWalker`` custom tree walker which
will modify the AST to execute a count query. The walkers
implementation is:
@@ -215,3 +224,39 @@ huge benefits with using vendor specific features. This would still
allow you write DQL queries instead of NativeQueries to make use of
vendor specific features.
Modifying the Output Walker to get the raw SQL with interpolated parameters
---------------------------------------------------------------------------
Sometimes we may want to log or trace the raw SQL being generated from its DQL
for profiling slow queries afterwards or audit queries that changed many rows
``$query->getSQL()`` will give us the prepared statement being passed to database
with all values of SQL parameters being replaced by positional ``?`` or named ``:name``
as parameters are interpolated into prepared statements by the database while executing the SQL.
``$query->getParameters()`` will give us details about SQL parameters that we've provided.
So we can create an output walker to interpolate all SQL parameters that will be
passed into prepared statement in PHP before database handle them internally:
.. literalinclude:: dql-custom-walkers/InterpolateParametersSQLOutputWalker.php
:language: php
Then you may get the raw SQL with this output walker:
.. code-block:: php
<?php
$query
->where('t.int IN (:ints)')->setParameter(':ints', [1, 2])
->orWhere('t.string IN (?0)')->setParameter(0, ['3', '4'])
->orWhere("t.bool = ?1")->setParameter('?1', true)
->orWhere("t.string = :string")->setParameter(':string', 'ABC')
->setHint(\Doctrine\ORM\Query::HINT_CUSTOM_OUTPUT_WALKER, InterpolateParametersSQLOutputWalker::class)
->getSQL();
The where clause of the returned SQL should be like:
.. code-block:: sql
WHERE t0_.int IN (1, 2)
OR t0_.string IN ('3', '4')
OR t0_.bool = 1
OR t0_.string = 'ABC'

View File

@@ -0,0 +1,47 @@
<?php
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Types\BooleanType;
use Doctrine\DBAL\Types\Exception\ValueNotConvertible;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Query\AST;
use Doctrine\ORM\Query\SqlOutputWalker;
class InterpolateParametersSQLOutputWalker extends SqlOutputWalker
{
/** {@inheritdoc} */
public function walkInputParameter(AST\InputParameter $inputParam): string
{
$parameter = $this->getQuery()->getParameter($inputParam->name);
if ($parameter === null) {
return '?';
}
$value = $parameter->getValue();
/** @var ParameterType|ArrayParameterType|int|string $typeName */
/** @see \Doctrine\ORM\Query\ParameterTypeInferer::inferType() */
$typeName = $parameter->getType();
$platform = $this->getConnection()->getDatabasePlatform();
$processParameterType = static fn(ParameterType $type) => static fn($value): string =>
(match ($type) { /** @see Type::getBindingType() */
ParameterType::NULL => 'NULL',
ParameterType::INTEGER => $value,
ParameterType::BOOLEAN => (new BooleanType())->convertToDatabaseValue($value, $platform),
ParameterType::STRING, ParameterType::ASCII => $platform->quoteStringLiteral($value),
default => throw new ValueNotConvertible($value, $type->name)
});
if (is_string($typeName) && Type::hasType($typeName)) {
return Type::getType($typeName)->convertToDatabaseValue($value, $platform);
}
if ($typeName instanceof ParameterType) {
return $processParameterType($typeName)($value);
}
if ($typeName instanceof ArrayParameterType && is_array($value)) {
$type = ArrayParameterType::toElementParameterType($typeName);
return implode(', ', array_map($processParameterType($type), $value));
}
throw new ValueNotConvertible($value, $typeName);
}
}

View File

@@ -232,6 +232,33 @@ vendors SQL parser to show us further errors in the parsing
process, for example if the Unit would not be one of the supported
values by MySql.
Typed functions
---------------
By default, result of custom functions is fetched as-is from the database driver.
If you want to be sure that the type is always the same, then your custom function needs to
implement ``Doctrine\ORM\Query\AST\TypedExpression``. Then, the result is wired
through ``Doctrine\DBAL\Types\Type::convertToPhpValue()`` of the ``Type`` returned in ``getReturnType()``.
.. code-block:: php
<?php
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Query\AST\Functions\FunctionNode;
use Doctrine\ORM\Query\AST\TypedExpression;
class DateDiff extends FunctionNode implements TypedExpression
{
// ...
public function getReturnType(): Type
{
return Type::getType(Types::INTEGER);
}
}
Conclusion
----------

View File

@@ -0,0 +1,44 @@
Generated Columns
=================
Generated columns, sometimes also called virtual columns, are populated by
the database engine itself. They are a tool for performance optimization, to
avoid calculating a value on each query.
You can define generated columns on entities and have Doctrine map the values
to your entity.
Declaring a generated column
----------------------------
There is no explicit mapping instruction for generated columns. Instead, you
specify that the column should not be written to, and define a custom column
definition.
.. literalinclude:: generated-columns/Person.php
:language: php
* ``insertable``, ``updatable``: Setting these to false tells Doctrine to never
write this column - writing to a generated column would result in an error
from the database.
* ``columnDefinition``: We specify the full DDL to create the column. To allow
to use database specific features, this attribute does not use Doctrine Query
Language but native SQL. Note that you need to reference columns by their
database name (either explicitly set in the mapping or per the current
:doc:`naming strategy <../reference/namingstrategy>`).
Be aware that specifying a column definition makes the ``SchemaTool``
completely ignore all other configuration for this column. See also
:ref:`#[Column] <attrref_column>`
* ``generated``: Specifying that this column is always generated tells Doctrine
to update the field on the entity with the value from the database after
every write operation.
Advanced example: Extracting a value from a JSON structure
----------------------------------------------------------
Lets assume we have an entity that stores a blogpost as structured JSON.
To avoid extracting all titles on the fly when listing the posts, we create a
generated column with the field.
.. literalinclude:: generated-columns/Article.php
:language: php

View File

@@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Article
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private int $id;
/**
* When working with Postgres, it is recommended to use the jsonb
* format for better performance.
*/
#[ORM\Column(options: ['jsonb' => true])]
private array $content;
/**
* Because we specify NOT NULL, inserting will fail if the content does
* not have a string in the title field.
*/
#[ORM\Column(
insertable: false,
updatable: false,
columnDefinition: "VARCHAR(255) generated always as (content->>'title') stored NOT NULL",
generated: 'ALWAYS',
)]
private string $title;
}

View File

@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Person
{
#[ORM\Column(type: 'string')]
private string $firstName;
#[ORM\Column(type: 'string', name: 'name')]
private string $lastName;
#[ORM\Column(
type: 'string',
insertable: false,
updatable: false,
columnDefinition: "VARCHAR(255) GENERATED ALWAYS AS (concat(firstName, ' ', name) stored NOT NULL",
generated: 'ALWAYS',
)]
private string $fullName;
}

View File

@@ -46,17 +46,18 @@ entities:
#[Entity]
class Article
{
const STATUS_VISIBLE = 'visible';
const STATUS_INVISIBLE = 'invisible';
public const STATUS_VISIBLE = 'visible';
public const STATUS_INVISIBLE = 'invisible';
#[Column(type: "string")]
private $status;
public function setStatus($status)
public function setStatus(string $status): void
{
if (!in_array($status, array(self::STATUS_VISIBLE, self::STATUS_INVISIBLE))) {
if (!in_array($status, [self::STATUS_VISIBLE, self::STATUS_INVISIBLE], true)) {
throw new \InvalidArgumentException("Invalid status");
}
$this->status = $status;
}
}
@@ -92,37 +93,33 @@ For example for the previous enum type:
class EnumVisibilityType extends Type
{
const ENUM_VISIBILITY = 'enumvisibility';
const STATUS_VISIBLE = 'visible';
const STATUS_INVISIBLE = 'invisible';
private const ENUM_VISIBILITY = 'enumvisibility';
private const STATUS_VISIBLE = 'visible';
private const STATUS_INVISIBLE = 'invisible';
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
{
return "ENUM('visible', 'invisible')";
}
public function convertToPHPValue($value, AbstractPlatform $platform)
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed
{
return $value;
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): string
{
if (!in_array($value, array(self::STATUS_VISIBLE, self::STATUS_INVISIBLE))) {
if (!in_array($value, [self::STATUS_VISIBLE, self::STATUS_INVISIBLE], true)) {
throw new \InvalidArgumentException("Invalid status");
}
return $value;
}
public function getName()
public function getName(): string
{
return self::ENUM_VISIBILITY;
}
public function requiresSQLCommentHint(AbstractPlatform $platform)
{
return true;
}
}
You can register this type with ``Type::addType('enumvisibility', 'MyProject\DBAL\EnumVisibilityType');``.
@@ -151,37 +148,33 @@ You can generalize this approach easily to create a base class for enums:
abstract class EnumType extends Type
{
protected $name;
protected $values = array();
protected $values = [];
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
{
$values = array_map(function($val) { return "'".$val."'"; }, $this->values);
$values = array_map(fn($val) => "'".$val."'", $this->values);
return "ENUM(".implode(", ", $values).")";
}
public function convertToPHPValue($value, AbstractPlatform $platform)
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed
{
return $value;
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): mixed
{
if (!in_array($value, $this->values)) {
if (!in_array($value, $this->values, true)) {
throw new \InvalidArgumentException("Invalid '".$this->name."' value.");
}
return $value;
}
public function getName()
public function getName(): string
{
return $this->name;
}
public function requiresSQLCommentHint(AbstractPlatform $platform)
{
return true;
}
}
With this base class you can define an enum as easily as:
@@ -194,5 +187,5 @@ With this base class you can define an enum as easily as:
class EnumVisibilityType extends EnumType
{
protected $name = 'enumvisibility';
protected $values = array('visible', 'invisible');
protected $values = ['visible', 'invisible'];
}

View File

@@ -11,7 +11,7 @@ What we offer are hooks to execute any kind of validation.
.. note::
You don't need to validate your entities in the lifecycle
events. Its only one of many options. Of course you can also
events. It is only one of many options. Of course you can also
perform validations in value setters or any other method of your
entities that are used in your code.

View File

@@ -13,7 +13,6 @@ If this documentation is not helping to answer questions you have about
Doctrine ORM don't panic. You can get help from different sources:
- There is a :doc:`FAQ <reference/faq>` with answers to frequent questions.
- The `Doctrine Mailing List <https://groups.google.com/group/doctrine-user>`_
- Slack chat room `#orm <https://www.doctrine-project.org/slack>`_
- Report a bug on `GitHub <https://github.com/doctrine/orm/issues>`_.
- On `StackOverflow <https://stackoverflow.com/questions/tagged/doctrine-orm>`_
@@ -73,6 +72,8 @@ Advanced Topics
* :doc:`TypedFieldMapper <reference/typedfieldmapper>`
* :doc:`Improving Performance <reference/improving-performance>`
* :doc:`Caching <reference/caching>`
* :doc:`Partial Hydration <reference/partial-hydration>`
* :doc:`Partial Objects <reference/partial-objects>`
* :doc:`Change Tracking Policies <reference/change-tracking-policies>`
* :doc:`Best Practices <reference/best-practices>`
* :doc:`Metadata Drivers <reference/metadata-drivers>`
@@ -100,6 +101,7 @@ Cookbook
* **Patterns**:
:doc:`Aggregate Fields <cookbook/aggregate-fields>` \|
:doc:`Generated/Virtual Columns <cookbook/generated-columns>` \|
:doc:`Decorator Pattern <cookbook/decorator-pattern>` \|
:doc:`Strategy Pattern <cookbook/strategy-cookbook-introduction>`
@@ -119,4 +121,5 @@ Cookbook
* **Custom Datatypes**
:doc:`MySQL Enums <cookbook/mysql-enums>`
:doc:`Custom Mapping Types <cookbook/custom-mapping-types>`
:doc:`Advanced Field Value Conversion <cookbook/advanced-field-value-conversion-using-custom-mapping-types>`

View File

@@ -1,113 +0,0 @@
@ECHO OFF
REM Command file for Sphinx documentation
set SPHINXBUILD=sphinx-build
set BUILDDIR=_build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
)
if "%1" == "" goto help
if "%1" == "help" (
:help
echo.Please use `make ^<target^>` where ^<target^> is one of
echo. html to make standalone HTML files
echo. dirhtml to make HTML files named index.html in directories
echo. pickle to make pickle files
echo. json to make JSON files
echo. htmlhelp to make HTML files and a HTML help project
echo. qthelp to make HTML files and a qthelp project
echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
echo. changes to make an overview over all changed/added/deprecated items
echo. linkcheck to check all external links for integrity
echo. doctest to run all doctests embedded in the documentation if enabled
goto end
)
if "%1" == "clean" (
for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
del /q /s %BUILDDIR%\*
goto end
)
if "%1" == "html" (
%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/html.
goto end
)
if "%1" == "dirhtml" (
%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
echo.
echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
goto end
)
if "%1" == "pickle" (
%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
echo.
echo.Build finished; now you can process the pickle files.
goto end
)
if "%1" == "json" (
%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
echo.
echo.Build finished; now you can process the JSON files.
goto end
)
if "%1" == "htmlhelp" (
%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
echo.
echo.Build finished; now you can run HTML Help Workshop with the ^
.hhp project file in %BUILDDIR%/htmlhelp.
goto end
)
if "%1" == "qthelp" (
%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
echo.
echo.Build finished; now you can run "qcollectiongenerator" with the ^
.qhcp project file in %BUILDDIR%/qthelp, like this:
echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Doctrine2ORM.qhcp
echo.To view the help file:
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Doctrine2ORM.ghc
goto end
)
if "%1" == "latex" (
%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
echo.
echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
goto end
)
if "%1" == "changes" (
%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
echo.
echo.The overview file is in %BUILDDIR%/changes.
goto end
)
if "%1" == "linkcheck" (
%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
echo.
echo.Link check complete; look for any errors in the above output ^
or in %BUILDDIR%/linkcheck/output.txt.
goto end
)
if "%1" == "doctest" (
%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
echo.
echo.Testing of doctests in the sources finished, look at the ^
results in %BUILDDIR%/doctest/output.txt.
goto end
)
:end

View File

@@ -19,7 +19,7 @@ steps of configuration.
// ...
if ($applicationMode == "development") {
if ($applicationMode === "development") {
$queryCache = new ArrayAdapter();
$metadataCache = new ArrayAdapter();
} else {
@@ -29,16 +29,21 @@ steps of configuration.
$config = new Configuration;
$config->setMetadataCache($metadataCache);
$driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities'], true);
$driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities']);
$config->setMetadataDriverImpl($driverImpl);
$config->setQueryCache($queryCache);
$config->setProxyDir('/path/to/myproject/lib/MyProject/Proxies');
$config->setProxyNamespace('MyProject\Proxies');
if ($applicationMode == "development") {
$config->setAutoGenerateProxyClasses(true);
if (PHP_VERSION_ID > 80400) {
$config->enableNativeLazyObjects(true);
} else {
$config->setAutoGenerateProxyClasses(false);
$config->setProxyDir('/path/to/myproject/lib/MyProject/Proxies');
$config->setProxyNamespace('MyProject\Proxies');
if ($applicationMode === "development") {
$config->setAutoGenerateProxyClasses(true);
} else {
$config->setAutoGenerateProxyClasses(false);
}
}
$connection = DriverManager::getConnection([
@@ -71,8 +76,27 @@ Configuration Options
The following sections describe all the configuration options
available on a ``Doctrine\ORM\Configuration`` instance.
Proxy Directory (***REQUIRED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. _reference-native-lazy-objects:
Native Lazy Objects (**OPTIONAL**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
With PHP 8.4 we recommend that you use native lazy objects instead of
the code generation approach using the ``symfony/var-exporter`` Ghost trait.
With Doctrine 4, the minimal requirement will become PHP 8.4 and native lazy objects
will become the only approach to lazy loading.
.. code-block:: php
<?php
$config->enableNativeLazyObjects(true);
Proxy Directory
~~~~~~~~~~~~~~~
Required except if you use native lazy objects with PHP 8.4.
This setting will be removed in the future.
.. code-block:: php
@@ -85,8 +109,11 @@ classes. For a detailed explanation on proxy classes and how they
are used in Doctrine, refer to the "Proxy Objects" section further
down.
Proxy Namespace (***REQUIRED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Proxy Namespace
~~~~~~~~~~~~~~~
Required except if you use native lazy objects with PHP 8.4.
This setting will be removed in the future.
.. code-block:: php
@@ -98,8 +125,8 @@ Gets or sets the namespace to use for generated proxy classes. For
a detailed explanation on proxy classes and how they are used in
Doctrine, refer to the "Proxy Objects" section further down.
Metadata Driver (***REQUIRED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Metadata Driver (**REQUIRED**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: php
@@ -129,18 +156,62 @@ The attribute driver can be injected in the ``Doctrine\ORM\Configuration``:
<?php
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
$driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities'], true);
$driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities']);
$config->setMetadataDriverImpl($driverImpl);
The path information to the entities is required for the attribute
driver, because otherwise mass-operations on all entities through
the console could not work correctly. All of metadata drivers
accept either a single directory as a string or an array of
directories. With this feature a single driver can support multiple
directories of Entities.
the console could not work correctly. Metadata drivers can accept either
a single directory as a string or an array of directories.
Metadata Cache (***RECOMMENDED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AttributeDriver also accepts ``Doctrine\Persistence\Mapping\Driver\ClassLocator``,
allowing one to customize file discovery logic. You may choose to use Symfony Finder, or
utilize directory scan with ``FileClassLocator::createFromDirectories()``:
.. code-block:: php
<?php
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\Persistence\Mapping\Driver\FileClassLocator;
$paths = ['/path/to/lib/MyProject/Entities'];
$classLocator = FileClassLocator::createFromDirectories($paths);
$driverImpl = new AttributeDriver($classLocator);
$config->setMetadataDriverImpl($driverImpl);
With this feature, you're empowered to provide a fine-grained iterator of only necessary
files to the Driver. For example, if you are using Vertical Slice architecture, you can
exclude ``*Test.php``, ``*Controller.php``, ``*Service.php``, etc.:
.. code-block:: php
<?php
use Symfony\Component\Finder\Finder;
$finder = new Finder()->files()->in($paths)
->name('*.php')
->notName(['*Test.php', '*Controller.php', '*Service.php']);
$classLocator = new FileClassLocator($finder);
If you know the list of class names you want to track, use
``Doctrine\Persistence\Mapping\Driver\ClassNames``:
.. code-block:: php
<?php
use Doctrine\Persistence\Mapping\Driver\ClassNames;
use App\Entity\{Article, Book};
$entityClasses = [Article::class, Book::class];
$classLocator = new ClassNames($entityClasses);
$driverImpl = new AttributeDriver($classLocator);
$config->setMetadataDriverImpl($driverImpl);
Metadata Cache (**RECOMMENDED**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: php
@@ -161,8 +232,8 @@ For development you should use an array cache like
``Symfony\Component\Cache\Adapter\ArrayAdapter``
which only caches data on a per-request basis.
Query Cache (***RECOMMENDED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Query Cache (**RECOMMENDED**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: php
@@ -184,8 +255,8 @@ For development you should use an array cache like
``Symfony\Component\Cache\Adapter\ArrayAdapter``
which only caches data on a per-request basis.
SQL Logger (***Optional***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~
SQL Logger (**Optional**)
~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: php
@@ -197,8 +268,11 @@ Gets or sets the logger to use for logging all SQL statements
executed by Doctrine. The logger class must implement the
deprecated ``Doctrine\DBAL\Logging\SQLLogger`` interface.
Auto-generating Proxy Classes (***OPTIONAL***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Auto-generating Proxy Classes (**OPTIONAL**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This setting is not required if you use native lazy objects with PHP 8.4
and will be removed in the future.
Proxy classes can either be generated manually through the Doctrine
Console or automatically at runtime by Doctrine. The configuration
@@ -274,7 +348,7 @@ requests.
Connection
----------
The ``$connection`` passed as the first argument to he constructor of
The ``$connection`` passed as the first argument to the constructor of
``EntityManager`` has to be an instance of ``Doctrine\DBAL\Connection``.
You can use the factory ``Doctrine\DBAL\DriverManager::getConnection()``
to create such a connection. The DBAL configuration is explained in the
@@ -441,7 +515,7 @@ correctly if sub-namespaces use different metadata driver
implementations.
Default Repository (***OPTIONAL***)
Default Repository (**OPTIONAL**)
-----------------------------------
Specifies the FQCN of a subclass of the EntityRepository.
@@ -456,7 +530,7 @@ That will be available for all entities without a custom repository class.
The default value is ``Doctrine\ORM\EntityRepository``.
Any repository class must be a subclass of EntityRepository otherwise you got an ORMException
Ignoring entities (***OPTIONAL***)
Ignoring entities (**OPTIONAL**)
-----------------------------------
Specifies the Entity FQCNs to ignore.

View File

@@ -33,14 +33,13 @@ Doctrine ORM is divided into four main packages.
- ORM (depends on DBAL+Persistence+Collections)
This manual mainly covers the ORM package, sometimes touching parts
of the underlying DBAL and Persistence packages. The Doctrine code base
is split in to these packages for a few reasons and they are to...
of the underlying DBAL and Persistence packages. The Doctrine codebase
is split into these packages for a few reasons:
- ...make things more maintainable and decoupled
- ...allow you to use the code in Doctrine Persistence and Collections
without the ORM or DBAL
- ...allow you to use the DBAL without the ORM
- to make things more maintainable and decoupled
- to allow you to use the code in Doctrine Persistence and Collections without the ORM or DBAL
- to allow you to use the DBAL without the ORM
Collection, Event Manager and Persistence
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -80,8 +79,9 @@ Entities
An entity is a lightweight, persistent domain object. An entity can
be any regular PHP class observing the following restrictions:
- An entity class must not be final nor read-only but
it may contain final methods or read-only properties.
- An entity class can be final or read-only when
you use :ref:`native lazy objects <reference-native-lazy-objects>`.
It may contain final methods or read-only properties too.
- Any two entity classes in a class hierarchy that inherit
directly or indirectly from one another must not have a mapped
property with the same name. That is, if B inherits from A then B
@@ -168,7 +168,7 @@ recommended, at least not as long as an entity instance still holds
references to proxy objects or is still managed by an EntityManager.
By default, serializing proxy objects does not initialize them. On
unserialization, resulting objects are detached from the entity
manager and cannot be initialiazed anymore. You can implement the
manager and cannot be initialized anymore. You can implement the
``__serialize()`` method if you want to change that behavior, but
then you need to ensure that you won't generate large serialized
object graphs and take care of circular associations.

View File

@@ -870,8 +870,8 @@ This is essentially the same as the following, more verbose, mapping:
* @var Collection<int, Group>
*/
#[JoinTable(name: 'User_Group')]
#[JoinColumn(name: 'User_id', referencedColumnName: 'id')]
#[InverseJoinColumn(name: 'Group_id', referencedColumnName: 'id')]
#[JoinColumn(name: 'user_id', referencedColumnName: 'id')]
#[InverseJoinColumn(name: 'group_id', referencedColumnName: 'id')]
#[ManyToMany(targetEntity: Group::class)]
private Collection $groups;
// ...
@@ -884,10 +884,10 @@ This is essentially the same as the following, more verbose, mapping:
<many-to-many field="groups" target-entity="Group">
<join-table name="User_Group">
<join-columns>
<join-column id="User_id" referenced-column-name="id" />
<join-column id="user_id" referenced-column-name="id" />
</join-columns>
<inverse-join-columns>
<join-column id="Group_id" referenced-column-name="id" />
<join-column id="group_id" referenced-column-name="id" />
</inverse-join-columns>
</join-table>
</many-to-many>
@@ -903,8 +903,7 @@ defaults to "id", just as in one-to-one or many-to-one mappings.
Additionally, when using typed properties with Doctrine 2.9 or newer
you can skip ``targetEntity`` in ``ManyToOne`` and ``OneToOne``
associations as they will be set based on type. Also ``nullable``
attribute on ``JoinColumn`` will be inherited from PHP type. So that:
associations as they will be set based on type. So that:
.. configuration-block::
@@ -931,7 +930,7 @@ Is essentially the same as following:
<?php
/** One Product has One Shipment. */
#[OneToOne(targetEntity: Shipment::class)]
#[JoinColumn(name: 'shipment_id', referencedColumnName: 'id', nullable: false)]
#[JoinColumn(name: 'shipment_id', referencedColumnName: 'id')]
private Shipment $shipment;
.. code-block:: annotation
@@ -940,7 +939,7 @@ Is essentially the same as following:
/**
* One Product has One Shipment.
* @OneToOne(targetEntity="Shipment")
* @JoinColumn(name="shipment_id", referencedColumnName="id", nullable=false)
* @JoinColumn(name="shipment_id", referencedColumnName="id")
*/
private Shipment $shipment;
@@ -949,7 +948,7 @@ Is essentially the same as following:
<doctrine-mapping>
<entity class="Product">
<one-to-one field="shipment" target-entity="Shipment">
<join-column name="shipment_id" referenced-column-name="id" nulable=false />
<join-column name="shipment_id" referenced-column-name="id" nullable=false />
</one-to-one>
</entity>
</doctrine-mapping>

View File

@@ -15,7 +15,7 @@ Index
- :ref:`#[AttributeOverride] <attrref_attributeoverride>`
- :ref:`#[Column] <attrref_column>`
- :ref:`#[Cache] <attrref_cache>`
- :ref:`#[ChangeTrackingPolicy <attrref_changetrackingpolicy>`
- :ref:`#[ChangeTrackingPolicy] <attrref_changetrackingpolicy>`
- :ref:`#[CustomIdGenerator] <attrref_customidgenerator>`
- :ref:`#[DiscriminatorColumn] <attrref_discriminatorcolumn>`
- :ref:`#[DiscriminatorMap] <attrref_discriminatormap>`
@@ -175,6 +175,10 @@ Optional parameters:
- **unique**: Boolean value to determine if the value of the column
should be unique across all rows of the underlying entities table.
- **index**: Boolean value to generate an index for this column.
For more advanced usages, take a look at :ref:`#[Index] <attrref_index>`.
If not specified, default value is ``false``.
- **nullable**: Determines if NULL values allowed for this column.
If not specified, default value is ``false``.
@@ -214,12 +218,15 @@ Optional parameters:
- ``check``: Adds a check constraint type to the column (might not
be supported by all vendors).
- **columnDefinition**: DDL SQL snippet that starts after the column
- **columnDefinition**: Specify the DDL SQL snippet that starts after the column
name and specifies the complete (non-portable!) column definition.
This attribute allows to make use of advanced RMDBS features.
However you should make careful use of this feature and the
consequences. ``SchemaTool`` will not detect changes on the column correctly
anymore if you use ``columnDefinition``.
However, as this needs to be specified in the DDL native to the database,
the resulting schema changes are no longer portable. If you specify a
``columnDefinition``, the ``SchemaTool`` ignores all other attributes
that are normally used to build the definition DDL. Changes to the
``columnDefinition`` are not detected, you will need to manually create a
migration to apply changes.
Additionally you should remember that the ``type``
attribute still handles the conversion between PHP and Database
@@ -242,6 +249,9 @@ Examples:
#[Column(type: "string", length: 32, unique: true, nullable: false)]
protected $username;
#[Column(type: "string", index: true)]
protected $firstName;
#[Column(type: "string", columnDefinition: "CHAR(2) NOT NULL")]
protected $country;
@@ -262,10 +272,11 @@ Examples:
)]
protected $loginCount;
// MySQL example: full_name char(41) GENERATED ALWAYS AS (concat(firstname,' ',lastname)),
// columnDefinition is raw SQL, not DQL. This example works for MySQL:
#[Column(
type: "string",
name: "user_fullname",
columnDefinition: "VARCHAR(255) GENERATED ALWAYS AS (concat(firstname,' ',lastname))",
insertable: false,
updatable: false
)]
@@ -366,7 +377,7 @@ Optional parameters:
- **type**: By default this is string.
- **length**: By default this is 255.
- **columnDefinition**: By default this is null the definition according to the type will be used. This option allows to override it.
- **columnDefinition**: Allows to override how the column is generated. See the "columnDefinition" attribute on :ref:`#[Column] <attrref_column>`
- **enumType**: By default this is `null`. Allows to map discriminatorColumn value to PHP enum
- **options**: See "options" attribute on :ref:`#[Column] <attrref_column>`.
@@ -657,11 +668,6 @@ and in the Context of a :ref:`#[ManyToMany] <attrref_manytomany>`. If this attri
are missing they will be computed considering the field's name and the current
:doc:`naming strategy <namingstrategy>`.
The ``#[InverseJoinColumn]`` is the same as ``#[JoinColumn]`` and is used in the context
of a ``#[ManyToMany]`` attribute declaration to specifiy the details of the join table's
column information used for the join to the inverse entity. This is only required
on PHP 8.0, where nested attributes are not yet supported.
Optional parameters:
- **name**: Column name that holds the foreign key identifier for
@@ -672,13 +678,16 @@ Optional parameters:
- **unique**: Determines whether this relation is exclusive between the
affected entities and should be enforced as such on the database
constraint level. Defaults to false.
- **deferrable**: Determines whether this relation constraint can be deferred. Defaults to false.
- **nullable**: Determine whether the related entity is required, or if
null is an allowed state for the relation. Defaults to true.
- **onDelete**: Cascade Action (Database-level)
- **columnDefinition**: DDL SQL snippet that starts after the column
name and specifies the complete (non-portable!) column definition.
This attribute enables the use of advanced RMDBS features. Using
this attribute on ``#[JoinColumn]`` is necessary if you need slightly
This attribute enables the use of advanced RMDBS features. Note that you
need to reference columns by their database name (either explicitly set in
the mapping or per the current :doc:`naming strategy <namingstrategy>`).
Using this attribute on ``#[JoinColumn]`` is necessary if you need
different column definitions for joining columns, for example
regarding NULL/NOT NULL defaults. However by default a
"columnDefinition" attribute on :ref:`#[Column] <attrref_column>` also sets
@@ -1133,7 +1142,7 @@ Marker attribute that defines a specified column as version attribute used in
an :ref:`optimistic locking <transactions-and-concurrency_optimistic-locking>`
scenario. It only works on :ref:`#[Column] <attrref_column>` attributes that have
the type ``integer`` or ``datetime``. Setting ``#[Version]`` on a property with
:ref:`#[Id <attrref_id>` is not supported.
:ref:`#[Id] <attrref_id>` is not supported.
Example:

View File

@@ -167,6 +167,7 @@ Here is a complete list of ``Column``s attributes (all optional):
- ``nullable`` (default: ``false``): Whether the column is nullable.
- ``insertable`` (default: ``true``): Whether the column should be inserted.
- ``updatable`` (default: ``true``): Whether the column should be updated.
- ``generated`` (default: ``null``): Whether the generated strategy should be ``'NEVER'``, ``'INSERT'`` and ``ALWAYS``.
- ``enumType`` (requires PHP 8.1 and ``doctrine/orm`` 2.11): The PHP enum class name to convert the database value into.
- ``precision`` (default: 0): The precision for a decimal (exact numeric) column
(applies only for decimal column),
@@ -181,6 +182,37 @@ Here is a complete list of ``Column``s attributes (all optional):
- ``options``: Key-value pairs of options that get passed
to the underlying database platform when generating DDL statements.
Specifying default values
~~~~~~~~~~~~~~~~~~~~~~~~~
While it is possible to specify default values for properties in your
PHP class, Doctrine also allows you to specify default values for
database columns using the ``default`` key in the ``options`` array of
the ``Column`` attribute.
When using XML, you can specify object instances using the ``<object>``
element:
.. code-block:: xml
<field name="createdAt" type="datetime" insertable="false" updatable="false">
<options>
<option name="default">
<object class="Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp"/>
</option>
</options>
</field>
The ``<object>`` element requires a ``class`` attribute specifying the
fully qualified class name to instantiate.
.. configuration-block::
.. literalinclude:: basic-mapping/DefaultValues.php
:language: attribute
.. literalinclude:: basic-mapping/default-values.xml
:language: xml
.. _reference-php-mapping-types:
PHP Types Mapping
@@ -213,6 +245,8 @@ These are the "automatic" mapping rules:
| Any other type | ``Types::STRING`` |
+-----------------------+-------------------------------+
.. versionadded:: 2.11
As of version 2.11 Doctrine can also automatically map typed properties using a
PHP 8.1 enum to set the right ``type`` and ``enumType``.
@@ -223,6 +257,70 @@ and a custom ``Doctrine\ORM\Mapping\TypedFieldMapper`` implementation.
:doc:`Read more about TypedFieldMapper <typedfieldmapper>`.
Property Hooks
--------------
.. versionadded:: 3.4
Doctrine supports mapping hooked properties as long as they have a backed property
and are not virtual.
.. configuration-block::
.. code-block:: attribute
<?php
use Doctrine\ORM\Mapping\Column;
use Doctrine\DBAL\Types\Types;
#[Entity]
class Message
{
#[Column(type: Types::INTEGER)]
private $id;
#[Column(type: Types::STRING)]
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);
}
}
}
.. code-block:: xml
<doctrine-mapping>
<entity name="Message">
<field name="id" type="integer" />
<field name="language" />
</entity>
</doctrine-mapping>
If you attempt to map a virtual property with ``#[Column]`` an exception will be thrown.
Some caveats apply to the use of property hooks, as they behave differently when accessing the property through
the entity or directly through DQL/EntityRepository. Because the property hook can modify the value of the property in a way
that value and raw value are different, you have to use the raw value representation when querying for the property.
.. code-block:: php
<?php
$queryBuilder = $entityManager->createQueryBuilder();
$queryBuilder->select('m')
->from(Message::class, 'm')
->where('m.language = :language')
->setParameter('language', 'de'); // Use lower case here for raw value representation
$query = $queryBuilder->getQuery();
$result = $query->getResult();
$messageRepository = $entityManager->getRepository(Message::class);
$deMessages = $messageRepository->findBy(['language' => 'de']); // Use lower case here for raw value representation
.. _reference-mapping-types:
Doctrine Mapping Types
@@ -322,17 +420,19 @@ Here is the list of possible generation strategies:
- ``AUTO`` (default): Tells Doctrine to pick the strategy that is
preferred by the used database platform. The preferred strategies
are ``IDENTITY`` for MySQL, SQLite, MsSQL and SQL Anywhere and, for
historical reasons, ``SEQUENCE`` for Oracle and PostgreSQL. This
strategy provides full portability.
are ``IDENTITY`` for MySQL, SQLite, MsSQL, SQL Anywhere and
PostgreSQL (on DBAL 4) and, for historical reasons, ``SEQUENCE``
for Oracle and PostgreSQL (on DBAL 3). This strategy provides
full portability.
- ``IDENTITY``: Tells Doctrine to use special identity columns in
the database that generate a value on insertion of a row. This
strategy does currently not provide full portability and is
supported by the following platforms: MySQL/SQLite/SQL Anywhere
(``AUTO_INCREMENT``), MSSQL (``IDENTITY``) and PostgreSQL (``SERIAL``).
(``AUTO_INCREMENT``), MSSQL (``IDENTITY``) and PostgreSQL (``SERIAL``
on DBAL 3, ``GENERATED BY DEFAULT AS IDENTITY`` on DBAL 4).
- ``SEQUENCE``: Tells Doctrine to use a database sequence for ID
generation. This strategy does currently not provide full
portability. Sequences are supported by Oracle, PostgreSql and
portability. Sequences are supported by Oracle, PostgreSQL and
SQL Anywhere.
- ``NONE``: Tells Doctrine that the identifiers are assigned (and
thus generated) by your code. The assignment must take place before

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace App\Entity;
use DateTime;
use Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
#[Entity]
class Message
{
#[Column(options: ['default' => 'Hello World!'])]
private string $text;
#[Column(options: ['default' => new CurrentTimestamp()], insertable: false, updatable: false)]
private DateTime $createdAt;
}

View File

@@ -0,0 +1,16 @@
<doctrine-mapping>
<entity name="Message">
<field name="text">
<options>
<option name="default">Hello World!</option>
</options>
</field>
<field name="createdAt" insertable="false" updatable="false">
<options>
<option name="default">
<object class="Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp"/>
</option>
</options>
</field>
</entity>
</doctrine-mapping>

View File

@@ -56,7 +56,8 @@ access point to ORM functionality provided by Doctrine.
'dbname' => 'foo',
];
$config = ORMSetup::createAttributeMetadataConfiguration($paths, $isDevMode);
$config = ORMSetup::createAttributeMetadataConfig($paths, $isDevMode);
// on PHP < 8.4, use ORMSetup::createAttributeMetadataConfiguration() instead
$connection = DriverManager::getConnection($dbParams, $config);
$entityManager = new EntityManager($connection, $config);
@@ -66,7 +67,8 @@ Or if you prefer XML:
<?php
$paths = ['/path/to/xml-mappings'];
$config = ORMSetup::createXMLMetadataConfiguration($paths, $isDevMode);
$config = ORMSetup::createXMLMetadataConfig($paths, $isDevMode);
// on PHP < 8.4, use ORMSetup::createXMLMetadataConfiguration() instead
$connection = DriverManager::getConnection($dbParams, $config);
$entityManager = new EntityManager($connection, $config);

View File

@@ -490,7 +490,7 @@ where you can generate an arbitrary join with the following syntax:
.. code-block:: php
<?php
$query = $em->createQuery('SELECT u FROM User u JOIN Banlist b WITH u.email = b.email');
$query = $em->createQuery('SELECT u FROM User u JOIN Banlist b ON u.email = b.email');
With an arbitrary join the result differs from the joins using a mapped property.
The result of an arbitrary join is an one dimensional array with a mix of the entity from the ``SELECT``
@@ -513,16 +513,46 @@ it loads all the related ``Banlist`` objects corresponding to this ``User``. Thi
when the DQL is switched to an arbitrary join.
.. note::
The differences between WHERE, WITH and HAVING clauses may be
The differences between WHERE, WITH, ON and HAVING clauses may be
confusing.
- WHERE is applied to the results of an entire query
- WITH is applied to a join as an additional condition. For
arbitrary joins (SELECT f, b FROM Foo f, Bar b WITH f.id = b.id)
the WITH is required, even if it is 1 = 1
- ON is applied to arbitrary joins as the join condition. For
arbitrary joins (SELECT f, b FROM Foo f, Bar b ON f.id = b.id)
the ON is required, even if it is 1 = 1. WITH is also
supported as alternative keyword for that case for BC reasons.
- WITH is applied to an association join as an additional condition.
- HAVING is applied to the results of a query after
aggregation (GROUP BY)
Partial Hydration Syntax
^^^^^^^^^^^^^^^^^^^^^^^^
By default when you run a DQL query in Doctrine and select only a
subset of the fields for a given entity, you do not receive objects
back. Instead, you receive only arrays as a flat rectangular result
set, similar to how you would if you were just using SQL directly
and joining some data.
If you want to select partial objects or fields in array hydration you can use the ``partial``
DQL keyword:
.. code-block:: php
<?php
$query = $em->createQuery('SELECT partial u.{id, username} FROM CmsUser u');
$users = $query->getResult(); // array of partially loaded CmsUser objects
You can use the partial syntax when joining as well:
.. code-block:: php
<?php
$query = $em->createQuery('SELECT partial u.{id, username}, partial a.{id, name} FROM CmsUser u JOIN u.articles a');
$usersArray = $query->getArrayResult(); // array of partially loaded CmsUser and CmsArticle fields
$users = $query->getResult(); // array of partially loaded CmsUser objects
"NEW" Operator Syntax
^^^^^^^^^^^^^^^^^^^^^
@@ -560,7 +590,101 @@ And then use the ``NEW`` DQL keyword :
$query = $em->createQuery('SELECT NEW CustomerDTO(c.name, e.email, a.city, SUM(o.value)) FROM Customer c JOIN c.email e JOIN c.address a JOIN c.orders o GROUP BY c');
$users = $query->getResult(); // array of CustomerDTO
Note that you can only pass scalar expressions to the constructor.
You can also nest several DTO :
.. code-block:: php
<?php
class CustomerDTO
{
public function __construct(string $name, string $email, AddressDTO $address, string|null $value = null)
{
// Bind values to the object properties.
}
}
class AddressDTO
{
public function __construct(string $street, string $city, string $zip)
{
// Bind values to the object properties.
}
}
.. code-block:: php
<?php
$query = $em->createQuery('SELECT NEW CustomerDTO(c.name, e.email, NEW AddressDTO(a.street, a.city, a.zip)) FROM Customer c JOIN c.email e JOIN c.address a');
$users = $query->getResult(); // array of CustomerDTO
Note that you can only pass scalar expressions or other Data Transfer Objects to the constructor.
If you use your data transfer objects for multiple queries, and you would rather not have to
specify arguments that precede the ones you are really interested in, you can use named arguments.
Consider the following DTO, which uses optional arguments:
.. code-block:: php
<?php
class CustomerDTO
{
public function __construct(
public string|null $name = null,
public string|null $email = null,
public string|null $city = null,
public mixed|null $value = null,
public AddressDTO|null $address = null,
) {
}
}
You can specify arbitrary arguments in an arbitrary order by using the named argument syntax, and the ORM will try to match argument names with the selected column names.
The syntax relies on the NAMED keyword, like so:
.. code-block:: php
<?php
$query = $em->createQuery('SELECT NEW NAMED CustomerDTO(a.city, c.name) FROM Customer c JOIN c.address a');
$users = $query->getResult(); // array of CustomerDTO
// CustomerDTO => {name : 'SMITH', email: null, city: 'London', value: null}
ORM will also give precedence to column aliases over column names :
.. code-block:: php
<?php
$query = $em->createQuery('SELECT NEW NAMED CustomerDTO(c.name, CONCAT(a.city, ' ' , a.zip) AS value) FROM Customer c JOIN c.address a');
$users = $query->getResult(); // array of CustomerDTO
// CustomerDTO => {name : 'DOE', email: null, city: null, value: 'New York 10011'}
To define a custom name for a DTO constructor argument, you can either alias the column with the ``AS`` keyword.
The ``NAMED`` keyword must precede all DTO you want to instantiate :
.. code-block:: php
<?php
$query = $em->createQuery('SELECT NEW NAMED CustomerDTO(c.name, NEW NAMED AddressDTO(a.street, a.city, a.zip) AS address) FROM Customer c JOIN c.address a');
$users = $query->getResult(); // array of CustomerDTO
// CustomerDTO => {name : 'DOE', email: null, city: null, value: 'New York 10011'}
If two arguments have the same name, a ``DuplicateFieldException`` is thrown.
If a field cannot be matched with a property name, a ``NoMatchingPropertyException`` is thrown. This typically happens when using functions without aliasing them.
You can hydrate an entity nested in a DTO :
.. code-block:: php
<?php
$query = $em->createQuery('SELECT NEW CustomerDTO(c.name, a AS address) FROM Customer c JOIN c.address a');
$users = $query->getResult(); // array of CustomerDTO
// CustomerDTO => {name : 'DOE', email: null, address : {city: 'New York', zip: '10011', address: 'Abbey Road'}
Using INDEX BY
~~~~~~~~~~~~~~
@@ -1287,8 +1411,7 @@ Result Cache API:
$query->setResultCacheDriver(new ApcCache());
$query->useResultCache(true)
->setResultCacheLifeTime(3600);
$query->enableResultCache(3600);
$result = $query->getResult(); // cache miss
@@ -1298,8 +1421,8 @@ Result Cache API:
$query->setResultCacheId('my_query_result');
$result = $query->getResult(); // saved in given result cache id.
// or call useResultCache() with all parameters:
$query->useResultCache(true, 3600, 'my_query_result');
// or call enableResultCache() with all parameters:
$query->enableResultCache(3600, 'my_query_result');
$result = $query->getResult(); // cache hit!
// Introspection
@@ -1324,6 +1447,15 @@ exist mostly internal query hints that are not be consumed in
userland. However the following few hints are to be used in
userland:
- ``Query::HINT_FORCE_PARTIAL_LOAD`` - Allows to hydrate objects
although not all their columns are fetched. This query hint can be
used to handle memory consumption problems with large result-sets
that contain char or binary data. Doctrine has no way of implicitly
reloading this data. Partially loaded objects have to be passed to
``EntityManager::refresh()`` if they are to be reloaded fully from
the database. This query hint is deprecated and will be removed
in the future (\ `Details <https://github.com/doctrine/orm/issues/8471>`_)
- ``Query::HINT_REFRESH`` - This query is used internally by
``EntityManager::refresh()`` and can be used in userland as well.
If you specify this hint and a query returns the data for an entity
@@ -1568,18 +1700,26 @@ From, Join and Index by
SubselectIdentificationVariableDeclaration ::= IdentificationVariableDeclaration
RangeVariableDeclaration ::= AbstractSchemaName ["AS"] AliasIdentificationVariable
JoinAssociationDeclaration ::= JoinAssociationPathExpression ["AS"] AliasIdentificationVariable [IndexBy]
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" (JoinAssociationDeclaration | RangeVariableDeclaration) ["WITH" ConditionalExpression]
Join ::= ["LEFT" ["OUTER"] | "INNER"] "JOIN" (JoinAssociationDeclaration ["WITH" ConditionalExpression] | RangeVariableDeclaration [("ON" | "WITH") ConditionalExpression])
IndexBy ::= "INDEX" "BY" SingleValuedPathExpression
.. note::
Using the ``WITH`` keyword for the ``ConditionalExpression`` of a
``RangeVariableDeclaration`` is deprecated and will be removed in
ORM 4.0. Use the ``ON`` keyword instead.
Select Expressions
~~~~~~~~~~~~~~~~~~
.. code-block:: php
SelectExpression ::= (IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | "(" Subselect ")" | CaseExpression | NewObjectExpression) [["AS"] ["HIDDEN"] AliasResultVariable]
SimpleSelectExpression ::= (StateFieldPathExpression | IdentificationVariable | FunctionDeclaration | AggregateExpression | "(" Subselect ")" | ScalarExpression) [["AS"] AliasResultVariable]
NewObjectExpression ::= "NEW" AbstractSchemaName "(" NewObjectArg {"," NewObjectArg}* ")"
NewObjectArg ::= ScalarExpression | "(" Subselect ")"
SelectExpression ::= (IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | PartialObjectExpression | "(" Subselect ")" | CaseExpression | NewObjectExpression) [["AS"] ["HIDDEN"] AliasResultVariable]
SimpleSelectExpression ::= (StateFieldPathExpression | IdentificationVariable | FunctionDeclaration | AggregateExpression | "(" Subselect ")" | ScalarExpression) [["AS"] AliasResultVariable]
PartialObjectExpression ::= "PARTIAL" IdentificationVariable "." PartialFieldSet
PartialFieldSet ::= "{" SimpleStateField {"," SimpleStateField}* "}"
NewObjectExpression ::= "NEW" AbstractSchemaName "(" NewObjectArg {"," NewObjectArg}* ")"
NewObjectArg ::= (ScalarExpression | "(" Subselect ")" | NewObjectExpression | EntityAsDtoArgumentExpression) ["AS" AliasResultVariable]
EntityAsDtoArgumentExpression ::= IdentificationVariable
Conditional Expressions
~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -265,7 +265,7 @@ specific to a particular entity class's lifecycle.
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="User">

View File

@@ -18,30 +18,6 @@ In your mapping configuration, the column definition (for example, the
the ``charset`` and ``collation``. The default values are ``utf8`` and
``utf8_unicode_ci``, respectively.
Entity Classes
--------------
How can I add default values to a column?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Doctrine does not support to set the default values in columns through the "DEFAULT" keyword in SQL.
This is not necessary however, you can just use your class properties as default values. These are then used
upon insert:
.. code-block:: php
class User
{
private const STATUS_DISABLED = 0;
private const STATUS_ENABLED = 1;
private string $algorithm = "sha1";
/** @var self::STATUS_* */
private int $status = self::STATUS_DISABLED;
}
.
Mapping
-------

View File

@@ -30,7 +30,7 @@ table alias of the SQL table of the entity.
For the filter to correctly function, the following rules must be followed. Failure to do so will lead to unexpected results from the query cache.
1. Parameters for the query should be set on the filter object by ``SQLFilter#setParameter()`` before the filter is used by the ORM ( i.e. do not set parameters inside ``SQLFilter#addFilterConstraint()`` function ).
2. The filter must be deterministic. Don't change the values base on external inputs.
2. The filter must be deterministic. Don't change the values based on external inputs.
The ``SQLFilter#getParameter()`` function takes care of the proper quoting of parameters.

View File

@@ -16,7 +16,7 @@ is common to multiple entity classes.
Mapped superclasses, just as regular, non-mapped classes, can
appear in the middle of an otherwise mapped inheritance hierarchy
(through Single Table Inheritance or Class Table Inheritance). They
are not query-able, and need not have an ``#[Id]`` property.
are not query-able, and do not require an ``#[Id]`` property.
No database table will be created for a mapped superclass itself,
only for entity classes inheriting from it. That implies that a
@@ -208,6 +208,22 @@ Example:
// ...
}
.. code-block:: xml
<doctrine-mapping>
<entity name="MyProject\Model\Person" inheritance-type="SINGLE_TABLE">
<discriminator-column name="discr" type="string" />
<discriminator-map>
<discriminator-mapping value="person" class="MyProject\Model\Person"/>
<discriminator-mapping value="employee" class="MyProject\Model\Employee"/>
</discriminator-map>
</entity>
</doctrine-mapping>
<doctrine-mapping>
<entity name="MyProject\Model\Employee">
</entity>
</doctrine-mapping>
In this example, the ``#[DiscriminatorMap]`` specifies that in the
discriminator column, a value of "person" identifies a row as being of type

View File

@@ -1,3 +1,5 @@
:orphan:
Installation
============

View File

@@ -178,6 +178,14 @@ internally by the ORM currently refers to fields by their name only, without tak
class containing the field into consideration. This makes it impossible to keep separate
mapping configuration for both fields.
Apart from that, in the case of having multiple ``private`` fields of the same name within
the class hierarchy an entity or mapped superclass, the Collection filtering API cannot determine
the right field to look at. Even if only one of these fields is actually mapped, the ``ArrayCollection``
will not be able to tell, since it does not have access to any metadata.
Thus, to avoid problems in this regard, it is best to avoid having multiple ``private`` fields of the
same name in class hierarchies containing entity and mapped superclasses.
Known Issues
------------

View File

@@ -70,8 +70,8 @@ implements the ``MappingDriver`` interface:
/**
* Loads the metadata for the specified class into the provided container.
*
* @psalm-param class-string<T> $className
* @psalm-param ClassMetadata<T> $metadata
* @param class-string<T> $className
* @param ClassMetadata<T> $metadata
*
* @return void
*
@@ -82,8 +82,7 @@ implements the ``MappingDriver`` interface:
/**
* Gets the names of all mapped classes known to this driver.
*
* @return array<int, string> The names of all mapped classes known to this driver.
* @psalm-return list<class-string>
* @return list<class-string> The names of all mapped classes known to this driver.
*/
public function getAllClassNames();
@@ -91,7 +90,7 @@ implements the ``MappingDriver`` interface:
* Returns whether the class with the specified name should have its metadata loaded.
* This is only the case if it is either mapped as an Entity or a MappedSuperclass.
*
* @psalm-param class-string $className
* @param class-string $className
*
* @return bool
*/

View File

@@ -0,0 +1,15 @@
Partial Hydration
=================
Partial hydration of entities is allowed in the array hydrator, when
only a subset of the fields of an entity are loaded from the database
and the nested results are still created based on the entity relationship structure.
.. code-block:: php
<?php
$users = $em->createQuery("SELECT PARTIAL u.{id,name}, partial a.{id,street} FROM MyApp\Domain\User u JOIN u.addresses a")
->getArrayResult();
This is a useful optimization when you are not interested in all fields of an entity
for performance reasons, for example in use-cases for exporting or rendering lots of data.

View File

@@ -0,0 +1,88 @@
Partial Objects
===============
A partial object is an object whose state is not fully initialized
after being reconstituted from the database and that is
disconnected from the rest of its data. The following section will
describe why partial objects are problematic and what the approach
of Doctrine to this problem is.
.. note::
The partial object problem in general does not apply to
methods or queries where you do not retrieve the query result as
objects. Examples are: ``Query#getArrayResult()``,
``Query#getScalarResult()``, ``Query#getSingleScalarResult()``,
etc.
.. warning::
Use of partial objects is tricky. Fields that are not retrieved
from the database will not be updated by the UnitOfWork even if they
get changed in your objects. You can only promote a partial object
to a fully-loaded object by calling ``EntityManager#refresh()``
or a DQL query with the refresh flag.
What is the problem?
--------------------
In short, partial objects are problematic because they are usually
objects with broken invariants. As such, code that uses these
partial objects tends to be very fragile and either needs to "know"
which fields or methods can be safely accessed or add checks around
every field access or method invocation. The same holds true for
the internals, i.e. the method implementations, of such objects.
You usually simply assume the state you need in the method is
available, after all you properly constructed this object before
you pushed it into the database, right? These blind assumptions can
quickly lead to null reference errors when working with such
partial objects.
It gets worse with the scenario of an optional association (0..1 to
1). When the associated field is NULL, you don't know whether this
object does not have an associated object or whether it was simply
not loaded when the owning object was loaded from the database.
These are reasons why many ORMs do not allow partial objects at all
and instead you always have to load an object with all its fields
(associations being proxied). One secure way to allow partial
objects is if the programming language/platform allows the ORM tool
to hook deeply into the object and instrument it in such a way that
individual fields (not only associations) can be loaded lazily on
first access. This is possible in Java, for example, through
bytecode instrumentation. In PHP though this is not possible, so
there is no way to have "secure" partial objects in an ORM with
transparent persistence.
Doctrine, by default, does not allow partial objects. That means,
any query that only selects partial object data and wants to
retrieve the result as objects (i.e. ``Query#getResult()``) will
raise an exception telling you that partial objects are dangerous.
If you want to force a query to return you partial objects,
possibly as a performance tweak, you can use the ``partial``
keyword as follows:
.. code-block:: php
<?php
$q = $em->createQuery("select partial u.{id,name} from MyApp\Domain\User u");
You can also get a partial reference instead of a proxy reference by
calling:
.. code-block:: php
<?php
$reference = $em->getPartialReference('MyApp\Domain\User', 1);
Partial references are objects with only the identifiers set as they
are passed to the second argument of the ``getPartialReference()`` method.
All other fields are null.
When should I force partial objects?
------------------------------------
Mainly for optimization purposes, but be careful of premature
optimization as partial objects lead to potentially more fragile
code.

View File

@@ -209,6 +209,7 @@ Field & Association Getters
- ``isUniqueField($fieldName)``
- ``isNullable($fieldName)``
- ``isIndexed($fieldName)``
- ``getColumnName($fieldName)``
- ``getFieldMapping($fieldName)``
- ``getAssociationMapping($fieldName)``

View File

@@ -344,10 +344,10 @@ the Query object which can be retrieved from ``EntityManager#createQuery()``.
Executing a Query
^^^^^^^^^^^^^^^^^
The QueryBuilder is a builder object only - it has no means of actually
executing the Query. Additionally a set of parameters such as query hints
cannot be set on the QueryBuilder itself. This is why you always have to convert
a querybuilder instance into a Query object:
The QueryBuilder is only a builder object - it has no means of actually
executing the Query. Additional functionality, such as enabling the result cache,
cannot be set on the QueryBuilder itself. This is why you must always convert
a QueryBuilder instance into a Query object:
.. code-block:: php
@@ -355,9 +355,8 @@ a querybuilder instance into a Query object:
// $qb instanceof QueryBuilder
$query = $qb->getQuery();
// Set additional Query options
$query->setQueryHint('foo', 'bar');
$query->useResultCache('my_cache_id');
// Enable the result cache
$query->enableResultCache(3600, 'my_custom_id');
// Execute Query
$result = $query->getResult();
@@ -555,6 +554,24 @@ using ``addCriteria``:
$qb->addCriteria($criteria);
// then execute your query like normal
Adding hints to a Query
^^^^^^^^^^^^^^^^^^^^^^^
You can also set query hints to a QueryBuilder by using ``setHint``:
.. code-block:: php
<?php
// ...
// $qb instanceof QueryBuilder
$qb->setHint('hintName', 'hintValue');
// then execute your query like normal
The query hint can hold anything the usual query hints can hold
except null. Those hints will be applied to the query when the
query is created.
Low Level API
^^^^^^^^^^^^^
@@ -611,3 +628,21 @@ same query of example 6 written using
->add('from', new Expr\From('User', 'u'))
->add('where', new Expr\Comparison('u.id', '=', '?1'))
->add('orderBy', new Expr\OrderBy('u.name', 'ASC'));
Binding Parameters to Placeholders
----------------------------------
It is often not necessary to know about the exact placeholder names when
building a query. You can use a helper method to bind a value to a placeholder
and directly use that placeholder in your query as a return value:
.. code-block:: php
<?php
// $qb instanceof QueryBuilder
$qb->select('u')
->from('User', 'u')
->where('u.email = ' . $qb->createNamedParameter($userInputEmail))
;
// SELECT u FROM User u WHERE email = :dcValue1

View File

@@ -44,7 +44,7 @@ Something like below for an entity region:
If the entity holds a collection that also needs to be cached.
An collection region could look something like:
A collection region could look something like:
.. code-block:: php
@@ -133,7 +133,7 @@ Caching mode
* Read Write cache employs locks before update/delete.
* Use if data needs to be updated.
* Slowest strategy.
* To use it a the cache region implementation must support locking.
* To use it the cache region implementation must support locking.
Built-in cached persisters
@@ -299,7 +299,7 @@ level cache region.
<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Country">
@@ -351,7 +351,7 @@ It caches the primary keys of association and cache each element will be cached
<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="State">
@@ -518,7 +518,7 @@ DELETE / UPDATE queries
DQL UPDATE / DELETE statements are ported directly into a database and bypass
the second-level cache.
Entities that are already cached will NOT be invalidated.
However the cached data could be evicted using the cache API or an special query hint.
However the cached data could be evicted using the cache API or a special query hint.
Execute the ``UPDATE`` and invalidate ``all cache entries`` using ``Query::HINT_CACHE_EVICT``

View File

@@ -118,7 +118,7 @@ entity might look like this:
}
}
Now the possiblity of mass-assignment exists on this entity and can
Now the possibility of mass-assignment exists on this entity and can
be exploited by attackers to set the "isAdmin" flag to true on any
object when you pass the whole request data to this method like:

View File

@@ -22,7 +22,7 @@ have to register them yourself.
All the commands of the Doctrine Console require access to the
``EntityManager``. You have to inject it into the console application.
Here is an example of a the project-specific ``bin/doctrine`` binary.
Here is an example of a project-specific ``bin/doctrine`` binary.
.. code-block:: php
@@ -84,7 +84,7 @@ The following Commands are currently available:
- ``orm:clear-cache:result`` Clear result cache of the various
cache drivers.
- ``orm:generate-proxies`` Generates proxy classes for entity
classes.
classes. Deprecated in favor of using native lazy objects.
- ``orm:run-dql`` Executes arbitrary DQL directly from the command
line.
- ``orm:schema-tool:create`` Processes the schema and either
@@ -96,6 +96,10 @@ The following Commands are currently available:
- ``orm:schema-tool:update`` Processes the schema and either
update the database schema of EntityManager Storage Connection or
generate the SQL output.
- ``orm:debug:event-manager`` Lists event listeners for an entity
manager, optionally filtered by event name.
- ``orm:debug:entity-listeners`` Lists entity listeners for a given
entity, optionally filtered by event name.
The following alias is defined:

View File

@@ -88,7 +88,7 @@ requirement.
A more convenient alternative for explicit transaction demarcation is the use
of provided control abstractions in the form of
``Connection#transactional($func)`` and ``EntityManager#transactional($func)``.
``Connection#transactional($func)`` and ``EntityManager#wrapInTransaction($func)``.
When used, these control abstractions ensure that you never forget to rollback
the transaction, in addition to the obvious code reduction. An example that is
functionally equivalent to the previously shown code looks as follows:
@@ -96,21 +96,23 @@ functionally equivalent to the previously shown code looks as follows:
.. code-block:: php
<?php
// transactional with Connection instance
// $conn instanceof Connection
$conn->transactional(function($conn) {
// ... do some work
$user = new User;
$user->setName('George');
});
// transactional with EntityManager instance
// $em instanceof EntityManager
$em->transactional(function($em) {
$em->wrapInTransaction(function($em) {
// ... do some work
$user = new User;
$user->setName('George');
$em->persist($user);
});
.. warning::
For historical reasons, ``EntityManager#transactional($func)`` will return
``true`` whenever the return value of ``$func`` is loosely false.
Some examples of this include ``array()``, ``"0"``, ``""``, ``0``, and
``null``.
The difference between ``Connection#transactional($func)`` and
``EntityManager#transactional($func)`` is that the latter
abstraction flushes the ``EntityManager`` prior to transaction

View File

@@ -102,7 +102,7 @@ How Doctrine Detects Changes
----------------------------
Doctrine is a data-mapper that tries to achieve persistence-ignorance (PI).
This means you map php objects into a relational database that don't
This means you map PHP objects into a relational database that don't
necessarily know about the database at all. A natural question would now be,
"how does Doctrine even detect objects have changed?".

View File

@@ -736,6 +736,35 @@ methods:
.. note::
There is a limitation on the compatibility of Criteria comparisons.
You have to use scalar values only as the value in a comparison or
the behaviour between different backends is not the same.
Depending on whether the collection has already been loaded from the
database or not, criteria matching may happen at the database/SQL level
or on objects in memory. This may lead to different results and come
surprising, for example when a code change in one place leads to a collection
becoming initialized and, as a side effect, returning a different result
or even breaking a ``matching()`` call somewhere else. Also, collection
initialization state in practical use cases may differ from the one covered
in unit tests.
Database level comparisons are based on scalar representations of the values
stored in entity properties. The field names passed to expressions correspond
to property names. Comparison and sorting may be affected by
database-specific behavior. For example, MySQL enum types sort by index position,
not lexicographically by value.
In-memory handling is based on the ``Selectable`` API of `Doctrine Collections <https://www.doctrine-project.org/projects/doctrine-collections/en/stable/index.html#matching>`.
In this case, field names passed to expressions are being used to derive accessor
method names. Strict type comparisons are used for equal and not-equal checks,
and generally PHP language rules are being used for other comparison operators
or sorting.
As a general guidance, for consistent results use the Criteria API with scalar
values only. Note that ``DateTime`` and ``DateTimeImmutable`` are two predominant
examples of value objects that are *not* scalars.
Refrain from using special database-level column types or custom Doctrine Types
that may lead to database-specific comparison or sorting rules being applied, or
to database-level values being different from object field values.
Provide accessor methods for all entity fields used in criteria expressions,
and implement those methods in a way that their return value is the
same as the database-level value.

View File

@@ -166,7 +166,7 @@ your code. See the following code:
Traversing the object graph for parts that are lazy-loaded will
easily trigger lots of SQL queries and will perform badly if used
to heavily. Make sure to use DQL to fetch-join all the parts of the
too heavily. Make sure to use DQL to fetch-join all the parts of the
object-graph that you need as efficiently as possible.
@@ -338,10 +338,11 @@ Performance of different deletion strategies
Deleting an object with all its associated objects can be achieved
in multiple ways with very different performance impacts.
1. If an association is marked as ``CASCADE=REMOVE`` Doctrine ORM
will fetch this association. If its a Single association it will
pass this entity to
``EntityManager#remove()``. If the association is a collection, Doctrine will loop over all its elements and pass them to``EntityManager#remove()``.
1. If an association is marked as ``CASCADE=REMOVE`` Doctrine ORM will
fetch this association. If it's a Single association it will pass
this entity to ``EntityManager#remove()``. If the association is a
collection, Doctrine will loop over all its elements and pass them to
``EntityManager#remove()``.
In both cases the cascade remove semantics are applied recursively.
For large object graphs this removal strategy can be very costly.
2. Using a DQL ``DELETE`` statement allows you to delete multiple

View File

@@ -18,7 +18,7 @@ setup for the latest code in trunk.
.. code-block:: xml
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
@@ -46,7 +46,7 @@ In order to work, this requires certain conventions:
.. code-block:: php
<?php
$driver->setFileExtension('.xml');
$driver->getLocator()->setFileExtension('.xml');
It is recommended to put all XML mapping documents in a single
folder but you can spread the documents over several folders if you
@@ -104,7 +104,7 @@ of several common elements:
// Doctrine.Tests.ORM.Mapping.User.dcm.xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
@@ -112,7 +112,6 @@ of several common elements:
<indexes>
<index name="name_idx" columns="name"/>
<index columns="user_email"/>
</indexes>
<unique-constraints>
@@ -131,7 +130,7 @@ of several common elements:
</id>
<field name="name" column="name" type="string" length="50" nullable="true" unique="true" />
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
<field name="email" column="user_email" type="string" index="true" column-definition="CHAR(32) NOT NULL" />
<one-to-one field="address" target-entity="Address" inversed-by="user">
<cascade><cascade-remove /></cascade>
@@ -255,6 +254,8 @@ Optional attributes:
only.
- unique - Should this field contain a unique value across the
table? Defaults to false.
- index - Should an index be created for this column? Defaults to
false.
- nullable - Should this field allow NULL as a value? Defaults to
false.
- insertable - Should this field be inserted? Defaults to true.
@@ -770,7 +771,7 @@ entity relationship. You can define this in XML with the "association-key" attri
.. code-block:: xml
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

View File

@@ -1,80 +1,74 @@
.. toc::
:orphan:
.. tocheader:: Tutorials
.. toctree::
:caption: Tutorials
:depth: 3
.. toctree::
:depth: 3
tutorials/getting-started
tutorials/working-with-indexed-associations
tutorials/extra-lazy-associations
tutorials/composite-primary-keys
tutorials/ordered-associations
tutorials/override-field-association-mappings-in-subclasses
tutorials/pagination
tutorials/embeddables
tutorials/getting-started
tutorials/getting-started-database
tutorials/getting-started-models
tutorials/working-with-indexed-associations
tutorials/extra-lazy-associations
tutorials/composite-primary-keys
tutorials/ordered-associations
tutorials/override-field-association-mappings-in-subclasses
tutorials/pagination
tutorials/embeddables
.. toctree::
:caption: Reference
:depth: 3
.. toc::
reference/architecture
reference/configuration
reference/faq
reference/basic-mapping
reference/association-mapping
reference/inheritance-mapping
reference/working-with-objects
reference/working-with-associations
reference/typedfieldmapper
reference/events
reference/unitofwork
reference/unitofwork-associations
reference/transactions-and-concurrency
reference/batch-processing
reference/dql-doctrine-query-language
reference/query-builder
reference/native-sql
reference/change-tracking-policies
reference/partial-hydration
reference/partial-objects
reference/attributes-reference
reference/xml-mapping
reference/php-mapping
reference/caching
reference/improving-performance
reference/tools
reference/metadata-drivers
reference/best-practices
reference/limitations-and-known-issues
tutorials/pagination
reference/filters
reference/namingstrategy
reference/advanced-configuration
reference/second-level-cache
reference/security
.. tocheader:: Reference
.. toctree::
:caption: Cookbook
:depth: 3
.. toctree::
:depth: 3
reference/architecture
reference/configuration
reference/faq
reference/basic-mapping
reference/association-mapping
reference/inheritance-mapping
reference/working-with-objects
reference/working-with-associations
reference/typedfieldmapper
reference/events
reference/unitofwork
reference/unitofwork-associations
reference/transactions-and-concurrency
reference/batch-processing
reference/dql-doctrine-query-language
reference/query-builder
reference/native-sql
reference/change-tracking-policies
reference/attributes-reference
reference/xml-mapping
reference/php-mapping
reference/caching
reference/improving-performance
reference/tools
reference/metadata-drivers
reference/best-practices
reference/limitations-and-known-issues
tutorials/pagination
reference/filters
reference/namingstrategy
reference/advanced-configuration
reference/second-level-cache
reference/security
.. toc::
.. tocheader:: Cookbook
.. toctree::
:depth: 3
cookbook/aggregate-fields
cookbook/custom-mapping-types
cookbook/decorator-pattern
cookbook/dql-custom-walkers
cookbook/dql-user-defined-functions
cookbook/implementing-arrayaccess-for-domain-objects
cookbook/resolve-target-entity-listener
cookbook/sql-table-prefixes
cookbook/strategy-cookbook-introduction
cookbook/validation-of-entities
cookbook/working-with-datetime
cookbook/mysql-enums
cookbook/advanced-field-value-conversion-using-custom-mapping-types
cookbook/entities-in-session
cookbook/aggregate-fields
cookbook/custom-mapping-types
cookbook/decorator-pattern
cookbook/dql-custom-walkers
cookbook/dql-user-defined-functions
cookbook/generated-columns
cookbook/implementing-arrayaccess-for-domain-objects
cookbook/resolve-target-entity-listener
cookbook/sql-table-prefixes
cookbook/strategy-cookbook-introduction
cookbook/validation-of-entities
cookbook/working-with-datetime
cookbook/mysql-enums
cookbook/advanced-field-value-conversion-using-custom-mapping-types
cookbook/entities-in-session

View File

@@ -54,7 +54,7 @@ and year of production as primary keys:
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
@@ -85,11 +85,12 @@ And for querying you can use arrays to both DQL and EntityRepositories:
namespace VehicleCatalogue\Model;
// $em is the EntityManager
$audi = $em->find("VehicleCatalogue\Model\Car", array("name" => "Audi A8", "year" => 2010));
$audi = $em->find("VehicleCatalogue\Model\Car", ["name" => "Audi A8", "year" => 2010]);
$dql = "SELECT c FROM VehicleCatalogue\Model\Car c WHERE c.id = ?1";
$dql = "SELECT c FROM VehicleCatalogue\Model\Car c WHERE c.name = ?1 AND c.year = ?2";
$audi = $em->createQuery($dql)
->setParameter(1, ["name" => "Audi A8", "year" => 2010])
->setParameter(1, "Audi A8")
->setParameter(2, 2010)
->getSingleResult();
You can also use this entity in associations. Doctrine will then generate two foreign keys one for ``name``
@@ -145,7 +146,7 @@ We keep up the example of an Article with arbitrary attributes, the mapping look
#[OneToMany(targetEntity: ArticleAttribute::class, mappedBy: 'article', cascade: ['ALL'], indexBy: 'attribute')]
private Collection $attributes;
public function addAttribute(string $name, ArticleAttribute $value): void
public function addAttribute(string $name, string $value): void
{
$this->attributes[$name] = new ArticleAttribute($name, $value, $this);
}
@@ -174,7 +175,7 @@ We keep up the example of an Article with arbitrary attributes, the mapping look
.. code-block:: xml
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
@@ -249,7 +250,7 @@ of products purchased and maybe even the current price.
public function __construct(
#[ManyToOne(targetEntity: Customer::class)]
private Customer $customer,
private Customer $customer
) {
$this->items = new ArrayCollection();
$this->created = new DateTime("now");
@@ -294,6 +295,7 @@ of products purchased and maybe even the current price.
$this->order = $order;
$this->product = $product;
$this->offeredPrice = $product->getCurrentPrice();
$this->amount = $amount;
}
}

View File

@@ -17,7 +17,9 @@ can be called without triggering a full load of the collection:
- ``Collection#contains($entity)``
- ``Collection#containsKey($key)``
- ``Collection#count()``
- ``Collection#first()``
- ``Collection#get($key)``
- ``Collection#isEmpty()``
- ``Collection#slice($offset, $length = null)``
For each of the above methods the following semantics apply:
@@ -69,7 +71,7 @@ switch to extra lazy as shown in these examples:
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

View File

@@ -1,26 +0,0 @@
Getting Started: Database First
===============================
.. note:: *Development Workflows*
When you :doc:`Code First <getting-started>`, you
start with developing Objects and then map them onto your database. When
you :doc:`Model First <getting-started-models>`, you are modelling your application using tools (for
example UML) and generate database schema and PHP code from this model.
When you have a Database First, you already have a database schema
and generate the corresponding PHP code from it.
.. note::
This getting started guide is in development.
Development of new applications often starts with an existing database schema.
When the database schema is the starting point for your application, then
development is said to use the *Database First* approach to Doctrine.
In this workflow you would modify the database schema first and then
regenerate the PHP code to use with this schema. You need a flexible
code-generator for this task.
We spun off a subproject, Doctrine CodeGenerator, that will fill this gap and
allow you to do *Database First* development.

View File

@@ -1,24 +0,0 @@
Getting Started: Model First
============================
.. note:: *Development Workflows*
When you :doc:`Code First <getting-started>`, you
start with developing Objects and then map them onto your database. When
you Model First, you are modelling your application using tools (for
example UML) and generate database schema and PHP code from this model.
When you have a :doc:`Database First <getting-started-database>`, then you already have a database schema
and generate the corresponding PHP code from it.
.. note::
This getting started guide is in development.
There are applications when you start with a high-level description of the
model using modelling tools such as UML. Modelling tools could also be Excel,
XML or CSV files that describe the model in some structured way. If your
application is using a modelling tool, then the development workflow is said to
be a *Model First* approach to Doctrine2.
In this workflow you always change the model description and then regenerate
both PHP code and database schema from this model.

View File

@@ -49,8 +49,9 @@ An entity contains persistable properties. A persistable property
is an instance variable of the entity that is saved into and retrieved from the database
by Doctrine's data mapping capabilities.
An entity class must not be final nor read-only, although
it can contain final methods or read-only properties.
An entity class can be final or read-only when you use
:ref:`native lazy objects <reference-native-lazy-objects>`.
It may contain final methods or read-only properties too.
An Example Model: Bug Tracker
-----------------------------
@@ -138,13 +139,13 @@ step:
require_once "vendor/autoload.php";
// Create a simple "default" Doctrine ORM configuration for Attributes
$config = ORMSetup::createAttributeMetadataConfiguration(
paths: array(__DIR__."/src"),
$config = ORMSetup::createAttributeMetadataConfig( // on PHP < 8.4, use ORMSetup::createAttributeMetadataConfiguration()
paths: [__DIR__ . '/src'],
isDevMode: true,
);
// or if you prefer XML
// $config = ORMSetup::createXMLMetadataConfiguration(
// paths: array(__DIR__."/config/xml"),
// $config = ORMSetup::createXMLMetadataConfig( // on PHP < 8.4, use ORMSetup::createXMLMetadataConfiguration()
// paths: [__DIR__ . '/config/xml'],
// isDevMode: true,
//);
@@ -514,7 +515,7 @@ methods, but you only need to choose one.
<!-- config/xml/Product.dcm.xml -->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
@@ -534,7 +535,7 @@ the ``id`` tag. It has a ``generator`` tag nested inside, which
specifies that the primary key generation mechanism should automatically
use the database platform's native id generation strategy (for
example, AUTO INCREMENT in the case of MySql, or Sequences in the
case of PostgreSql and Oracle).
case of PostgreSQL and Oracle).
Now that we have defined our first entity and its metadata,
let's update the database schema:
@@ -1023,7 +1024,7 @@ the ``Product`` before:
<!-- config/xml/Bug.dcm.xml -->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
@@ -1103,7 +1104,7 @@ Finally, we'll add metadata mappings for the ``User`` entity.
<!-- config/xml/User.dcm.xml -->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
@@ -1287,7 +1288,7 @@ The console output of this script is then:
result set to retrieve entities from the database. DQL boils down to a
Native SQL statement and a ``ResultSetMapping`` instance itself. Using
Native SQL you could even use stored procedures for data retrieval, or
make use of advanced non-portable database queries like PostgreSql's
make use of advanced non-portable database queries like PostgreSQL's
recursive queries.
@@ -1586,7 +1587,7 @@ we have to adjust the metadata slightly.
.. code-block:: xml
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

View File

@@ -9,7 +9,7 @@ i.e. attributes and associations metadata in particular. The example here shows
the overriding of a class that uses a trait but is similar when extending a base
class as shown at the end of this tutorial.
Suppose we have a class ExampleEntityWithOverride. This class uses trait ExampleTrait:
Suppose we have a class ``ExampleEntityWithOverride``. This class uses trait ``ExampleTrait``:
.. code-block:: php
@@ -17,22 +17,20 @@ Suppose we have a class ExampleEntityWithOverride. This class uses trait Example
#[Entity]
#[AttributeOverrides([
new AttributeOverride('foo', [
'column' => new Column([
'name' => 'foo_overridden',
'type' => 'integer',
'length' => 140,
'nullable' => false,
'unique' => false,
]),
]),
new AttributeOverride('foo', new Column(
name: 'foo_overridden',
type: 'integer',
length: 140,
nullable: false,
unique: false,
)),
])]
#[AssociationOverrides([
new AssociationOverride('bar', [
'joinColumns' => new JoinColumn([
'name' => 'example_entity_overridden_bar_id',
'referencedColumnName' => 'id',
]),
new JoinColumn(
name: 'example_entity_overridden_bar_id',
referencedColumnName: 'id',
),
]),
])]
class ExampleEntityWithOverride
@@ -47,7 +45,7 @@ Suppose we have a class ExampleEntityWithOverride. This class uses trait Example
private $id;
}
The docblock is showing metadata override of the attribute and association type. It
``#[AttributeOverrides]`` contains metadata override of the attribute and association type. It
basically changes the names of the columns mapped for a property ``foo`` and for
the association ``bar`` which relates to Bar class shown above. Here is the trait
which has mapping metadata that is overridden by the attribute above:

View File

@@ -29,83 +29,11 @@ You can map indexed associations by adding:
The code and mappings for the Market entity looks like this:
.. configuration-block::
.. code-block:: attribute
.. literalinclude:: working-with-indexed-associations/Market.php
:language: attribute
<?php
namespace Doctrine\Tests\Models\StockExchange;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
#[Entity]
#[Table(name: 'exchange_markets')]
class Market
{
#[Id, Column(type: 'integer'), GeneratedValue]
private int|null $id = null;
#[Column(type: 'string')]
private string $name;
/** @var Collection<string, Stock> */
#[OneToMany(targetEntity: Stock::class, mappedBy: 'market', indexBy: 'symbol')]
private Collection $stocks;
public function __construct(string $name)
{
$this->name = $name;
$this->stocks = new ArrayCollection();
}
public function getId(): int|null
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function addStock(Stock $stock): void
{
$this->stocks[$stock->getSymbol()] = $stock;
}
public function getStock(string $symbol): Stock
{
if (!isset($this->stocks[$symbol])) {
throw new \InvalidArgumentException("Symbol is not traded on this market.");
}
return $this->stocks[$symbol];
}
/** @return array<string, Stock> */
public function getStocks(): array
{
return $this->stocks->toArray();
}
}
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\Models\StockExchange\Market">
<id name="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="name" type="string"/>
<one-to-many target-entity="Stock" mapped-by="market" field="stocks" index-by="symbol" />
</entity>
</doctrine-mapping>
.. literalinclude:: working-with-indexed-associations/market.xml
:language: xml
Inside the ``addStock()`` method you can see how we directly set the key of the association to the symbol,
so that we can work with the indexed association directly after invoking ``addStock()``. Inside ``getStock($symbol)``
@@ -150,7 +78,7 @@ here are the code and mappings for it:
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

View File

@@ -0,0 +1,68 @@
<?php
declare(strict_types=1);
namespace Doctrine\Tests\Models\StockExchange;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\Table;
use InvalidArgumentException;
#[Entity]
#[Table(name: 'exchange_markets')]
class Market
{
#[Id]
#[Column(type: 'integer')]
#[GeneratedValue]
private int|null $id = null;
#[Column(type: 'string')]
private string $name;
/** @var Collection<string, Stock> */
#[OneToMany(targetEntity: Stock::class, mappedBy: 'market', indexBy: 'symbol')]
private Collection $stocks;
public function __construct(string $name)
{
$this->name = $name;
$this->stocks = new ArrayCollection();
}
public function getId(): int|null
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function addStock(Stock $stock): void
{
$this->stocks[$stock->getSymbol()] = $stock;
}
public function getStock(string $symbol): Stock
{
if (! isset($this->stocks[$symbol])) {
throw new InvalidArgumentException('Symbol is not traded on this market.');
}
return $this->stocks[$symbol];
}
/** @return array<string, Stock> */
public function getStocks(): array
{
return $this->stocks->toArray();
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="Doctrine\Tests\Models\StockExchange\Market">
<id name="id" type="integer">
<generator strategy="AUTO" />
</id>
<field name="name" type="string"/>
<one-to-many target-entity="Stock" mapped-by="market" field="stocks" index-by="symbol" />
</entity>
</doctrine-mapping>

View File

@@ -155,10 +155,20 @@
</xs:restriction>
</xs:simpleType>
<xs:complexType name="object">
<xs:attribute name="class" type="xs:string" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>
<xs:complexType name="option" mixed="true">
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="option" type="orm:option"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
<xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="object" type="orm:object"/>
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="option" type="orm:option"/>
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
</xs:sequence>
</xs:choice>
<xs:attribute name="name" type="xs:NMTOKEN" use="required"/>
<xs:anyAttribute namespace="##other"/>
@@ -243,6 +253,7 @@
<xs:attribute name="length" type="xs:NMTOKEN" />
<xs:attribute name="unique" type="xs:boolean" default="false" />
<xs:attribute name="nullable" type="xs:boolean" default="false" />
<xs:attribute name="index" type="xs:boolean" default="false" />
<xs:attribute name="insertable" type="xs:boolean" default="true" />
<xs:attribute name="updatable" type="xs:boolean" default="true" />
<xs:attribute name="generated" type="orm:generated-type" default="NEVER" />
@@ -321,7 +332,7 @@
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other"/>
</xs:choice>
<xs:attribute name="value" type="xs:NMTOKEN" use="required"/>
<xs:attribute name="value" type="orm:type" use="required"/>
<xs:attribute name="class" type="orm:fqcn" use="required"/>
<xs:anyAttribute namespace="##other"/>
</xs:complexType>

View File

@@ -1,5 +1,7 @@
<?xml version="1.0"?>
<ruleset>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="PHP_CodeSniffer"
xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
<arg name="basepath" value="."/>
<arg name="extensions" value="php"/>
<arg name="parallel" value="80"/>
@@ -14,7 +16,6 @@
<file>src</file>
<file>tests</file>
<exclude-pattern>*/src/Mapping/InverseJoinColumn.php</exclude-pattern>
<exclude-pattern>*/tests/Tests/Proxies/__CG__*</exclude-pattern>
<exclude-pattern>*/tests/Tests/ORM/Tools/Export/export/*</exclude-pattern>
@@ -49,6 +50,8 @@
</rule>
<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
<exclude-pattern>src/Mapping/Driver/LoadMappingFileImplementation.php</exclude-pattern>
<exclude-pattern>src/Mapping/GetReflectionClassImplementation.php</exclude-pattern>
<exclude-pattern>tests/*</exclude-pattern>
</rule>

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,7 @@ includes:
- phpstan-params.neon
parameters:
reportUnmatchedIgnoredErrors: false # Some errors in the baseline only apply to DBAL 4
ignoreErrors:
# Symfony cache supports passing a key prefix to the clear method.
- '/^Method Psr\\Cache\\CacheItemPoolInterface\:\:clear\(\) invoked with 1 parameter, 0 required\.$/'
@@ -10,20 +11,152 @@ parameters:
# We can be certain that those values are not matched.
-
message: '~^Match expression does not handle remaining values:~'
path: src/Persisters/Entity/BasicEntityPersister.php
path: src/Utility/PersisterHelper.php
# DBAL 4 compatibility
-
message: '~^Method Doctrine\\ORM\\Query\\AST\\Functions\\TrimFunction::getTrimMode\(\) never returns .* so it can be removed from the return type\.$~'
path: src/Query/AST/Functions/TrimFunction.php
-
message: '~^Method Doctrine\\ORM\\Persisters\\Entity\\BasicEntityPersister\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~'
path: src/Persisters/Entity/BasicEntityPersister.php
message: '~.*getTrimExpression.*expects int.*~'
path: src/Query/AST/Functions/TrimFunction.php
-
message: '~^Call to static method unquoted\(\) on an unknown class Doctrine\\DBAL\\Schema\\Name\\Identifier\.$~'
path: src/Tools/SchemaTool.php
-
message: '~^Instantiated class Doctrine\\DBAL\\Schema\\Name\\UnqualifiedName not found\.$~'
path: src/Tools/SchemaTool.php
-
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\Table::addPrimaryKeyConstraint\(\)\.$~'
path: src/Tools/SchemaTool.php
-
message: '~^Call to static method quoted\(\) on an unknown class Doctrine\\DBAL\\Schema\\Name\\Identifier\.$~'
path: src/Tools/SchemaTool.php
-
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\Table\:\:getObjectName\(\)\.$~'
path: src/Mapping/Driver/DatabaseDriver.php
-
message: '~^Call to an undefined method Doctrine\\DBAL\\Schema\\ForeignKeyConstraint::get.*\.$~'
identifier: method.notFound
-
message: '~createComparator~'
identifier: arguments.count
-
message: '~UnqualifiedName~'
identifier: class.notFound
-
message: '~IndexedColumn~'
identifier: class.notFound
-
message: '~PrimaryKeyConstraint~'
identifier: class.notFound
-
message: '~IndexType~'
identifier: class.notFound
-
message: '~dropForeignKey~'
identifier: method.notFound
-
message: '~getIndexedColumns~'
identifier: method.notFound
-
message: '~getPrimaryKeyConstraint~'
identifier: method.notFound
-
message: '~PrimaryKeyConstraint~'
identifier: class.notFound
path: src/Tools/SchemaTool.php
-
message: '~^Call to method toString.*UnqualifiedName\.$~'
path: src/Tools/SchemaTool.php
- '~^Call to method getObjectName\(\) on an unknown class Doctrine\\DBAL\\Schema\\NamedObject\.$~'
- '~^Class Doctrine\\DBAL\\Platforms\\SQLitePlatform not found\.$~'
- '~^Class Doctrine\\DBAL\\Schema\\NamedObject not found\.$~'
-
message: '~sort~'
identifier: argument.unresolvableType
path: src/Mapping/Driver/DatabaseDriver.php
-
message: '#^Parameter \#1 \$asset of static method Doctrine\\ORM\\Mapping\\Driver\\DatabaseDriver\:\:getAssetName\(\) expects Doctrine\\DBAL\\Schema\\AbstractAsset, Doctrine\\DBAL\\Schema\\Column\|false given\.$#'
identifier: argument.type
path: src/Mapping/Driver/DatabaseDriver.php
-
message: '#^Instantiated class Doctrine\\DBAL\\Schema\\DefaultExpression\\\w+ not found\.$#'
identifier: class.notFound
path: src/Tools/SchemaTool.php
# To be removed in 4.0
-
message: '#Negated boolean expression is always false\.#'
paths:
- src/Mapping/Driver/AttributeDriver.php
-
message: '~^Call to deprecated method getEventManager\(\) of class Doctrine\\DBAL\\Connection\.$~'
path: src/EntityManager.php
-
message: '~deprecated class Doctrine\\DBAL\\Tools\\Console\\Command\\ReservedWordsCommand\:~'
path: src/Tools/Console/ConsoleRunner.php
# Compatibility with Persistence 3
-
message: '#Expression on left side of \?\? is not nullable.#'
path: src/Mapping/Driver/AttributeDriver.php
-
message: '~^Method Doctrine\\ORM\\Utility\\PersisterHelper\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~'
path: src/Utility/PersisterHelper.php
-
message: '~inferParameterTypes.*should return~'
path: src/Utility/PersisterHelper.php
-
message: '~.*appendLockHint.*expects.*LockMode given~'
paths:
- src/Persisters/Entity/BasicEntityPersister.php
- src/Persisters/Entity/JoinedSubclassPersister.php
-
message: '~.*executeStatement.*expects~'
path: src/Query/Exec/MultiTableUpdateExecutor.php
-
message: '~method_exists.*getEventManager~'
path: src/EntityManager.php
-
message: '~method_exists.*getIdentitySequence~'
path: src/Mapping/ClassMetadataFactory.php
-
message: '~expand(Criteria)?Parameters.*should return array~'
path: src/Persisters/Entity/BasicEntityPersister.php
-
message: '~inferType.*never returns~'
path: src/Query/ParameterTypeInferer.php

View File

@@ -1,5 +1,5 @@
parameters:
level: 5
level: 7
paths:
- src
- tests/StaticAnalysis
@@ -8,4 +8,4 @@ parameters:
earlyTerminatingMethodCalls:
Doctrine\ORM\Query\Parser:
- syntaxError
phpVersion: 80200
phpVersion: 80400

View File

@@ -10,15 +10,19 @@ parameters:
# We can be certain that those values are not matched.
-
message: '~^Match expression does not handle remaining values:~'
path: src/Persisters/Entity/BasicEntityPersister.php
path: src/Utility/PersisterHelper.php
# The return type is already narrow enough.
- '~^Method Doctrine\\ORM\\Query\\ParameterTypeInferer\:\:inferType\(\) never returns ''[a-z_]+'' so it can be removed from the return type\.$~'
- '~^Method Doctrine\\ORM\\Query\\ParameterTypeInferer\:\:inferType\(\) never returns Doctrine\\DBAL\\(?:Array)?ParameterType\:\:[A-Z_]+ so it can be removed from the return type\.$~'
# DBAL 4 compatibility
-
message: '~^Method Doctrine\\ORM\\Query\\AST\\Functions\\TrimFunction::getTrimMode\(\) never returns .* so it can be removed from the return type\.$~'
path: src/Query/AST/Functions/TrimFunction.php
-
message: '~^Method Doctrine\\ORM\\Persisters\\Entity\\BasicEntityPersister\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~'
path: src/Persisters/Entity/BasicEntityPersister.php
message: '~^Method Doctrine\\ORM\\Utility\\PersisterHelper\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~'
path: src/Utility/PersisterHelper.php
# Compatibility with DBAL 3
# See https://github.com/doctrine/dbal/pull/3480
@@ -33,7 +37,7 @@ parameters:
path: src/UnitOfWork.php
-
message: '~^Parameter #1 \$command of method Symfony\\Component\\Console\\Application::add\(\) expects Symfony\\Component\\Console\\Command\\Command, Doctrine\\DBAL\\Tools\\Console\\Command\\ReservedWordsCommand given\.$~'
message: '~^Parameter #2 \$command of static method Doctrine\\ORM\\Tools\\Console\\ConsoleRunner::addCommandToApplication\(\) expects Symfony\\Component\\Console\\Command\\Command, Doctrine\\DBAL\\Tools\\Console\\Command\\ReservedWordsCommand given\.$~'
path: src/Tools/Console/ConsoleRunner.php
-
@@ -45,3 +49,8 @@ parameters:
message: '#Negated boolean expression is always false\.#'
paths:
- src/Mapping/Driver/AttributeDriver.php
# Compatibility with Persistence 3
-
message: '#Expression on left side of \?\? is not nullable.#'
path: src/Mapping/Driver/AttributeDriver.php

View File

@@ -14,6 +14,8 @@
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
colors="true"
beStrictAboutOutputDuringTests="true"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerNotices="true"
displayDetailsOnTestsThatTriggerWarnings="true"
failOnNotice="true"
@@ -67,5 +69,12 @@
<var name="privileged_db_port" value="3306"/>
-->
<env name="COLUMNS" value="120"/>
<env name="DOCTRINE_DEPRECATIONS" value="trigger"/>
</php>
<source ignoreSuppressionOfDeprecations="true">
<include>
<directory>src</directory>
</include>
</source>
</phpunit>

File diff suppressed because it is too large Load Diff

245
psalm.xml
View File

@@ -1,245 +0,0 @@
<?xml version="1.0"?>
<psalm
errorLevel="2"
phpVersion="8.2"
resolveFromConfigFile="true"
findUnusedBaselineEntry="true"
findUnusedCode="false"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
errorBaseline="psalm-baseline.xml"
>
<projectFiles>
<directory name="src" />
<directory name="tests/StaticAnalysis" />
<ignoreFiles>
<directory name="vendor" />
<file name="src/Mapping/Driver/AttributeReader.php" />
</ignoreFiles>
</projectFiles>
<enableExtensions>
<extension name="simplexml" />
</enableExtensions>
<issueHandlers>
<DeprecatedClass>
<errorLevel type="suppress">
<!-- We wire the command as long as DBAL ships it -->
<referencedClass name="Doctrine\DBAL\Tools\Console\Command\ReservedWordsCommand" />
<!-- Remove on 3.0.x -->
<referencedClass name="Doctrine\ORM\Event\LifecycleEventArgs"/>
<referencedClass name="Doctrine\ORM\Exception\UnknownEntityNamespace"/>
<referencedClass name="Doctrine\ORM\Mapping\Driver\AnnotationDriver"/>
<referencedClass name="Doctrine\ORM\Mapping\Driver\YamlDriver"/>
<referencedClass name="Doctrine\ORM\Mapping\NamedNativeQueries"/>
<referencedClass name="Doctrine\ORM\Mapping\NamedNativeQuery"/>
<referencedClass name="Doctrine\ORM\Mapping\NamedQueries"/>
<referencedClass name="Doctrine\ORM\Mapping\NamedQuery"/>
<referencedClass name="Doctrine\ORM\Query\AST\InExpression"/>
<referencedClass name="Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand"/>
<referencedClass name="Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand"/>
<referencedClass name="Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand"/>
<referencedClass name="Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand"/>
<referencedClass name="Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand"/>
<referencedClass name="Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper"/>
<referencedClass name="Doctrine\ORM\Tools\Console\EntityManagerProvider\HelperSetManagerProvider"/>
</errorLevel>
</DeprecatedClass>
<DeprecatedMethod>
<errorLevel type="suppress">
<!-- Remove on 3.0.x -->
<!-- Compatibility with DBAL 3 -->
<referencedMethod name="Doctrine\DBAL\Connection::getEventManager"/>
<file name="src/Query/TreeWalkerChain.php"/>
</errorLevel>
</DeprecatedMethod>
<DocblockTypeContradiction>
<errorLevel type="suppress">
<!-- We're catching invalid input here. -->
<file name="src/Internal/Hydration/AbstractHydrator.php"/>
<!-- DBAL 3.2 forward compatibility -->
<file name="src/Tools/Pagination/CountOutputWalker.php"/>
<file name="src/Tools/Pagination/LimitSubqueryOutputWalker.php"/>
<!-- https://github.com/vimeo/psalm/issues/8520 -->
<file name="src/PersistentCollection.php"/>
<!-- Remove on 4.0.x -->
<file name="src/Mapping/Driver/AttributeDriver.php"/>
<file name="src/Mapping/Driver/XmlDriver.php"/>
<file name="src/ORMSetup.php"/>
</errorLevel>
</DocblockTypeContradiction>
<ForbiddenCode>
<errorLevel type="suppress">
<file name="src/Tools/Debug.php"/>
</errorLevel>
</ForbiddenCode>
<InvalidArgument>
<errorLevel type="suppress">
<referencedFunction name="Doctrine\ORM\Mapping\ClassMetadata::addInheritedAssociationMapping"/>
</errorLevel>
</InvalidArgument>
<InvalidArrayAccess>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/9160 -->
<file name="src/Mapping/ClassMetadataFactory.php"/>
</errorLevel>
</InvalidArrayAccess>
<InvalidArrayAssignment>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/9160 -->
<file name="src/Mapping/ClassMetadataFactory.php"/>
</errorLevel>
</InvalidArrayAssignment>
<LessSpecificReturnStatement>
<errorLevel type="suppress">
<!-- In DBAL 4, column precision is nullable. See https://github.com/doctrine/dbal/pull/3511 -->
<file name="src/Mapping/Driver/DatabaseDriver.php"/>
</errorLevel>
</LessSpecificReturnStatement>
<MoreSpecificReturnType>
<errorLevel type="suppress">
<!-- In DBAL 4, the default column value is mixed. See https://github.com/doctrine/dbal/pull/3511 -->
<file name="src/Mapping/Driver/DatabaseDriver.php"/>
</errorLevel>
</MoreSpecificReturnType>
<InvalidReturnType>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/8819 -->
<file name="src/Internal/Hydration/AbstractHydrator.php"/>
</errorLevel>
</InvalidReturnType>
<InvalidParamDefault>
<errorLevel type="suppress">
<!-- Remove on 3.0.x -->
<file name="src/Query/AST/InstanceOfExpression.php"/>
</errorLevel>
</InvalidParamDefault>
<InvalidPropertyAssignmentValue>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/9155 -->
<file name="src/Mapping/ClassMetadataFactory.php"/>
</errorLevel>
</InvalidPropertyAssignmentValue>
<MethodSignatureMismatch>
<errorLevel type="suppress">
<!-- See https://github.com/vimeo/psalm/issues/7357 -->
<file name="src/Mapping/ReflectionReadonlyProperty.php"/>
</errorLevel>
</MethodSignatureMismatch>
<MissingParamType>
<errorLevel type="suppress">
<!-- Persistence 2 compatibility -->
<file name="src/EntityManager.php"/>
<file name="src/Mapping/ClassMetadataFactory.php"/>
<file name="src/Mapping/ClassMetadata.php"/>
</errorLevel>
</MissingParamType>
<PossiblyInvalidArgument>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/9155 -->
<file name="src/Mapping/ClassMetadataFactory.php"/>
</errorLevel>
</PossiblyInvalidArgument>
<PossiblyNullArrayOffset>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/7878 -->
<file name="src/Persisters/Collection/ManyToManyPersister.php"/>
</errorLevel>
</PossiblyNullArrayOffset>
<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<directory name="src/Query/AST" />
</errorLevel>
</PropertyNotSetInConstructor>
<PropertyTypeCoercion>
<errorLevel type="suppress">
<file name="src/Mapping/ClassMetadata.php"/>
</errorLevel>
</PropertyTypeCoercion>
<RedundantCastGivenDocblockType>
<errorLevel type="suppress">
<!-- Can be removed once the "getMaxResults" methods of those classes have native parameter types -->
<file name="src/Query.php"/>
<file name="src/QueryBuilder.php"/>
</errorLevel>
</RedundantCastGivenDocblockType>
<ReferenceConstraintViolation>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/9155 -->
<file name="src/Mapping/ClassMetadataFactory.php"/>
</errorLevel>
</ReferenceConstraintViolation>
<RiskyTruthyFalsyComparison>
<!-- TODO: Enable this new rule on higher branches. -->
<errorLevel type="suppress">
<directory name="src" />
</errorLevel>
</RiskyTruthyFalsyComparison>
<TooManyArguments>
<errorLevel type="suppress">
<!-- Symfony cache supports passing a key prefix to the clear method. -->
<referencedFunction name="Psr\Cache\CacheItemPoolInterface::clear"/>
<!-- Persistence 2 compatibility -->
<referencedFunction name="Doctrine\Persistence\ObjectManager::clear"/>
<!-- See https://github.com/doctrine/orm/issues/8850 -->
<referencedFunction name="Doctrine\DBAL\Connection::lastInsertId"/>
<!-- FIXME -->
<referencedFunction name="Doctrine\DBAL\DriverManager::getConnection"/>
</errorLevel>
</TooManyArguments>
<TypeDoesNotContainNull>
<errorLevel type="suppress">
<!-- DBAL 3 compatibility -->
<file name="src/Tools/SchemaTool.php"/>
</errorLevel>
</TypeDoesNotContainNull>
<TypeDoesNotContainType>
<errorLevel type="suppress">
<file name="src/Internal/SQLResultCasing.php"/>
<file name="src/Mapping/ClassMetadataFactory.php"/>
<!-- DBAL 3 compatibility -->
<file name="src/UnitOfWork.php"/>
<file name="src/Utility/LockSqlHelper.php"/>
</errorLevel>
</TypeDoesNotContainType>
<UndefinedClass>
<errorLevel type="suppress">
<!-- Compatibility with DBAL 3 -->
<referencedClass name="Doctrine\DBAL\Platforms\SQLitePlatform"/>
</errorLevel>
</UndefinedClass>
<UndefinedMethod>
<errorLevel type="suppress">
<!-- Compatibility with DBAL 3 -->
<referencedMethod name="Doctrine\DBAL\Connection::getEventManager"/>
<!-- FIXME -->
<referencedMethod name="Doctrine\DBAL\Schema\SchemaDiff::toSaveSql"/>
</errorLevel>
</UndefinedMethod>
<UndefinedPropertyFetch>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/7878 -->
<file name="src/Persisters/Collection/ManyToManyPersister.php"/>
<file name="src/PersistentCollection.php"/>
<file name="src/Utility/PersisterHelper.php"/>
<file name="src/Tools/SchemaValidator.php"/>
</errorLevel>
</UndefinedPropertyFetch>
<UnhandledMatchCondition>
<errorLevel type="suppress">
<!-- We can be certain that those values are not matched. -->
<file name="src/Persisters/Entity/BasicEntityPersister.php"/>
</errorLevel>
</UnhandledMatchCondition>
<ArgumentTypeCoercion>
<errorLevel type="suppress">
<!-- See https://github.com/JetBrains/phpstorm-stubs/pull/1383 -->
<file name="src/Mapping/ClassMetadata.php"/>
</errorLevel>
</ArgumentTypeCoercion>
</issueHandlers>
</psalm>

View File

@@ -1,21 +0,0 @@
#!/bin/bash
# This script is a small convenience wrapper for running the doctrine testsuite against a large bunch of databases.
# Just create the phpunit.xmls as described in the array below and configure the specific files <php /> section
# to connect to that database. Just omit a file if you don't have that database and the tests will be skipped.
configs[1]="mysql.phpunit.xml"
configs[2]='postgres.phpunit.xml'
configs[3]='sqlite.phpunit.xml'
configs[4]='oracle.phpunit.xml'
configs[5]='db2.phpunit.xml'
configs[6]='pdo-ibm.phpunit.xml'
configs[7]='sqlsrv.phpunit.xml'
for i in "${configs[@]}"; do
if [ -f "$i" ];
then
echo "RUNNING TESTS WITH CONFIG $i"
phpunit -c "$i" "$@"
fi;
done

View File

@@ -18,7 +18,6 @@ use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\MappingException as ORMMappingException;
use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
use Doctrine\ORM\Query\Parameter;
use Doctrine\ORM\Query\QueryException;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\Mapping\MappingException;
use LogicException;
@@ -83,7 +82,7 @@ abstract class AbstractQuery
* The parameter map of this query.
*
* @var ArrayCollection|Parameter[]
* @psalm-var ArrayCollection<int, Parameter>
* @phpstan-var ArrayCollection<int, Parameter>
*/
protected ArrayCollection $parameters;
@@ -95,14 +94,14 @@ abstract class AbstractQuery
/**
* The map of query hints.
*
* @psalm-var array<string, mixed>
* @phpstan-var array<string, mixed>
*/
protected array $hints = [];
/**
* The hydration mode.
*
* @psalm-var string|AbstractQuery::HYDRATE_*
* @phpstan-var string|AbstractQuery::HYDRATE_*
*/
protected string|int $hydrationMode = self::HYDRATE_OBJECT;
@@ -130,7 +129,7 @@ abstract class AbstractQuery
/**
* Second level query cache mode.
*
* @psalm-var Cache::MODE_*|null
* @phpstan-var Cache::MODE_*|null
*/
protected int|null $cacheMode = null;
@@ -217,14 +216,14 @@ abstract class AbstractQuery
return $this;
}
/** @psalm-return Cache::MODE_*|null */
/** @phpstan-return Cache::MODE_*|null */
public function getCacheMode(): int|null
{
return $this->cacheMode;
}
/**
* @psalm-param Cache::MODE_* $cacheMode
* @phpstan-param Cache::MODE_* $cacheMode
*
* @return $this
*/
@@ -267,7 +266,7 @@ abstract class AbstractQuery
/**
* Get all defined parameters.
*
* @psalm-return ArrayCollection<int, Parameter>
* @phpstan-return ArrayCollection<int, Parameter>
*/
public function getParameters(): ArrayCollection
{
@@ -286,7 +285,7 @@ abstract class AbstractQuery
$key = Parameter::normalizeName($key);
$filteredParameters = $this->parameters->filter(
static fn (Parameter $parameter): bool => $parameter->getName() === $key
static fn (Parameter $parameter): bool => $parameter->getName() === $key,
);
return ! $filteredParameters->isEmpty() ? $filteredParameters->first() : null;
@@ -296,14 +295,14 @@ abstract class AbstractQuery
* Sets a collection of query parameters.
*
* @param ArrayCollection|mixed[] $parameters
* @psalm-param ArrayCollection<int, Parameter>|mixed[] $parameters
* @phpstan-param ArrayCollection<int, Parameter>|mixed[] $parameters
*
* @return $this
*/
public function setParameters(ArrayCollection|array $parameters): static
{
if (is_array($parameters)) {
/** @psalm-var ArrayCollection<int, Parameter> $parameterCollection */
/** @phpstan-var ArrayCollection<int, Parameter> $parameterCollection */
$parameterCollection = new ArrayCollection();
foreach ($parameters as $key => $value) {
@@ -642,7 +641,7 @@ abstract class AbstractQuery
* Change the default fetch mode of an association for this query.
*
* @param class-string $class
* @psalm-param Mapping\ClassMetadata::FETCH_EAGER|Mapping\ClassMetadata::FETCH_LAZY $fetchMode
* @phpstan-param Mapping\ClassMetadata::FETCH_EAGER|Mapping\ClassMetadata::FETCH_LAZY $fetchMode
*/
public function setFetchMode(string $class, string $assocName, int $fetchMode): static
{
@@ -656,7 +655,7 @@ abstract class AbstractQuery
*
* @param string|int $hydrationMode Doctrine processing mode to be used during hydration process.
* One of the Query::HYDRATE_* constants.
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_* $hydrationMode
*
* @return $this
*/
@@ -670,7 +669,7 @@ abstract class AbstractQuery
/**
* Gets the hydration mode currently used by the query.
*
* @psalm-return string|AbstractQuery::HYDRATE_*
* @phpstan-return string|AbstractQuery::HYDRATE_*
*/
public function getHydrationMode(): string|int
{
@@ -682,7 +681,7 @@ abstract class AbstractQuery
*
* Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
*
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_* $hydrationMode
*/
public function getResult(string|int $hydrationMode = self::HYDRATE_OBJECT): mixed
{
@@ -728,7 +727,7 @@ abstract class AbstractQuery
/**
* Get exactly one result or null.
*
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*
* @throws NonUniqueResultException
*/
@@ -763,7 +762,7 @@ abstract class AbstractQuery
* If the result is not unique, a NonUniqueResultException is thrown.
* If there is no result, a NoResultException is thrown.
*
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*
* @throws NonUniqueResultException If the query result is not unique.
* @throws NoResultException If the query returned no result.
@@ -843,8 +842,8 @@ abstract class AbstractQuery
* Executes the query and returns an iterable that can be used to incrementally
* iterate over the result.
*
* @psalm-param ArrayCollection<int, Parameter>|mixed[] $parameters
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
* @phpstan-param ArrayCollection<int, Parameter>|mixed[] $parameters
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*
* @return iterable<mixed>
*/
@@ -865,10 +864,6 @@ abstract class AbstractQuery
throw new LogicException('Uninitialized result set mapping.');
}
if ($rsm->isMixed && count($rsm->scalarMappings) > 0) {
throw QueryException::iterateWithMixedResultNotAllowed();
}
$stmt = $this->_doExecute();
return $this->em->newHydrator($this->hydrationMode)->toIterable($stmt, $rsm, $this->hints);
@@ -877,8 +872,8 @@ abstract class AbstractQuery
/**
* Executes the query.
*
* @psalm-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
* @phpstan-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*/
public function execute(
ArrayCollection|array|null $parameters = null,
@@ -894,8 +889,8 @@ abstract class AbstractQuery
/**
* Execute query ignoring second level cache.
*
* @psalm-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
* @phpstan-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*/
private function executeIgnoreQueryCache(
ArrayCollection|array|null $parameters = null,
@@ -965,8 +960,8 @@ abstract class AbstractQuery
/**
* Load from second level cache or executes the query and put into cache.
*
* @psalm-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
* @phpstan-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*/
private function executeUsingQueryCache(
ArrayCollection|array|null $parameters = null,
@@ -1029,7 +1024,7 @@ abstract class AbstractQuery
* automatically generated for you.
*
* @return string[] ($key, $hash)
* @psalm-return array{string, string} ($key, $hash)
* @phpstan-return array{string, string} ($key, $hash)
*/
protected function getHydrationCacheId(): array
{
@@ -1070,7 +1065,7 @@ abstract class AbstractQuery
}
/**
* Executes the query and returns a the resulting Statement object.
* Executes the query and returns the resulting Statement object.
*
* @return Result|int The executed database statement that holds
* the results, or an integer indicating how

View File

@@ -22,18 +22,21 @@ class CollectionCacheKey extends CacheKey
public readonly array $ownerIdentifier;
/**
* @param class-string $entityClass The owner entity class.
* @param array<string, mixed> $ownerIdentifier The identifier of the owning entity.
* @param class-string $entityClass The owner entity class
*/
public function __construct(
public readonly string $entityClass,
public readonly string $association,
array $ownerIdentifier,
string $filterHash = '',
) {
ksort($ownerIdentifier);
$this->ownerIdentifier = $ownerIdentifier;
parent::__construct(str_replace('\\', '.', strtolower($entityClass)) . '_' . implode(' ', $ownerIdentifier) . '__' . $association);
$filterHash = $filterHash === '' ? '' : '_' . $filterHash;
parent::__construct(str_replace('\\', '.', strtolower($entityClass)) . '_' . implode(' ', $ownerIdentifier) . '__' . $association . $filterHash);
}
}

View File

@@ -25,7 +25,7 @@ class DefaultCache implements Cache
/**
* @var QueryCache[]
* @psalm-var array<string, QueryCache>
* @phpstan-var array<string, QueryCache>
*/
private array $queryCaches = [];

View File

@@ -16,6 +16,7 @@ use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\UnitOfWork;
use function array_map;
@@ -210,6 +211,10 @@ class DefaultQueryCache implements QueryCache
throw FeatureNotImplemented::nonSelectStatements();
}
if (($hints[SqlWalker::HINT_PARTIAL] ?? false) === true || ($hints[Query::HINT_FORCE_PARTIAL_LOAD] ?? false) === true) {
throw FeatureNotImplemented::partialEntities();
}
if (! ($key->cacheMode & Cache::MODE_PUT)) {
return false;
}
@@ -226,7 +231,6 @@ class DefaultQueryCache implements QueryCache
$region = $persister->getCacheRegion();
$cm = $this->em->getClassMetadata($entityName);
assert($cm instanceof ClassMetadata);
foreach ($result as $index => $entity) {
$identifier = $this->uow->getEntityIdentifier($entity);
@@ -292,7 +296,7 @@ class DefaultQueryCache implements QueryCache
/**
* @return mixed[]|null
* @psalm-return array{targetEntity: class-string, type: mixed, list?: array[], identifier?: array}|null
* @phpstan-return array{targetEntity: class-string, type: mixed, list?: array[], identifier?: array}|null
*/
private function storeAssociationCache(QueryCacheKey $key, AssociationMapping $assoc, mixed $assocValue): array|null
{
@@ -343,7 +347,7 @@ class DefaultQueryCache implements QueryCache
];
}
/** @psalm-return list<mixed>|object|null */
/** @phpstan-return list<mixed>|object|null */
private function getAssociationValue(
ResultSetMapping $rsm,
string $assocAlias,
@@ -369,9 +373,9 @@ class DefaultQueryCache implements QueryCache
}
/**
* @psalm-param array<array-key, array{field: string, class: string}> $path
* @phpstan-param array<array-key, array{field: string, class: string}> $path
*
* @psalm-return list<mixed>|object|null
* @phpstan-return list<mixed>|object|null
*/
private function getAssociationPathValue(mixed $value, array $path): array|object|null
{

View File

@@ -11,8 +11,8 @@ use function array_map;
class EntityCacheEntry implements CacheEntry
{
/**
* @param array<string,mixed> $data The entity map data
* @psalm-param class-string $class The entity class name
* @param class-string $class The entity class name
* @param array<string,mixed> $data The entity map data
*/
public function __construct(
public readonly string $class,

View File

@@ -20,4 +20,9 @@ class FeatureNotImplemented extends CacheException
{
return new self('Second-level cache query supports only select statements.');
}
public static function partialEntities(): self
{
return new self('Second level cache does not support partial entities.');
}
}

View File

@@ -18,6 +18,7 @@ use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Persisters\Collection\CollectionPersister;
use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
use Doctrine\ORM\Query\FilterCollection;
use Doctrine\ORM\UnitOfWork;
use function array_values;
@@ -35,6 +36,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
protected array $queuedCache = [];
protected string $regionName;
protected FilterCollection $filters;
protected CollectionHydrator $hydrator;
protected CacheLogger|null $cacheLogger;
@@ -48,6 +50,10 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
$cacheConfig = $configuration->getSecondLevelCacheConfiguration();
$cacheFactory = $cacheConfig->getCacheFactory();
$this->region = $region;
$this->persister = $persister;
$this->association = $association;
$this->filters = $em->getFilters();
$this->regionName = $region->getName();
$this->uow = $em->getUnitOfWork();
$this->metadataFactory = $em->getMetadataFactory();
@@ -135,7 +141,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
public function count(PersistentCollection $collection): int
{
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId);
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId, $this->filters->getHash());
$entry = $this->region->get($key);
if ($entry !== null) {

View File

@@ -36,7 +36,7 @@ class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPers
public function delete(PersistentCollection $collection): void
{
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId);
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId, $this->filters->getHash());
$this->persister->delete($collection);
@@ -53,7 +53,7 @@ class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPers
}
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId);
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId, $this->filters->getHash());
// Invalidate non initialized collections OR ordered collection
if ($isDirty && ! $isInitialized || $this->association->isOrdered()) {

Some files were not shown because too many files have changed in this diff Show More