Compare commits

...

149 Commits

Author SHA1 Message Date
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
04694a9f7b Merge pull request #11835 from gseidel/fix-pre-persist-call-persist
fix: calling scheduleForInsert twice
2025-08-07 06:25:35 +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
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
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
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
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
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
Alexander M. Turek
5d21bb158b Fix calls to Application::add() (#12006) 2025-06-18 08:58:26 +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
e9f0345a97 Merge pull request #11966 from greg0ire/partial-revert-10162-2
Partially revert to stdout
2025-06-07 09:41:03 +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
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
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
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
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
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
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
Stefan Gehrig
067ad51b3f fixes sqlite sql inconsistency 2025-03-17 08:48:30 +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
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
Stefan Gehrig
d96fc23327 skips tests when running on postgres 2025-02-27 10:30:21 +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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Joren Martens
14866461c5 [DDC-551] fix, add filter support in oneToOne relation 2024-11-07 10:48:16 +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
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
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
182469b346 Fix copy/paste/adapt mistake (#11684)
The last step was missing.
2024-10-16 22:59:19 +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
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
Alexander M. Turek
f53350934f Psalm 5.26.1 (#11677) 2024-10-13 22:04:07 +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
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
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
MatteoFeltrin
73e30df52b allow classname in 'value' attribute of xml discriminator-mapping field 2024-05-20 11:00:23 +02:00
382 changed files with 8804 additions and 5034 deletions

2
.gitattributes vendored
View File

@@ -19,5 +19,3 @@ phpstan-baseline.neon export-ignore
phpstan-dbal2.neon export-ignore
phpstan-params.neon export-ignore
phpstan-persistence2.neon export-ignore
psalm.xml export-ignore
psalm-baseline.xml export-ignore

View File

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

View File

@@ -1,4 +1,4 @@
name: "Continuous Integration"
name: "CI"
on:
pull_request:
@@ -119,7 +119,7 @@ jobs:
- "default"
- "3@dev"
postgres-version:
- "15"
- "17"
extension:
- pdo_pgsql
- pgsql
@@ -363,6 +363,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"
@@ -381,7 +383,7 @@ jobs:
path: "reports"
- name: "Upload to Codecov"
uses: "codecov/codecov-action@v4"
uses: "codecov/codecov-action@v5"
with:
directory: reports
env:

View File

@@ -17,4 +17,4 @@ on:
jobs:
documentation:
name: "Documentation"
uses: "doctrine/.github/.github/workflows/documentation.yml@5.1.0"
uses: "doctrine/.github/.github/workflows/documentation.yml@7.3.0"

View File

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

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:
@@ -48,7 +46,7 @@ jobs:
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "8.3"
php-version: "8.4"
- name: "Require specific DBAL version"
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
@@ -73,31 +71,3 @@ jobs:
- name: "Run a static analysis with phpstan/phpstan"
run: "vendor/bin/phpstan analyse -c phpstan-persistence2.neon"
if: "${{ matrix.dbal-version == 'default' && matrix.persistence-version != 'default'}}"
static-analysis-psalm:
name: "Static Analysis with Psalm"
runs-on: "ubuntu-22.04"
strategy:
fail-fast: false
steps:
- name: "Checkout code"
uses: "actions/checkout@v4"
- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "8.3"
- name: "Require specific persistence version"
run: "composer require doctrine/persistence ^3.1 --no-update"
- name: "Install dependencies with Composer"
uses: "ramsey/composer-install@v3"
with:
dependency-versions: "highest"
- name: "Run a static analysis with vimeo/psalm"
run: "vendor/bin/psalm --show-info=false --stats --output-format=github --threads=$(nproc)"

View File

@@ -1,7 +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.6.x][3.6] | [3.5.x][3.5] | [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] |
| [![Build status][4.0 image]][4.0 workflow] | [![Build status][3.6 image]][3.6 workflow] | [![Build status][3.5 image]][3.5 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.6 coverage image]][3.6 coverage] | [![Coverage Status][3.5 coverage image]][3.5 coverage] | [![Coverage Status][2.21 coverage image]][2.21 coverage] | [![Coverage Status][2.20 coverage image]][2.20 coverage] |
[<h1 align="center">🇺🇦 UKRAINE NEEDS YOUR HELP NOW!</h1>](https://www.doctrine-project.org/stop-war.html)
@@ -20,21 +20,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.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
[3.5 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.5.x
[3.5]: https://github.com/doctrine/orm/tree/3.5.x
[3.5 workflow]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml?query=branch%3A3.5.x
[3.5 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.5.x/graph/badge.svg
[3.5 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.5.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

@@ -41,18 +41,17 @@
},
"require-dev": {
"doctrine/annotations": "^1.13 || ^2",
"doctrine/coding-standard": "^9.0.2 || ^12.0",
"doctrine/coding-standard": "^9.0.2 || ^13.0",
"phpbench/phpbench": "^0.16.10 || ^1.0",
"phpstan/extension-installer": "~1.1.0 || ^1.4",
"phpstan/phpstan": "~1.4.10 || 1.12.6",
"phpstan/phpstan-deprecation-rules": "^1",
"phpstan/phpstan": "~1.4.10 || 2.0.3",
"phpstan/phpstan-deprecation-rules": "^1 || ^2",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.6",
"psr/log": "^1 || ^2 || ^3",
"squizlabs/php_codesniffer": "3.7.2",
"squizlabs/php_codesniffer": "3.12.0",
"symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0",
"symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0",
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0",
"vimeo/psalm": "4.30.0 || 5.24.0"
"symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0"
},
"conflict": {
"doctrine/annotations": "<1.13 || >= 3.0"

3
docs/.gitignore vendored Normal file
View File

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

24
docs/Makefile Normal file
View File

@@ -0,0 +1,24 @@
# Makefile for Doctrine ORM documentation
#
# You can set these variables from the command line.
DOCOPTS =
BUILD = vendor/bin/guides
BUILDDIR = build
# Internal variables.
ALLGUIDESOPTS = $(DOCOPTS) en/
.PHONY: help clean html
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
clean:
-rm -rf ./$(BUILDDIR)/*
html:
$(BUILD) $(ALLGUIDESOPTS) --output=$(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

View File

@@ -1,18 +1,22 @@
# 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 `docs/` folder, run
It will generate the documentation into the build directory of the checkout.
composer update
Then compile the documentation with:
## Theme issues
make html
If you get a "Theme error", check if the `en/_theme` subdirectory is empty,
in which case you will need to run:
This will generate the documentation into the `build` subdirectory.
1. git submodule init
2. git submodule update
To browse the documentation, you need to run a webserver:
cd build/html
php -S localhost:8000
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

10
docs/composer.json Normal file
View File

@@ -0,0 +1,10 @@
{
"name": "doctrine/orm-docs",
"description": "Documentation for the Object-Relational Mapper\"",
"type": "library",
"license": "MIT",
"require": {
"phpdocumentor/guides-cli": "1.7.1",
"phpdocumentor/filesystem": "1.7.1"
}
}

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,93 +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',
'yaml': 'YAML',
'jinja': 'Twig',
'html+jinja': 'Twig',
'jinja+html': 'Twig',
'php+html': 'PHP',
'html+php': 'PHP',
'ini': 'INI',
'php-annotations': 'Annotations',
}
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)

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

@@ -103,6 +103,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>`
@@ -123,4 +124,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

@@ -71,8 +71,8 @@ Configuration Options
The following sections describe all the configuration options
available on a ``Doctrine\ORM\Configuration`` instance.
Proxy Directory (***REQUIRED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Proxy Directory (**REQUIRED**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: php
@@ -85,8 +85,8 @@ 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**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: php
@@ -98,8 +98,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
@@ -144,8 +144,8 @@ 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.
Metadata Cache (***RECOMMENDED***)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Metadata Cache (**RECOMMENDED**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block:: php
@@ -166,8 +166,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
@@ -189,8 +189,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
@@ -202,8 +202,8 @@ 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**)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Proxy classes can either be generated manually through the Doctrine
Console or automatically at runtime by Doctrine. The configuration
@@ -446,7 +446,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.
@@ -461,7 +461,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

@@ -1368,8 +1368,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::
@@ -1409,7 +1408,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
@@ -1418,7 +1417,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;
@@ -1427,7 +1426,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>
@@ -1442,7 +1441,6 @@ Is essentially the same as following:
joinColumn:
name: shipment_id
referencedColumnName: id
nullable: false
If you accept these defaults, you can reduce the mapping code to a
minimum.

View File

@@ -213,12 +213,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
@@ -261,10 +264,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 +370,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>`.
@@ -678,8 +682,10 @@ Optional parameters:
- **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

View File

@@ -239,6 +239,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),

View File

@@ -299,7 +299,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

@@ -323,7 +323,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">
@@ -431,7 +431,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">

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

@@ -17,7 +17,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">
@@ -103,7 +103,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">
@@ -770,7 +770,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

@@ -65,6 +65,7 @@
cookbook/decorator-pattern
cookbook/dql-custom-walkers
cookbook/dql-user-defined-functions
cookbook/generated-columns
cookbook/implementing-arrayaccess-for-domain-objects
cookbook/implementing-the-notify-changetracking-policy
cookbook/resolve-target-entity-listener

View File

@@ -86,7 +86,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">
@@ -127,11 +127,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``
@@ -268,7 +269,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">

View File

@@ -18,6 +18,7 @@ can be called without triggering a full load of the collection:
- ``Collection#containsKey($key)``
- ``Collection#count()``
- ``Collection#get($key)``
- ``Collection#isEmpty()``
- ``Collection#slice($offset, $length = null)``
For each of the above methods the following semantics apply:
@@ -86,7 +87,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

@@ -558,7 +558,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">
@@ -1139,7 +1139,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">
@@ -1294,7 +1294,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">
@@ -1818,7 +1818,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

@@ -31,169 +31,18 @@ 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;
.. literalinclude:: working-with-indexed-associations/Market-annotations.php
:language: annotation
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
.. literalinclude:: working-with-indexed-associations/market.xml
:language: xml
#[Entity]
#[Table(name: 'exchange_markets')]
class Market
{
#[Id, Column(type: 'integer'), GeneratedValue]
private int|null $id = null;
.. literalinclude:: working-with-indexed-associations/market.yaml
:language: yaml
#[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:: annotation
<?php
namespace Doctrine\Tests\Models\StockExchange;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @Entity
* @Table(name="exchange_markets")
*/
class Market
{
/**
* @Id @Column(type="integer") @GeneratedValue
* @var int
*/
private int|null $id = null;
/**
* @Column(type="string")
* @var string
*/
private string $name;
/**
* @OneToMany(targetEntity="Stock", mappedBy="market", indexBy="symbol")
* @var Collection<int, Stock>
*/
private Collection $stocks;
public function __construct($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($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>
.. code-block:: yaml
Doctrine\Tests\Models\StockExchange\Market:
type: entity
id:
id:
type: integer
generator:
strategy: AUTO
fields:
name:
type:string
oneToMany:
stocks:
targetEntity: Stock
mappedBy: market
indexBy: symbol
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)``
@@ -279,7 +128,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,74 @@
<?php
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
* @var int
*/
private int|null $id = null;
/**
* @Column(type="string")
* @var string
*/
private string $name;
/**
* @OneToMany(targetEntity="Stock", mappedBy="market", indexBy="symbol")
* @var Collection<int, Stock>
*/
private Collection $stocks;
public function __construct($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($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,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

@@ -0,0 +1,15 @@
Doctrine\Tests\Models\StockExchange\Market:
type: entity
id:
id:
type: integer
generator:
strategy: AUTO
fields:
name:
type:string
oneToMany:
stocks:
targetEntity: Stock
mappedBy: market
indexBy: symbol

View File

@@ -375,7 +375,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"/>

File diff suppressed because it is too large Load Diff

View File

@@ -7,6 +7,7 @@ parameters:
ignoreErrors:
# PHPStan doesn't understand our method_exists() safeguards.
- '/Call to function method_exists.*/'
- '/Call to an undefined method Doctrine\\DBAL\\Connection::createSchemaManager\(\)\./'
# Class name will change in DBAL 3.
- '/^Class Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform not found\.$/'
@@ -46,6 +47,16 @@ parameters:
path: src/Query/AST/Functions/LocateFunction.php
# Won't get fixed in DBAL 2
-
message: '#.*deleteItem.*expects string.*#'
count: 1
path: src/Query.php
-
message: '#.*get(Drop|Create)SchemaS(ql|QL).*should return list.*but returns array.*#'
count: 2
path: src/Tools/SchemaTool.php
-
message: "#^Parameter \\#2 \\$start of method Doctrine\\\\DBAL\\\\Platforms\\\\AbstractPlatform\\:\\:getSubstringExpression\\(\\) expects int, string given\\.$#"
count: 1
@@ -66,6 +77,19 @@ parameters:
message: '~deprecated class Doctrine\\DBAL\\Tools\\Console\\Command\\ImportCommand\:~'
path: src/Tools/Console/ConsoleRunner.php
-
message: '#^Method Doctrine\\ORM\\AbstractQuery\:\:getHydrationCacheId\(\) should return array\{string, string\} but returns array\<string\>\.$#'
path: src/AbstractQuery.php
-
message: '#^Method Doctrine\\ORM\\Internal\\Hydration\\AbstractHydrator\:\:\w+\(\) has parameter \$stmt with no value type specified in iterable type Doctrine\\DBAL\\Driver\\ResultStatement\.$#'
path: src/Internal/Hydration/AbstractHydrator.php
-
message: '#^Parameter \#1 \$key of method Psr\\Cache\\CacheItemPoolInterface\:\:deleteItem\(\) expects string, string\|false given\.$#'
path: src/Query
# Symfony cache supports passing a key prefix to the clear method.
- '/^Method Psr\\Cache\\CacheItemPoolInterface\:\:clear\(\) invoked with 1 parameter, 0 required\.$/'

View File

@@ -1,5 +1,5 @@
parameters:
level: 5
level: 7
paths:
- src
- tests/StaticAnalysis
@@ -8,8 +8,4 @@ parameters:
earlyTerminatingMethodCalls:
Doctrine\ORM\Query\Parser:
- syntaxError
phpVersion: 80200
ignoreErrors:
# Remove on 3.0.x
- '~^Default value of the parameter #2 \$value \(array\{\}\) of method Doctrine\\ORM\\Query\\AST\\InstanceOfExpression\:\:__construct\(\) is incompatible with type non\-empty\-array<int, Doctrine\\ORM\\Query\\AST\\InputParameter\|string>\.$~'
phpVersion: 80400

View File

@@ -11,7 +11,7 @@ parameters:
# Fallback logic for DBAL 2
-
message: '/Application::add\(\) expects Symfony\\Component\\Console\\Command\\Command/'
message: '/Parameter #2 \$command of static method Doctrine\\ORM\\Tools\\Console\\ConsoleRunner\:\:addCommandToApplication\(\) expects Symfony\\Component\\Console\\Command\\Command/'
path: src/Tools/Console/ConsoleRunner.php
- '/^Class Doctrine\\DBAL\\Platforms\\SQLAnywherePlatform not found\.$/'
@@ -82,3 +82,21 @@ parameters:
-
message: '~deprecated class Doctrine\\Common\\Persistence\\PersistentObject\:~'
path: src/EntityManager.php
-
message: '#Cannot access offset \S+ on .*ClassMetadata.*#'
paths:
- src/Mapping/Driver/XmlDriver.php
- src/Mapping/Driver/YamlDriver.php
-
message: '#^Parameter \#1 \$orderings of method Doctrine\\Common\\Collections\\Criteria\:\:orderBy\(\) expects array\<string\>, array\<string, Doctrine\\Common\\Collections\\Order\|string\> given\.$#'
path: src/PersistentCollection.php
-
message: '#^Parameter \#5 \.\.\.\$args of static method Doctrine\\Deprecations\\Deprecation\:\:trigger\(\) expects float\|int\|string, string\|false given\.$#'
path: src/Mapping/ClassMetadataFactory.php
-
message: '#^Parameter \#1 \$classNames of method Doctrine\\ORM\\Mapping\\ClassMetadataInfo\<object\>\:\:setParentClasses\(\) expects list\<class\-string\>, array\<string\> given\.$#'
path: src/Mapping/ClassMetadataFactory.php

View File

@@ -9,7 +9,7 @@ parameters:
# Fallback logic for DBAL 2
-
message: '/Application::add\(\) expects Symfony\\Component\\Console\\Command\\Command/'
message: '/Parameter #2 \$command of static method Doctrine\\ORM\\Tools\\Console\\ConsoleRunner\:\:addCommandToApplication\(\) expects Symfony\\Component\\Console\\Command\\Command/'
path: src/Tools/Console/ConsoleRunner.php
- '/^Class Doctrine\\DBAL\\Platforms\\SQLAnywherePlatform not found\.$/'

File diff suppressed because it is too large Load Diff

311
psalm.xml
View File

@@ -1,311 +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">
<!-- DBAL 2 compatibility -->
<referencedClass name="Doctrine\DBAL\Tools\Console\Command\ImportCommand"/>
<referencedClass name="Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper"/>
<!-- The exception is thrown by a deprecated method. -->
<referencedClass name="Doctrine\ORM\Cache\Exception\InvalidResultCacheDriver"/>
<!-- 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\Common\Persistence\PersistentObject"/>
<referencedClass name="Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets"/>
<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>
<DeprecatedConstant>
<errorLevel type="suppress">
<file name="src/Configuration.php"/>
<file name="src/Query/Lexer.php"/>
<file name="src/Query/Parser.php"/>
<file name="src/QueryBuilder.php"/>
<file name="src/Tools/EntityGenerator.php"/>
<file name="src/Mapping/ClassMetadataInfo.php" />
<file name="src/Tools/EntityGenerator.php" />
<file name="src/Tools/Export/Driver/AbstractExporter.php" />
<file name="src/Tools/SchemaTool.php" />
</errorLevel>
</DeprecatedConstant>
<DeprecatedInterface>
<errorLevel type="suppress">
<!-- Remove on 3.0.x -->
<referencedClass name="Doctrine\ORM\Cache\MultiGetRegion"/>
<referencedClass name="Doctrine\ORM\Mapping\Annotation"/>
</errorLevel>
</DeprecatedInterface>
<DeprecatedMethod>
<errorLevel type="suppress">
<!-- We're calling the deprecated method for BC here. -->
<file name="src/Internal/SQLResultCasing.php"/>
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::getIdentitySequenceName"/>
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::usesSequenceEmulatedIdentityColumns"/>
<!-- We need to keep the calls for DBAL 2.13 compatibility. -->
<referencedMethod name="Doctrine\DBAL\Cache\QueryCacheProfile::getResultCacheDriver"/>
<referencedMethod name="Doctrine\DBAL\Cache\QueryCacheProfile::setResultCacheDriver"/>
<referencedMethod name="Doctrine\DBAL\Configuration::getResultCacheImpl"/>
<referencedMethod name="Doctrine\DBAL\Configuration::setResultCacheImpl"/>
<referencedMethod name="Doctrine\DBAL\Connection::getSchemaManager"/>
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::getGuidExpression"/>
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::supportsForeignKeyConstraints"/>
<!-- Remove on 3.0.x -->
<referencedMethod name="Doctrine\DBAL\Connection::getEventManager"/>
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::getReadLockSQL"/>
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::getWriteLockSQL"/>
<referencedMethod name="Doctrine\DBAL\Schema\Schema::visit"/>
<referencedMethod name="Doctrine\DBAL\Schema\SchemaDiff::toSaveSql"/>
<referencedMethod name="Doctrine\DBAL\Schema\SchemaDiff::toSql"/>
<referencedMethod name="Doctrine\ORM\Internal\Hydration\AbstractHydrator::hydrateRow"/>
<referencedMethod name="Doctrine\ORM\Configuration::ensureProductionSettings"/>
<referencedMethod name="Doctrine\ORM\Configuration::newDefaultAnnotationDriver"/>
<referencedMethod name="Doctrine\ORM\EntityManager::createConnection"/>
<referencedMethod name="Doctrine\ORM\EntityManagerInterface::getPartialReference"/>
<referencedMethod name="Doctrine\ORM\Id\AbstractIdGenerator::generate"/>
<referencedMethod name="Doctrine\ORM\ORMInvalidArgumentException::invalidEntityName"/>
<referencedMethod name="Doctrine\ORM\ORMSetup::createDefaultAnnotationDriver"/>
<referencedMethod name="Doctrine\ORM\Query\SqlWalker::walkInExpression"/>
<referencedMethod name="Doctrine\ORM\Query\TreeWalkerAdapter::_getQueryComponents"/>
<referencedMethod name="Doctrine\ORM\Mapping\ClassMetadataInfo::isInheritanceTypeTablePerClass"/>
<file name="src/Query/TreeWalkerChain.php"/>
</errorLevel>
</DeprecatedMethod>
<DeprecatedProperty>
<errorLevel type="suppress">
<referencedProperty name="Doctrine\ORM\Cache\Region\DefaultRegion::$cache"/>
<referencedProperty name="Doctrine\ORM\Mapping\Driver\AttributeDriver::$entityAnnotationClasses"/>
</errorLevel>
</DeprecatedProperty>
<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"/>
</errorLevel>
</DocblockTypeContradiction>
<DuplicateClass>
<errorLevel type="suppress">
<file name="src/Tools/Console/CommandCompatibility.php"/>
<file name="src/Tools/Console/Helper/EntityManagerHelper.php"/>
</errorLevel>
</DuplicateClass>
<ForbiddenCode>
<errorLevel type="suppress">
<file name="src/Tools/Debug.php"/>
</errorLevel>
</ForbiddenCode>
<InvalidArgument>
<errorLevel type="suppress">
<!-- Argument type changes in DBAL 3.2 -->
<referencedFunction name="Doctrine\DBAL\Cache\QueryCacheProfile::__construct"/>
<!-- https://github.com/vimeo/psalm/issues/9155 -->
<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>
<InvalidClass>
<errorLevel type="suppress">
<!-- Class name changes in DBAL 3. -->
<referencedClass name="Doctrine\DBAL\Platforms\PostgreSQLPlatform" />
<referencedClass name="Doctrine\DBAL\Platforms\MySQLPlatform" />
</errorLevel>
</InvalidClass>
<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>
<MissingDependency>
<errorLevel type="suppress">
<!-- DBAL 3.2 forward compatibility -->
<file name="src/Internal/SQLResultCasing.php"/>
<file name="src/Mapping/ClassMetadataFactory.php"/>
<file name="src/Tools/Pagination/LimitSubqueryOutputWalker.php"/>
</errorLevel>
</MissingDependency>
<MissingParamType>
<errorLevel type="suppress">
<!-- Persistence 2 compatibility -->
<file name="src/EntityManager.php"/>
<file name="src/Mapping/ClassMetadataFactory.php"/>
<file name="src/Mapping/ClassMetadataInfo.php"/>
</errorLevel>
</MissingParamType>
<NonInvariantDocblockPropertyType>
<errorLevel type="suppress">
<!-- Remove on 3.0.x -->
<file name="src/Query/AST/InListExpression.php"/>
<file name="src/Query/AST/InSubselectExpression.php"/>
</errorLevel>
</NonInvariantDocblockPropertyType>
<PossiblyInvalidArgument>
<errorLevel type="suppress">
<!-- https://github.com/vimeo/psalm/issues/9155 -->
<file name="src/Mapping/ClassMetadataFactory.php"/>
</errorLevel>
</PossiblyInvalidArgument>
<PropertyNotSetInConstructor>
<errorLevel type="suppress">
<!-- Remove on 3.0.x -->
<referencedProperty name="Doctrine\ORM\Cache\CacheKey::$hash"/>
</errorLevel>
<errorLevel type="suppress">
<directory name="src/Query/AST" />
</errorLevel>
</PropertyNotSetInConstructor>
<PropertyTypeCoercion>
<errorLevel type="suppress">
<file name="src/Mapping/ClassMetadataInfo.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>
<RedundantCondition>
<errorLevel type="suppress">
<!-- The SQLAnywherePlatform class may or may not exist depending on the DBAL version -->
<file name="src/Mapping/ClassMetadataFactory.php"/>
</errorLevel>
</RedundantCondition>
<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"/>
<!-- Remove on 3.0.x -->
<referencedFunction name="Doctrine\Persistence\ObjectManager::refresh"/>
</errorLevel>
</TooManyArguments>
<TypeDoesNotContainType>
<errorLevel type="suppress">
<file name="src/Internal/SQLResultCasing.php"/>
<file name="src/Mapping/ClassMetadataFactory.php"/>
<file name="src/Utility/LockSqlHelper.php"/>
</errorLevel>
</TypeDoesNotContainType>
<UndefinedClass>
<errorLevel type="suppress">
<referencedClass name="Doctrine\Common\Cache\ApcCache"/>
<referencedClass name="Doctrine\Common\Cache\ArrayCache"/>
<referencedClass name="Doctrine\Common\Cache\XcacheCache"/>
<!-- DBAL 2 compatibility -->
<referencedClass name="Doctrine\DBAL\Driver\ResultStatement"/>
<referencedClass name="Doctrine\DBAL\ForwardCompatibility\Result"/>
<referencedClass name="Doctrine\DBAL\Platforms\SQLAnywherePlatform"/>
<!-- DBAL 3.2 forward compatibility -->
<referencedClass name="Doctrine\DBAL\Platforms\PostgreSQLPlatform"/>
<referencedClass name="Doctrine\DBAL\Platforms\SQLServerPlatform"/>
<!-- Persistence 2 compatibility -->
<referencedClass name="Doctrine\Persistence\ObjectManagerAware"/>
<!-- Annotations 1 compatibility -->
<referencedClass name="Doctrine\Common\Annotations\CachedReader"/>
</errorLevel>
</UndefinedClass>
<UndefinedDocblockClass>
<errorLevel type="suppress">
<!-- DBAL 2 compatibility -->
<referencedClass name="Doctrine\DBAL\Driver\ResultStatement"/>
</errorLevel>
</UndefinedDocblockClass>
<UndefinedMethod>
<errorLevel type="suppress">
<!-- See https://github.com/doctrine/orm/issues/8884 -->
<referencedMethod name="Doctrine\DBAL\Platforms\AbstractPlatform::getGuidExpression"/>
</errorLevel>
</UndefinedMethod>
<MissingClosureReturnType>
<errorLevel type="suppress">
<file name="src/Tools/Pagination/Paginator.php"/>
</errorLevel>
</MissingClosureReturnType>
</issueHandlers>
</psalm>

View File

@@ -90,7 +90,7 @@ abstract class AbstractQuery
* The parameter map of this query.
*
* @var ArrayCollection|Parameter[]
* @psalm-var ArrayCollection<int, Parameter>
* @phpstan-var ArrayCollection<int, Parameter>
*/
protected $parameters;
@@ -111,7 +111,7 @@ abstract class AbstractQuery
/**
* The map of query hints.
*
* @psalm-var array<string, mixed>
* @phpstan-var array<string, mixed>
*/
protected $_hints = [];
@@ -119,7 +119,7 @@ abstract class AbstractQuery
* The hydration mode.
*
* @var string|int
* @psalm-var string|AbstractQuery::HYDRATE_*
* @phpstan-var string|AbstractQuery::HYDRATE_*
*/
protected $_hydrationMode = self::HYDRATE_OBJECT;
@@ -157,7 +157,7 @@ abstract class AbstractQuery
* Second level query cache mode.
*
* @var int|null
* @psalm-var Cache::MODE_*|null
* @phpstan-var Cache::MODE_*|null
*/
protected $cacheMode;
@@ -254,7 +254,7 @@ abstract class AbstractQuery
/**
* @return int|null
* @psalm-return Cache::MODE_*|null
* @phpstan-return Cache::MODE_*|null
*/
public function getCacheMode()
{
@@ -263,7 +263,7 @@ abstract class AbstractQuery
/**
* @param int $cacheMode
* @psalm-param Cache::MODE_* $cacheMode
* @phpstan-param Cache::MODE_* $cacheMode
*
* @return $this
*/
@@ -311,7 +311,7 @@ abstract class AbstractQuery
* Get all defined parameters.
*
* @return ArrayCollection The defined query parameters.
* @psalm-return ArrayCollection<int, Parameter>
* @phpstan-return ArrayCollection<int, Parameter>
*/
public function getParameters()
{
@@ -344,14 +344,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($parameters)
{
if (is_array($parameters)) {
/** @psalm-var ArrayCollection<int, Parameter> $parameterCollection */
/** @phpstan-var ArrayCollection<int, Parameter> $parameterCollection */
$parameterCollection = new ArrayCollection();
foreach ($parameters as $key => $value) {
@@ -844,7 +844,7 @@ abstract class AbstractQuery
* @param class-string $class
* @param string $assocName
* @param int $fetchMode
* @psalm-param Mapping\ClassMetadata::FETCH_EAGER|Mapping\ClassMetadata::FETCH_LAZY $fetchMode
* @phpstan-param Mapping\ClassMetadata::FETCH_EAGER|Mapping\ClassMetadata::FETCH_LAZY $fetchMode
*
* @return $this
*/
@@ -870,7 +870,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
*/
@@ -885,7 +885,7 @@ abstract class AbstractQuery
* Gets the hydration mode currently used by the query.
*
* @return string|int
* @psalm-return string|AbstractQuery::HYDRATE_*
* @phpstan-return string|AbstractQuery::HYDRATE_*
*/
public function getHydrationMode()
{
@@ -898,7 +898,7 @@ abstract class AbstractQuery
* Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
*
* @param string|int $hydrationMode
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_* $hydrationMode
*
* @return mixed
*/
@@ -947,7 +947,7 @@ abstract class AbstractQuery
* Get exactly one result or null.
*
* @param string|int|null $hydrationMode
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*
* @return mixed
*
@@ -985,7 +985,7 @@ abstract class AbstractQuery
* If there is no result, a NoResultException is thrown.
*
* @param string|int|null $hydrationMode
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
*
* @return mixed
*
@@ -1083,8 +1083,8 @@ abstract class AbstractQuery
*
* @param ArrayCollection|mixed[]|null $parameters The query parameters.
* @param string|int|null $hydrationMode The hydration mode to use.
* @psalm-param ArrayCollection<int, Parameter>|array<string, mixed>|null $parameters
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode The hydration mode to use.
* @phpstan-param ArrayCollection<int, Parameter>|array<string, mixed>|null $parameters
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode The hydration mode to use.
*
* @return IterableResult
*/
@@ -1121,8 +1121,8 @@ abstract class AbstractQuery
*
* @param ArrayCollection|array|mixed[] $parameters The query parameters.
* @param string|int|null $hydrationMode The hydration mode to use.
* @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>
*/
@@ -1158,8 +1158,8 @@ abstract class AbstractQuery
*
* @param ArrayCollection|mixed[]|null $parameters Query parameters.
* @param string|int|null $hydrationMode Processing mode to be used during the hydration process.
* @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
*
* @return mixed
*/
@@ -1177,8 +1177,8 @@ abstract class AbstractQuery
*
* @param ArrayCollection|mixed[]|null $parameters
* @param string|int|null $hydrationMode
* @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
*
* @return mixed
*/
@@ -1259,8 +1259,8 @@ abstract class AbstractQuery
*
* @param ArrayCollection|mixed[]|null $parameters
* @param string|int|null $hydrationMode
* @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
*
* @return mixed
*/
@@ -1323,7 +1323,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()
{

View File

@@ -15,7 +15,7 @@ use Doctrine\ORM\Persisters\Entity\EntityPersister;
/**
* Contract for building second level cache regions components.
*
* @psalm-import-type AssociationMapping from ClassMetadata
* @phpstan-import-type AssociationMapping from ClassMetadata
*/
interface CacheFactory
{

View File

@@ -43,7 +43,7 @@ class CollectionCacheKey extends CacheKey
* @param string $association The field name that represents the association.
* @param array<string, mixed> $ownerIdentifier The identifier of the owning entity.
*/
public function __construct($entityClass, $association, array $ownerIdentifier)
public function __construct($entityClass, $association, array $ownerIdentifier, string $filterHash = '')
{
ksort($ownerIdentifier);
@@ -51,6 +51,8 @@ class CollectionCacheKey extends CacheKey
$this->entityClass = (string) $entityClass;
$this->association = (string) $association;
parent::__construct(str_replace('\\', '.', strtolower($entityClass)) . '_' . implode(' ', $ownerIdentifier) . '__' . $association);
$filterHash = $filterHash === '' ? '' : '_' . $filterHash;
parent::__construct(str_replace('\\', '.', strtolower($entityClass)) . '_' . implode(' ', $ownerIdentifier) . '__' . $association . $filterHash);
}
}

View File

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

View File

@@ -29,7 +29,7 @@ use function reset;
/**
* Default query cache implementation.
*
* @psalm-import-type AssociationMapping from ClassMetadata
* @phpstan-import-type AssociationMapping from ClassMetadata
*/
class DefaultQueryCache implements QueryCache
{
@@ -262,7 +262,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);
@@ -331,7 +330,7 @@ class DefaultQueryCache implements QueryCache
* @param mixed $assocValue
*
* @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, array $assoc, $assocValue): ?array
{
@@ -386,7 +385,7 @@ class DefaultQueryCache implements QueryCache
* @param object $entity
*
* @return mixed[]|object|null
* @psalm-return list<mixed>|object|null
* @phpstan-return list<mixed>|object|null
*/
private function getAssociationValue(
ResultSetMapping $rsm,
@@ -414,10 +413,10 @@ class DefaultQueryCache implements QueryCache
/**
* @param mixed $value
* @psalm-param array<array-key, array{field: string, class: string}> $path
* @phpstan-param array<array-key, array{field: string, class: string}> $path
*
* @return mixed[]|object|null
* @psalm-return list<mixed>|object|null
* @phpstan-return list<mixed>|object|null
*/
private function getAssociationPathValue($value, array $path)
{

View File

@@ -19,13 +19,14 @@ 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;
use function assert;
use function count;
/** @psalm-import-type AssociationMapping from ClassMetadata */
/** @phpstan-import-type AssociationMapping from ClassMetadata */
abstract class AbstractCollectionPersister implements CachedCollectionPersister
{
/** @var UnitOfWork */
@@ -55,6 +56,9 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
/** @var string */
protected $regionName;
/** @var FilterCollection */
protected $filters;
/** @var CollectionHydrator */
protected $hydrator;
@@ -76,6 +80,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
$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();
@@ -189,7 +194,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
public function count(PersistentCollection $collection)
{
$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) {
@@ -241,7 +246,8 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
$key = new CollectionCacheKey(
$this->sourceEntity->rootEntityName,
$this->association['fieldName'],
$this->uow->getEntityIdentifier($collection->getOwner())
$this->uow->getEntityIdentifier($collection->getOwner()),
$this->filters->getHash()
);
$this->region->evict($key);

View File

@@ -45,7 +45,7 @@ class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPers
public function delete(PersistentCollection $collection)
{
$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);
@@ -65,7 +65,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 || isset($this->association['orderBy'])) {

View File

@@ -13,7 +13,7 @@ use Doctrine\ORM\Persisters\Collection\CollectionPersister;
use function spl_object_id;
/** @psalm-import-type AssociationMapping from ClassMetadata */
/** @phpstan-import-type AssociationMapping from ClassMetadata */
class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
{
/** @param AssociationMapping $association The association mapping. */
@@ -68,7 +68,7 @@ class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
public function delete(PersistentCollection $collection)
{
$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());
$lock = $this->region->lock($key);
$this->persister->delete($collection);
@@ -98,7 +98,7 @@ class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
$this->persister->update($collection);
$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());
$lock = $this->region->lock($key);
if ($lock === null) {

View File

@@ -22,10 +22,11 @@ use Doctrine\ORM\Mapping\ClassMetadataFactory;
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Persisters\Entity\EntityPersister;
use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
use Doctrine\ORM\Query\FilterCollection;
use Doctrine\ORM\UnitOfWork;
use function array_merge;
use function assert;
use function func_get_args;
use function serialize;
use function sha1;
@@ -63,6 +64,9 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
/** @var Cache */
protected $cache;
/** @var FilterCollection */
protected $filters;
/** @var CacheLogger|null */
protected $cacheLogger;
@@ -92,6 +96,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
$this->region = $region;
$this->persister = $persister;
$this->cache = $em->getCache();
$this->filters = $em->getFilters();
$this->regionName = $region->getName();
$this->uow = $em->getUnitOfWork();
$this->metadataFactory = $em->getMetadataFactory();
@@ -262,7 +267,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
? $this->persister->expandCriteriaParameters($criteria)
: $this->persister->expandParameters($criteria);
return sha1($query . serialize($params) . serialize($orderBy) . $limit . $offset);
return sha1($query . serialize($params) . serialize($orderBy) . $limit . $offset . $this->filters->getHash());
}
/**
@@ -525,7 +530,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
}
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
$key = $this->buildCollectionCacheKey($assoc, $ownerId);
$key = $this->buildCollectionCacheKey($assoc, $ownerId, $this->filters->getHash());
$list = $persister->loadCollectionCache($collection, $key);
if ($list !== null) {
@@ -560,7 +565,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
}
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
$key = $this->buildCollectionCacheKey($assoc, $ownerId);
$key = $this->buildCollectionCacheKey($assoc, $ownerId, $this->filters->getHash());
$list = $persister->loadCollectionCache($collection, $key);
if ($list !== null) {
@@ -612,11 +617,15 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
*
* @return CollectionCacheKey
*/
protected function buildCollectionCacheKey(array $association, $ownerId)
protected function buildCollectionCacheKey(array $association, $ownerId/*, string $filterHash */)
{
$metadata = $this->metadataFactory->getMetadataFor($association['sourceEntity']);
assert($metadata instanceof ClassMetadata);
$filterHash = (string) (func_get_args()[2] ?? ''); // todo: move to argument in next major release
return new CollectionCacheKey($metadata->rootEntityName, $association['fieldName'], $ownerId);
return new CollectionCacheKey(
$this->metadataFactory->getMetadataFor($association['sourceEntity'])->rootEntityName,
$association['fieldName'],
$ownerId,
$filterHash
);
}
}

View File

@@ -24,7 +24,7 @@ class QueryCacheKey extends CacheKey
*
* @readonly Public only for performance reasons, it should be considered immutable.
* @var int
* @psalm-var Cache::MODE_*
* @phpstan-var Cache::MODE_*
*/
public $cacheMode;
@@ -34,7 +34,7 @@ class QueryCacheKey extends CacheKey
*/
public $timestampKey;
/** @psalm-param Cache::MODE_* $cacheMode */
/** @phpstan-param Cache::MODE_* $cacheMode */
public function __construct(
string $cacheId,
int $lifetime = 0,

View File

@@ -43,7 +43,7 @@ class FileLockRegion implements ConcurrentRegion
/** @var string */
private $directory;
/** @psalm-var numeric-string */
/** @phpstan-var numeric-string */
private $lockLifetime;
/**

View File

@@ -70,16 +70,16 @@ class Configuration extends \Doctrine\DBAL\Configuration
/** @var mixed[] */
protected $_attributes = [];
/** @psalm-var array<class-string<AbstractPlatform>, ClassMetadata::GENERATOR_TYPE_*> */
/** @phpstan-var array<class-string<AbstractPlatform>, ClassMetadata::GENERATOR_TYPE_*> */
private $identityGenerationPreferences = [];
/** @psalm-param array<class-string<AbstractPlatform>, ClassMetadata::GENERATOR_TYPE_*> $value */
/** @phpstan-param array<class-string<AbstractPlatform>, ClassMetadata::GENERATOR_TYPE_*> $value */
public function setIdentityGenerationPreferences(array $value): void
{
$this->identityGenerationPreferences = $value;
}
/** @psalm-return array<class-string<AbstractPlatform>, ClassMetadata::GENERATOR_TYPE_*> $value */
/** @phpstan-return array<class-string<AbstractPlatform>, ClassMetadata::GENERATOR_TYPE_*> $value */
public function getIdentityGenerationPreferences(): array
{
return $this->identityGenerationPreferences;
@@ -172,7 +172,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string|string[] $paths
* @param bool $useSimpleAnnotationReader
* @psalm-param string|list<string> $paths
* @phpstan-param string|list<string> $paths
*
* @return AnnotationDriver
*/
@@ -279,7 +279,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets the entity alias map.
*
* @psalm-param array<string, string> $entityNamespaces
* @phpstan-param array<string, string> $entityNamespaces
*
* @return void
*/
@@ -291,7 +291,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Retrieves the list of registered entity namespace aliases.
*
* @psalm-return array<string, string>
* @phpstan-return array<string, string>
*/
public function getEntityNamespaces()
{
@@ -551,7 +551,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* @param string $name The name of the query.
*
* @return mixed[]
* @psalm-return array{string, ResultSetMapping} A tuple with the first element being the SQL string and the second
* @phpstan-return array{string, ResultSetMapping} A tuple with the first element being the SQL string and the second
* element being the ResultSetMapping.
*
* @throws NamedNativeQueryNotFound
@@ -620,7 +620,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name Function name.
* @param class-string|callable $className Class name or a callable that returns the function.
* @psalm-param class-string<FunctionNode>|callable(string):FunctionNode $className
* @phpstan-param class-string<FunctionNode>|callable(string):FunctionNode $className
*
* @return void
*/
@@ -635,7 +635,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* @param string $name
*
* @return string|callable|null
* @psalm-return class-string<FunctionNode>|callable(string):FunctionNode|null
* @phpstan-return class-string<FunctionNode>|callable(string):FunctionNode|null
*/
public function getCustomStringFunction($name)
{
@@ -652,7 +652,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* Any previously added string functions are discarded.
*
* @psalm-param array<string, class-string<FunctionNode>|callable(string):FunctionNode> $functions The map of custom
* @phpstan-param array<string, class-string<FunctionNode>|callable(string):FunctionNode> $functions The map of custom
* DQL string functions.
*
* @return void
@@ -673,7 +673,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name Function name.
* @param class-string|callable $className Class name or a callable that returns the function.
* @psalm-param class-string<FunctionNode>|callable(string):FunctionNode $className
* @phpstan-param class-string<FunctionNode>|callable(string):FunctionNode $className
*
* @return void
*/
@@ -725,7 +725,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
*
* @param string $name Function name.
* @param string|callable $className Class name or a callable that returns the function.
* @psalm-param class-string<FunctionNode>|callable(string):FunctionNode $className
* @phpstan-param class-string<FunctionNode>|callable(string):FunctionNode $className
*
* @return void
*/
@@ -757,7 +757,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
* Any previously added date/time functions are discarded.
*
* @param array $functions The map of custom DQL date/time functions.
* @psalm-param array<string, class-string<FunctionNode>|callable(string):FunctionNode> $functions
* @phpstan-param array<string, class-string<FunctionNode>|callable(string):FunctionNode> $functions
*
* @return void
*/
@@ -1038,7 +1038,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Returns query hints, which will be applied to every query in application
*
* @psalm-return array<string, mixed>
* @phpstan-return array<string, mixed>
*/
public function getDefaultQueryHints()
{
@@ -1048,7 +1048,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
/**
* Sets array of query hints, which will be applied to every query in application
*
* @psalm-param array<string, mixed> $defaultQueryHints
* @phpstan-param array<string, mixed> $defaultQueryHints
*
* @return void
*/
@@ -1109,6 +1109,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
public function setLazyGhostObjectEnabled(bool $flag): void
{
// @phpstan-ignore classConstant.deprecatedTrait (Because we support Symfony < 7.3)
if ($flag && ! trait_exists(LazyGhostTrait::class)) {
throw new LogicException(
'Lazy ghost objects cannot be enabled because the "symfony/var-exporter" library'

View File

@@ -52,7 +52,7 @@ abstract class EntityManagerDecorator extends ObjectManagerDecorator implements
*
* @param class-string<T> $className
*
* @psalm-return EntityRepository<T>
* @phpstan-return EntityRepository<T>
*
* @template T of object
*/

View File

@@ -424,7 +424,7 @@ class EntityManager implements EntityManagerInterface
* during the search.
* @param int|null $lockVersion The version of the entity to find when using
* optimistic locking.
* @psalm-param LockMode::*|null $lockMode
* @phpstan-param LockMode::*|null $lockMode
*
* @return T|null The entity instance or NULL if the entity can not be found.
*
@@ -710,7 +710,7 @@ class EntityManager implements EntityManagerInterface
* overriding any local changes that have not yet been persisted.
*
* @param object $entity The entity to refresh
* @psalm-param LockMode::*|null $lockMode
* @phpstan-param LockMode::*|null $lockMode
*
* @return void
*
@@ -786,7 +786,7 @@ class EntityManager implements EntityManagerInterface
/**
* {@inheritDoc}
*
* @psalm-return never
* @phpstan-return never
*/
public function copy($entity, $deep = false)
{
@@ -983,7 +983,7 @@ class EntityManager implements EntityManagerInterface
* @param mixed[]|Connection $connection An array with the connection parameters or an existing Connection instance.
* @param Configuration $config The Configuration instance to use.
* @param EventManager|null $eventManager The EventManager instance to use.
* @psalm-param array<string, mixed>|Connection $connection
* @phpstan-param array<string, mixed>|Connection $connection
*
* @return EntityManager The created EntityManager.
*
@@ -1014,7 +1014,7 @@ class EntityManager implements EntityManagerInterface
* @param mixed[]|Connection $connection An array with the connection parameters or an existing Connection instance.
* @param Configuration $config The Configuration instance to use.
* @param EventManager|null $eventManager The EventManager instance to use.
* @psalm-param array<string, mixed>|Connection $connection
* @phpstan-param array<string, mixed>|Connection $connection
*
* @return Connection
*
@@ -1081,7 +1081,7 @@ class EntityManager implements EntityManagerInterface
}
/**
* @psalm-param LockMode::* $lockMode
* @phpstan-param LockMode::* $lockMode
*
* @throws OptimisticLockException
* @throws TransactionRequiredException

View File

@@ -238,7 +238,7 @@ interface EntityManagerInterface extends ObjectManager
* @param object $entity
* @param int $lockMode
* @param int|DateTimeInterface|null $lockVersion
* @psalm-param LockMode::* $lockMode
* @phpstan-param LockMode::* $lockMode
*
* @return void
*
@@ -284,7 +284,7 @@ interface EntityManagerInterface extends ObjectManager
* @deprecated
*
* @param string|int $hydrationMode
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_* $hydrationMode
*
* @return AbstractHydrator
*/
@@ -294,7 +294,7 @@ interface EntityManagerInterface extends ObjectManager
* Create a new instance for the given hydration mode.
*
* @param string|int $hydrationMode
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
* @phpstan-param string|AbstractQuery::HYDRATE_* $hydrationMode
*
* @return AbstractHydrator
*
@@ -336,9 +336,9 @@ interface EntityManagerInterface extends ObjectManager
* @param string|class-string<T> $className
*
* @return Mapping\ClassMetadata
* @psalm-return ($className is class-string<T> ? Mapping\ClassMetadata<T> : Mapping\ClassMetadata<object>)
* @phpstan-return ($className is class-string<T> ? Mapping\ClassMetadata<T> : Mapping\ClassMetadata<object>)
*
* @psalm-template T of object
* @phpstan-template T of object
*/
public function getClassMetadata($className);
}

View File

@@ -57,14 +57,14 @@ class EntityRepository implements ObjectRepository, Selectable
* @internal This property will be private in 3.0, call {@see getClassMetadata()} instead.
*
* @var ClassMetadata
* @psalm-var ClassMetadata<T>
* @phpstan-var ClassMetadata<T>
*/
protected $_class;
/** @var Inflector|null */
private static $inflector;
/** @psalm-param ClassMetadata<T> $class */
/** @phpstan-param ClassMetadata<T> $class */
public function __construct(EntityManagerInterface $em, ClassMetadata $class)
{
$this->_entityName = $class->name;
@@ -186,10 +186,10 @@ class EntityRepository implements ObjectRepository, Selectable
* or NULL if no specific lock mode should be used
* during the search.
* @param int|null $lockVersion The lock version.
* @psalm-param LockMode::*|null $lockMode
* @phpstan-param LockMode::*|null $lockMode
*
* @return object|null The entity instance or NULL if the entity can not be found.
* @psalm-return ?T
* @phpstan-return ?T
*/
public function find($id, $lockMode = null, $lockVersion = null)
{
@@ -199,7 +199,7 @@ class EntityRepository implements ObjectRepository, Selectable
/**
* Finds all entities in the repository.
*
* @psalm-return list<T> The entities.
* @phpstan-return list<T> The entities.
*/
public function findAll()
{
@@ -211,11 +211,11 @@ class EntityRepository implements ObjectRepository, Selectable
*
* @param int|null $limit
* @param int|null $offset
* @psalm-param array<string, mixed> $criteria
* @psalm-param array<string, string>|null $orderBy
* @phpstan-param array<string, mixed> $criteria
* @phpstan-param array<string, string>|null $orderBy
*
* @return object[] The objects.
* @psalm-return list<T>
* @phpstan-return list<T>
*/
public function findBy(array $criteria, ?array $orderBy = null, $limit = null, $offset = null)
{
@@ -227,11 +227,11 @@ class EntityRepository implements ObjectRepository, Selectable
/**
* Finds a single entity by a set of criteria.
*
* @psalm-param array<string, mixed> $criteria
* @psalm-param array<string, string>|null $orderBy
* @phpstan-param array<string, mixed> $criteria
* @phpstan-param array<string, string>|null $orderBy
*
* @return object|null The entity instance or NULL if the entity can not be found.
* @psalm-return ?T
* @phpstan-return ?T
*/
public function findOneBy(array $criteria, ?array $orderBy = null)
{
@@ -243,7 +243,7 @@ class EntityRepository implements ObjectRepository, Selectable
/**
* Counts entities by a set of criteria.
*
* @psalm-param array<string, mixed> $criteria
* @phpstan-param array<string, mixed> $criteria
*
* @return int The cardinality of the objects that match the given criteria.
*
@@ -259,7 +259,7 @@ class EntityRepository implements ObjectRepository, Selectable
*
* @param string $method
* @param mixed[] $arguments
* @psalm-param list<mixed> $arguments
* @phpstan-param list<mixed> $arguments
*
* @return mixed The returned value from the resolved method.
*
@@ -308,7 +308,7 @@ class EntityRepository implements ObjectRepository, Selectable
/**
* @return ClassMetadata
* @psalm-return ClassMetadata<T>
* @phpstan-return ClassMetadata<T>
*/
protected function getClassMetadata()
{
@@ -320,7 +320,7 @@ class EntityRepository implements ObjectRepository, Selectable
* return a new collection containing these elements.
*
* @return AbstractLazyCollection
* @psalm-return AbstractLazyCollection<int, T>&Selectable<int, T>
* @phpstan-return AbstractLazyCollection<int, T>&Selectable<int, T>
*/
public function matching(Criteria $criteria)
{
@@ -334,7 +334,7 @@ class EntityRepository implements ObjectRepository, Selectable
*
* @param string $method The method to call
* @param string $by The property name used as condition
* @psalm-param list<mixed> $arguments The arguments to pass at method call
* @phpstan-param list<mixed> $arguments The arguments to pass at method call
*
* @return mixed
*

View File

@@ -43,7 +43,7 @@ class ListenersInvoker
* @param string $eventName The entity lifecycle event.
*
* @return int Bitmask of subscribed event systems.
* @psalm-return int-mask-of<self::INVOKE_*>
* @phpstan-return int-mask-of<self::INVOKE_*>
*/
public function getSubscribedSystems(ClassMetadata $metadata, $eventName)
{
@@ -72,7 +72,7 @@ class ListenersInvoker
* @param object $entity The Entity on which the event occurred.
* @param EventArgs $event The Event args.
* @param int $invoke Bitmask to invoke listeners.
* @psalm-param int-mask-of<self::INVOKE_*> $invoke
* @phpstan-param int-mask-of<self::INVOKE_*> $invoke
*
* @return void
*/

View File

@@ -24,7 +24,7 @@ class PreUpdateEventArgs extends LifecycleEventArgs
/**
* @param object $entity
* @param mixed[][] $changeSet
* @psalm-param array<string, array{mixed, mixed}|PersistentCollection> $changeSet
* @phpstan-param array<string, array{mixed, mixed}|PersistentCollection> $changeSet
*/
public function __construct($entity, EntityManagerInterface $em, array &$changeSet)
{
@@ -38,7 +38,7 @@ class PreUpdateEventArgs extends LifecycleEventArgs
* Retrieves entity changeset.
*
* @return mixed[][]
* @psalm-return array<string, array{mixed, mixed}|PersistentCollection>
* @phpstan-return array<string, array{mixed, mixed}|PersistentCollection>
*/
public function getEntityChangeSet()
{

View File

@@ -103,16 +103,14 @@ final class Events
* The onFlush event occurs when the EntityManager#flush() operation is invoked,
* after any changes to managed entities have been determined but before any
* actual database operations are executed. The event is only raised if there is
* actually something to do for the underlying UnitOfWork. If nothing needs to be done,
* the onFlush event is not raised.
* actually something to do for the underlying UnitOfWork.
*/
public const onFlush = 'onFlush';
/**
* The postFlush event occurs when the EntityManager#flush() operation is invoked and
* after all actual database operations are executed successfully. The event is only raised if there is
* actually something to do for the underlying UnitOfWork. If nothing needs to be done,
* the postFlush event is not raised. The event won't be raised if an error occurs during the
* actually something to do for the underlying UnitOfWork. The event won't be raised if an error occurs during the
* flush operation.
*/
public const postFlush = 'postFlush';

View File

@@ -14,11 +14,7 @@ use function strtoupper;
trait CriteriaOrderings
{
/**
* @return array<string, string>
*
* @psalm-suppress DeprecatedMethod We need to call the deprecated API if the new one does not exist yet.
*/
/** @return array<string, string> */
private static function getCriteriaOrderings(Criteria $criteria): array
{
if (! method_exists(Criteria::class, 'orderings')) {

View File

@@ -112,7 +112,7 @@ abstract class AbstractHydrator
*
* @param Result|ResultStatement $stmt
* @param ResultSetMapping $resultSetMapping
* @psalm-param array<string, mixed> $hints
* @phpstan-param array<string, mixed> $hints
*
* @return IterableResult
*/
@@ -142,7 +142,7 @@ abstract class AbstractHydrator
* Initiates a row-by-row hydration.
*
* @param Result|ResultStatement $stmt
* @psalm-param array<string, mixed> $hints
* @phpstan-param array<string, mixed> $hints
*
* @return Generator<array-key, mixed>
*
@@ -233,7 +233,7 @@ abstract class AbstractHydrator
*
* @param Result|ResultStatement $stmt
* @param ResultSetMapping $resultSetMapping
* @psalm-param array<string, string> $hints
* @phpstan-param array<string, string> $hints
*
* @return mixed[]
*/
@@ -390,14 +390,14 @@ abstract class AbstractHydrator
* the values applied. Scalar values are kept in a specific key 'scalars'.
*
* @param mixed[] $data SQL Result Row.
* @psalm-param array<string, string> $id Dql-Alias => ID-Hash.
* @psalm-param array<string, bool> $nonemptyComponents Does this DQL-Alias has at least one non NULL value?
* @phpstan-param array<string, string> $id Dql-Alias => ID-Hash.
* @phpstan-param array<string, bool> $nonemptyComponents Does this DQL-Alias has at least one non NULL value?
*
* @return array<string, array<string, mixed>> An array with all the fields
* (name => value) of the data
* row, grouped by their
* component alias.
* @psalm-return array{
* @phpstan-return array{
* data: array<array-key, array>,
* newObjects?: array<array-key, array{
* class: mixed,
@@ -495,10 +495,10 @@ abstract class AbstractHydrator
* of elements as before.
*
* @param mixed[] $data
* @psalm-param array<string, mixed> $data
* @phpstan-param array<string, mixed> $data
*
* @return mixed[] The processed row.
* @psalm-return array<string, mixed>
* @phpstan-return array<string, mixed>
*/
protected function gatherScalarRowData(&$data)
{
@@ -533,7 +533,7 @@ abstract class AbstractHydrator
* @param string $key Column name
*
* @return mixed[]|null
* @psalm-return array<string, mixed>|null
* @phpstan-return array<string, mixed>|null
*/
protected function hydrateColumnInfo($key)
{
@@ -630,7 +630,7 @@ abstract class AbstractHydrator
/**
* @return string[]
* @psalm-return non-empty-list<string>
* @phpstan-return non-empty-list<string>
*/
private function getDiscriminatorValues(ClassMetadata $classMetadata): array
{

View File

@@ -219,7 +219,7 @@ class ObjectHydrator extends AbstractHydrator
* Gets an entity instance.
*
* @param string $dqlAlias The DQL alias of the entity's class.
* @psalm-param array<string, mixed> $data The instance data.
* @phpstan-param array<string, mixed> $data The instance data.
*
* @return object
*
@@ -274,7 +274,7 @@ class ObjectHydrator extends AbstractHydrator
/**
* @param class-string $className
* @psalm-param array<string, mixed> $data
* @phpstan-param array<string, mixed> $data
*
* @return mixed
*/

View File

@@ -16,6 +16,7 @@ use function array_keys;
use function array_search;
use function count;
use function in_array;
use function is_array;
use function key;
use function reset;
use function sprintf;
@@ -143,14 +144,21 @@ class SimpleObjectHydrator extends AbstractHydrator
}
if ($value !== null && isset($cacheKeyInfo['enumType'])) {
$originalValue = $value;
$originalValue = $currentValue = $value;
try {
$value = $this->buildEnum($originalValue, $cacheKeyInfo['enumType']);
if (! is_array($originalValue)) {
$value = $this->buildEnum($originalValue, $cacheKeyInfo['enumType']);
} else {
$value = [];
foreach ($originalValue as $i => $currentValue) {
$value[$i] = $this->buildEnum($currentValue, $cacheKeyInfo['enumType']);
}
}
} catch (ValueError $e) {
throw MappingException::invalidEnumValue(
$entityName,
$cacheKeyInfo['fieldName'],
(string) $originalValue,
(string) $currentValue,
$cacheKeyInfo['enumType'],
$e
);

View File

@@ -57,7 +57,7 @@ final class AssociationOverride implements MappingAttribute
* The fetching strategy to use for the association.
*
* @var string|null
* @psalm-var 'LAZY'|'EAGER'|'EXTRA_LAZY'|null
* @phpstan-var 'LAZY'|'EAGER'|'EXTRA_LAZY'|null
* @readonly
* @Enum({"LAZY", "EAGER", "EXTRA_LAZY"})
*/
@@ -66,7 +66,7 @@ final class AssociationOverride implements MappingAttribute
/**
* @param JoinColumn|array<JoinColumn> $joinColumns
* @param JoinColumn|array<JoinColumn> $inverseJoinColumns
* @psalm-param 'LAZY'|'EAGER'|'EXTRA_LAZY'|null $fetch
* @phpstan-param 'LAZY'|'EAGER'|'EXTRA_LAZY'|null $fetch
*/
public function __construct(
string $name,

View File

@@ -135,7 +135,7 @@ class ClassMetadataBuilder
* Adds Index.
*
* @param string $name
* @psalm-param list<string> $columns
* @phpstan-param list<string> $columns
*
* @return $this
*/
@@ -154,7 +154,7 @@ class ClassMetadataBuilder
* Adds Unique Constraint.
*
* @param string $name
* @psalm-param list<string> $columns
* @phpstan-param list<string> $columns
*
* @return $this
*/
@@ -301,7 +301,7 @@ class ClassMetadataBuilder
*
* @param string $name
* @param string $type
* @psalm-param array<string, mixed> $mapping
* @phpstan-param array<string, mixed> $mapping
*
* @return $this
*/

View File

@@ -12,7 +12,7 @@ namespace Doctrine\ORM\Mapping\Builder;
class OneToManyAssociationBuilder extends AssociationBuilder
{
/**
* @psalm-param array<string, string> $fieldNames
* @phpstan-param array<string, string> $fieldNames
*
* @return $this
*/

View File

@@ -22,14 +22,14 @@ final class Cache implements MappingAttribute
*
* @Enum({"READ_ONLY", "NONSTRICT_READ_WRITE", "READ_WRITE"})
* @var string
* @psalm-var 'READ_ONLY'|'NONSTRICT_READ_WRITE'|'READ_WRITE'
* @phpstan-var 'READ_ONLY'|'NONSTRICT_READ_WRITE'|'READ_WRITE'
*/
public $usage = 'READ_ONLY';
/** @var string|null Cache region name. */
public $region;
/** @psalm-param 'READ_ONLY'|'NONSTRICT_READ_WRITE'|'READ_WRITE' $usage */
/** @phpstan-param 'READ_ONLY'|'NONSTRICT_READ_WRITE'|'READ_WRITE' $usage */
public function __construct(string $usage = 'READ_ONLY', ?string $region = null)
{
$this->usage = $usage;

View File

@@ -19,13 +19,13 @@ final class ChangeTrackingPolicy implements MappingAttribute
* The change tracking policy.
*
* @var string
* @psalm-var 'DEFERRED_IMPLICIT'|'DEFERRED_EXPLICIT'|'NOTIFY'
* @phpstan-var 'DEFERRED_IMPLICIT'|'DEFERRED_EXPLICIT'|'NOTIFY'
* @readonly
* @Enum({"DEFERRED_IMPLICIT", "DEFERRED_EXPLICIT", "NOTIFY"})
*/
public $value;
/** @psalm-param 'DEFERRED_IMPLICIT'|'DEFERRED_EXPLICIT'|'NOTIFY' $value */
/** @phpstan-param 'DEFERRED_IMPLICIT'|'DEFERRED_EXPLICIT'|'NOTIFY' $value */
public function __construct(string $value)
{
$this->value = $value;

View File

@@ -12,7 +12,7 @@ use BackedEnum;
* @todo remove or rename ClassMetadataInfo to ClassMetadata
* @template-covariant T of object
* @template-extends ClassMetadataInfo<T>
* @psalm-type FieldMapping = array{
* @phpstan-type FieldMapping = array{
* type: string,
* fieldName: string,
* columnName: string,
@@ -38,7 +38,7 @@ use BackedEnum;
* version?: string,
* default?: string|int,
* }
* @psalm-type JoinColumnData = array{
* @phpstan-type JoinColumnData = array{
* name: string,
* referencedColumnName: string,
* unique?: bool,
@@ -48,7 +48,7 @@ use BackedEnum;
* columnDefinition?: string,
* nullable?: bool,
* }
* @psalm-type AssociationMapping = array{
* @phpstan-type AssociationMapping = array{
* cache?: array,
* cascade: array<string>,
* declared?: class-string,
@@ -83,7 +83,7 @@ use BackedEnum;
* type: int,
* unique?: bool,
* }
* @psalm-type DiscriminatorColumnMapping = array{
* @phpstan-type DiscriminatorColumnMapping = array{
* name: string,
* fieldName: string,
* type: string,
@@ -92,7 +92,7 @@ use BackedEnum;
* enumType?: class-string<BackedEnum>|null,
* options?: array<string, mixed>,
* }
* @psalm-type EmbeddedClassMapping = array{
* @phpstan-type EmbeddedClassMapping = array{
* class: class-string,
* columnPrefix: string|null,
* declaredField: string|null,
@@ -109,7 +109,7 @@ class ClassMetadata extends ClassMetadataInfo
* @see https://github.com/doctrine/orm/issues/8709
*
* @param string $entityName The name of the entity class the new instance is used for.
* @psalm-param class-string<T> $entityName
* @phpstan-param class-string<T> $entityName
*/
public function __construct($entityName, ?NamingStrategy $namingStrategy = null, ?TypedFieldMapper $typedFieldMapper = null)
{

View File

@@ -52,9 +52,9 @@ use function substr;
* to a relational database.
*
* @extends AbstractClassMetadataFactory<ClassMetadata>
* @psalm-import-type AssociationMapping from ClassMetadata
* @psalm-import-type EmbeddedClassMapping from ClassMetadata
* @psalm-import-type FieldMapping from ClassMetadata
* @phpstan-import-type AssociationMapping from ClassMetadata
* @phpstan-import-type EmbeddedClassMapping from ClassMetadata
* @phpstan-import-type FieldMapping from ClassMetadata
*/
class ClassMetadataFactory extends AbstractClassMetadataFactory
{
@@ -639,7 +639,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
$platform = $this->getTargetPlatform();
// Platforms that do not have native IDENTITY support need a sequence to emulate this behaviour.
/** @psalm-suppress UndefinedClass, InvalidClass */ // @phpstan-ignore method.deprecated
// @phpstan-ignore method.deprecated
if (! $platform instanceof MySQLPlatform && ! $platform instanceof SqlitePlatform && ! $platform instanceof SQLServerPlatform && $platform->usesSequenceEmulatedIdentityColumns()) {
Deprecation::trigger(
'doctrine/orm',
@@ -744,7 +744,7 @@ DEPRECATION
}
}
/** @psalm-return ClassMetadata::GENERATOR_TYPE_* */
/** @phpstan-return ClassMetadata::GENERATOR_TYPE_* */
private function determineIdGeneratorStrategy(AbstractPlatform $platform): int
{
assert($this->em !== null);
@@ -830,7 +830,6 @@ DEPRECATION
*/
protected function wakeupReflection(ClassMetadataInterface $class, ReflectionService $reflService)
{
assert($class instanceof ClassMetadata);
$class->wakeupReflection($reflService);
}
@@ -839,7 +838,6 @@ DEPRECATION
*/
protected function initializeReflection(ClassMetadataInterface $class, ReflectionService $reflService)
{
assert($class instanceof ClassMetadata);
$class->initializeReflection($reflService);
}

View File

@@ -68,11 +68,11 @@ use const PHP_VERSION_ID;
*
* @template-covariant T of object
* @template-implements ClassMetadata<T>
* @psalm-import-type AssociationMapping from \Doctrine\ORM\Mapping\ClassMetadata
* @psalm-import-type FieldMapping from \Doctrine\ORM\Mapping\ClassMetadata
* @psalm-import-type EmbeddedClassMapping from \Doctrine\ORM\Mapping\ClassMetadata
* @psalm-import-type JoinColumnData from \Doctrine\ORM\Mapping\ClassMetadata
* @psalm-import-type DiscriminatorColumnMapping from \Doctrine\ORM\Mapping\ClassMetadata
* @phpstan-import-type AssociationMapping from \Doctrine\ORM\Mapping\ClassMetadata
* @phpstan-import-type FieldMapping from \Doctrine\ORM\Mapping\ClassMetadata
* @phpstan-import-type EmbeddedClassMapping from \Doctrine\ORM\Mapping\ClassMetadata
* @phpstan-import-type JoinColumnData from \Doctrine\ORM\Mapping\ClassMetadata
* @phpstan-import-type DiscriminatorColumnMapping from \Doctrine\ORM\Mapping\ClassMetadata
*/
class ClassMetadataInfo implements ClassMetadata
{
@@ -370,14 +370,14 @@ class ClassMetadataInfo implements ClassMetadata
* declared in another parent <em>entity or mapped superclass</em>. The value is the FQCN
* of the topmost non-transient class that contains mapping information for this field.
*
* @psalm-var array<string, EmbeddedClassMapping>
* @phpstan-var array<string, EmbeddedClassMapping>
*/
public $embeddedClasses = [];
/**
* READ-ONLY: The named queries allowed to be called directly from Repository.
*
* @psalm-var array<string, array<string, mixed>>
* @phpstan-var array<string, array<string, mixed>>
*/
public $namedQueries = [];
@@ -394,7 +394,7 @@ class ClassMetadataInfo implements ClassMetadata
* )
* </pre>
*
* @psalm-var array<string, array<string, mixed>>
* @phpstan-var array<string, array<string, mixed>>
*/
public $namedNativeQueries = [];
@@ -410,7 +410,7 @@ class ClassMetadataInfo implements ClassMetadata
* )
* </pre>
*
* @psalm-var array<string, array{
* @phpstan-var array<string, array{
* name: string,
* entities: mixed[],
* columns: mixed[]
@@ -422,7 +422,7 @@ class ClassMetadataInfo implements ClassMetadata
* READ-ONLY: The field names of all fields that are part of the identifier/primary key
* of the mapped entity class.
*
* @psalm-var list<string>
* @phpstan-var list<string>
*/
public $identifier = [];
@@ -430,7 +430,7 @@ class ClassMetadataInfo implements ClassMetadata
* READ-ONLY: The inheritance mapping type used by the class.
*
* @var int
* @psalm-var self::INHERITANCE_TYPE_*
* @phpstan-var self::INHERITANCE_TYPE_*
*/
public $inheritanceType = self::INHERITANCE_TYPE_NONE;
@@ -438,7 +438,7 @@ class ClassMetadataInfo implements ClassMetadata
* READ-ONLY: The Id generator type used by the class.
*
* @var int
* @psalm-var self::GENERATOR_TYPE_*
* @phpstan-var self::GENERATOR_TYPE_*
*/
public $generatorType = self::GENERATOR_TYPE_NONE;
@@ -502,7 +502,7 @@ class ClassMetadataInfo implements ClassMetadata
* of the topmost non-transient class that contains mapping information for this field.
*
* @var mixed[]
* @psalm-var array<string, FieldMapping>
* @phpstan-var array<string, FieldMapping>
*/
public $fieldMappings = [];
@@ -510,7 +510,7 @@ class ClassMetadataInfo implements ClassMetadata
* READ-ONLY: An array of field names. Used to look up field names from column names.
* Keys are column names and values are field names.
*
* @psalm-var array<string, string>
* @phpstan-var array<string, string>
*/
public $fieldNames = [];
@@ -554,7 +554,7 @@ class ClassMetadataInfo implements ClassMetadata
* inheritance mappings.
*
* @var array<string, mixed>
* @psalm-var DiscriminatorColumnMapping|null
* @phpstan-var DiscriminatorColumnMapping|null
*/
public $discriminatorColumn;
@@ -568,7 +568,7 @@ class ClassMetadataInfo implements ClassMetadata
* uniqueConstraints => array
*
* @var mixed[]
* @psalm-var array{
* @phpstan-var array{
* name: string,
* schema?: string,
* indexes?: array,
@@ -582,14 +582,14 @@ class ClassMetadataInfo implements ClassMetadata
/**
* READ-ONLY: The registered lifecycle callbacks for entities of this class.
*
* @psalm-var array<string, list<string>>
* @phpstan-var array<string, list<string>>
*/
public $lifecycleCallbacks = [];
/**
* READ-ONLY: The registered entity listeners.
*
* @psalm-var array<string, list<array{class: class-string, method: string}>>
* @phpstan-var array<string, list<array{class: class-string, method: string}>>
*/
public $entityListeners = [];
@@ -665,7 +665,7 @@ class ClassMetadataInfo implements ClassMetadata
* )
* </pre>
*
* @psalm-var array<string, AssociationMapping>
* @phpstan-var array<string, AssociationMapping>
*/
public $associationMappings = [];
@@ -716,7 +716,7 @@ class ClassMetadataInfo implements ClassMetadata
* </code>
*
* @var array<string, mixed>|null
* @psalm-var array{sequenceName: string, allocationSize: string, initialValue: string, quoted?: mixed}|null
* @phpstan-var array{sequenceName: string, allocationSize: string, initialValue: string, quoted?: mixed}|null
* @todo Merge with tableGeneratorDefinition into generic generatorDefinition
*/
public $sequenceGeneratorDefinition;
@@ -821,7 +821,7 @@ class ClassMetadataInfo implements ClassMetadata
* Gets the ReflectionProperties of the mapped class.
*
* @return ReflectionProperty[]|null[] An array of ReflectionProperty instances.
* @psalm-return array<ReflectionProperty|null>
* @phpstan-return array<ReflectionProperty|null>
*/
public function getReflectionProperties()
{
@@ -896,7 +896,7 @@ class ClassMetadataInfo implements ClassMetadata
* Populates the entity identifier of an entity.
*
* @param object $entity
* @psalm-param array<string, mixed> $id
* @phpstan-param array<string, mixed> $id
*
* @return void
*
@@ -1248,7 +1248,7 @@ class ClassMetadataInfo implements ClassMetadata
}
/**
* @psalm-param array{usage?: mixed, region?: mixed} $cache
* @phpstan-param array{usage?: mixed, region?: mixed} $cache
*
* @return void
*/
@@ -1267,7 +1267,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* @param string $fieldName
* @psalm-param array{usage?: int, region?: string} $cache
* @phpstan-param array{usage?: int, region?: string} $cache
*
* @return void
*/
@@ -1278,11 +1278,10 @@ class ClassMetadataInfo implements ClassMetadata
/**
* @param string $fieldName
* @param array $cache
* @psalm-param array{usage?: int|null, region?: string|null} $cache
* @phpstan-param array{usage?: int|null, region?: string|null} $cache
*
* @return int[]|string[]
* @psalm-return array{usage: int, region: string|null}
* @phpstan-return array{usage: int, region: string|null}
*/
public function getAssociationCacheDefaults($fieldName, array $cache)
{
@@ -1410,7 +1409,7 @@ class ClassMetadataInfo implements ClassMetadata
* @param string $fieldName The field name.
*
* @return mixed[] The field mapping.
* @psalm-return FieldMapping
* @phpstan-return FieldMapping
*
* @throws MappingException
*/
@@ -1432,7 +1431,7 @@ class ClassMetadataInfo implements ClassMetadata
* the object model.
*
* @return mixed[] The mapping.
* @psalm-return AssociationMapping
* @phpstan-return AssociationMapping
*
* @throws MappingException
*/
@@ -1448,7 +1447,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Gets all association mappings of the class.
*
* @psalm-return array<string, AssociationMapping>
* @phpstan-return array<string, AssociationMapping>
*/
public function getAssociationMappings()
{
@@ -1492,7 +1491,7 @@ class ClassMetadataInfo implements ClassMetadata
* Gets all named queries of the class.
*
* @return mixed[][]
* @psalm-return array<string, array<string, mixed>>
* @phpstan-return array<string, array<string, mixed>>
*/
public function getNamedQueries()
{
@@ -1507,7 +1506,7 @@ class ClassMetadataInfo implements ClassMetadata
* @param string $queryName The query name.
*
* @return mixed[]
* @psalm-return array<string, mixed>
* @phpstan-return array<string, mixed>
*
* @throws MappingException
*/
@@ -1523,7 +1522,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Gets all named native queries of the class.
*
* @psalm-return array<string, array<string, mixed>>
* @phpstan-return array<string, array<string, mixed>>
*/
public function getNamedNativeQueries()
{
@@ -1538,7 +1537,7 @@ class ClassMetadataInfo implements ClassMetadata
* @param string $name The result set mapping name.
*
* @return mixed[]
* @psalm-return array{name: string, entities: array, columns: array}
* @phpstan-return array{name: string, entities: array, columns: array}
*
* @throws MappingException
*/
@@ -1555,7 +1554,7 @@ class ClassMetadataInfo implements ClassMetadata
* Gets all sql result set mappings of the class.
*
* @return mixed[]
* @psalm-return array<string, array{name: string, entities: array, columns: array}>
* @phpstan-return array<string, array{name: string, entities: array, columns: array}>
*/
public function getSqlResultSetMappings()
{
@@ -1616,7 +1615,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Validates & completes the given field mapping.
*
* @psalm-param array{
* @phpstan-param array{
* fieldName?: string,
* columnName?: string,
* id?: bool,
@@ -1719,10 +1718,10 @@ class ClassMetadataInfo implements ClassMetadata
* Validates & completes the basic mapping information that is common to all
* association mappings (one-to-one, many-ot-one, one-to-many, many-to-many).
*
* @psalm-param array<string, mixed> $mapping The mapping.
* @phpstan-param array<string, mixed> $mapping The mapping.
*
* @return mixed[] The updated mapping.
* @psalm-return AssociationMapping
* @phpstan-return AssociationMapping
*
* @throws MappingException If something is wrong with the mapping.
*/
@@ -1849,10 +1848,10 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Validates & completes a one-to-one association mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
* @phpstan-param array<string, mixed> $mapping The mapping to validate & complete.
*
* @return mixed[] The validated & completed mapping.
* @psalm-return AssociationMapping
* @phpstan-return AssociationMapping
*
* @throws RuntimeException
* @throws MappingException
@@ -1947,10 +1946,10 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Validates & completes a one-to-many association mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping to validate and complete.
* @phpstan-param array<string, mixed> $mapping The mapping to validate and complete.
*
* @return mixed[] The validated and completed mapping.
* @psalm-return AssociationMapping
* @phpstan-return AssociationMapping
*
* @throws MappingException
* @throws InvalidArgumentException
@@ -1975,10 +1974,10 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Validates & completes a many-to-many association mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping to validate & complete.
* @phpstan-param array<string, mixed> $mapping The mapping to validate & complete.
*
* @return mixed[] The validated & completed mapping.
* @psalm-return AssociationMapping
* @phpstan-return AssociationMapping
*
* @throws InvalidArgumentException
*/
@@ -2126,7 +2125,7 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the mapped identifier/primary key fields of this class.
* Mainly used by the ClassMetadataFactory to assign inherited identifiers.
*
* @psalm-param list<mixed> $identifier
* @phpstan-param list<mixed> $identifier
*
* @return void
*/
@@ -2155,10 +2154,10 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Gets an array containing all the column names.
*
* @psalm-param list<string>|null $fieldNames
* @phpstan-param list<string>|null $fieldNames
*
* @return mixed[]
* @psalm-return list<string>
* @phpstan-return list<string>
*/
public function getColumnNames(?array $fieldNames = null)
{
@@ -2172,7 +2171,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Returns an array with all the identifier column names.
*
* @psalm-return list<string>
* @phpstan-return list<string>
*/
public function getIdentifierColumnNames()
{
@@ -2201,7 +2200,7 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the type of Id generator to use for the mapped class.
*
* @param int $generatorType
* @psalm-param self::GENERATOR_TYPE_* $generatorType
* @phpstan-param self::GENERATOR_TYPE_* $generatorType
*
* @return void
*/
@@ -2282,7 +2281,7 @@ class ClassMetadataInfo implements ClassMetadata
*
* @return bool TRUE if the class uses the SEQUENCE generator, FALSE otherwise.
*
* @psalm-assert-if-true !null $this->sequenceGeneratorDefinition
* @phpstan-assert-if-true !null $this->sequenceGeneratorDefinition
*/
public function isIdGeneratorSequence()
{
@@ -2403,7 +2402,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Sets the mapped subclasses of this class.
*
* @psalm-param list<string> $subclasses The names of all mapped subclasses.
* @phpstan-param list<string> $subclasses The names of all mapped subclasses.
*
* @return void
*/
@@ -2437,7 +2436,7 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the inheritance type used by the class and its subclasses.
*
* @param int $type
* @psalm-param self::INHERITANCE_TYPE_* $type
* @phpstan-param self::INHERITANCE_TYPE_* $type
*
* @return void
*
@@ -2456,7 +2455,7 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the association to override association mapping of property for an entity relationship.
*
* @param string $fieldName
* @psalm-param array<string, mixed> $overrideMapping
* @phpstan-param array<string, mixed> $overrideMapping
*
* @return void
*
@@ -2525,7 +2524,7 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the override for a mapped field.
*
* @param string $fieldName
* @psalm-param array<string, mixed> $overrideMapping
* @phpstan-param array<string, mixed> $overrideMapping
*
* @return void
*
@@ -2649,7 +2648,7 @@ class ClassMetadataInfo implements ClassMetadata
*
* If a key is omitted, the current value is kept.
*
* @psalm-param array<string, mixed> $table The table description.
* @phpstan-param array<string, mixed> $table The table description.
*
* @return void
*/
@@ -2716,7 +2715,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Adds a mapped field to the class.
*
* @psalm-param array<string, mixed> $mapping The field mapping.
* @phpstan-param array<string, mixed> $mapping The field mapping.
*
* @return void
*
@@ -2739,7 +2738,7 @@ class ClassMetadataInfo implements ClassMetadata
* Adds an association mapping without completing/validating it.
* This is mainly used to add inherited association mappings to derived classes.
*
* @psalm-param AssociationMapping $mapping
* @phpstan-param AssociationMapping $mapping
*
* @return void
*
@@ -2759,7 +2758,7 @@ class ClassMetadataInfo implements ClassMetadata
* Adds a field mapping without completing/validating it.
* This is mainly used to add inherited field mappings to derived classes.
*
* @psalm-param FieldMapping $fieldMapping
* @phpstan-param FieldMapping $fieldMapping
*
* @return void
*/
@@ -2781,7 +2780,7 @@ class ClassMetadataInfo implements ClassMetadata
*
* @deprecated
*
* @psalm-param array<string, mixed> $queryMapping
* @phpstan-param array<string, mixed> $queryMapping
*
* @return void
*
@@ -2826,7 +2825,7 @@ class ClassMetadataInfo implements ClassMetadata
*
* @deprecated
*
* @psalm-param array<string, mixed> $queryMapping
* @phpstan-param array<string, mixed> $queryMapping
*
* @return void
*
@@ -2877,7 +2876,7 @@ class ClassMetadataInfo implements ClassMetadata
* INTERNAL:
* Adds a sql result set mapping to this class.
*
* @psalm-param array<string, mixed> $resultMapping
* @phpstan-param array<string, mixed> $resultMapping
*
* @return void
*
@@ -2951,7 +2950,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Adds a one-to-many mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping.
* @phpstan-param array<string, mixed> $mapping The mapping.
*
* @return void
*/
@@ -2967,7 +2966,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Adds a many-to-one mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping.
* @phpstan-param array<string, mixed> $mapping The mapping.
*
* @return void
*/
@@ -2984,7 +2983,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Adds a many-to-many mapping.
*
* @psalm-param array<string, mixed> $mapping The mapping.
* @phpstan-param array<string, mixed> $mapping The mapping.
*
* @return void
*/
@@ -3000,7 +2999,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Stores the association mapping.
*
* @psalm-param AssociationMapping $assocMapping
* @phpstan-param AssociationMapping $assocMapping
*
* @return void
*
@@ -3063,7 +3062,7 @@ class ClassMetadataInfo implements ClassMetadata
* @param string $event
*
* @return string[]
* @psalm-return list<string>
* @phpstan-return list<string>
*/
public function getLifecycleCallbacks($event)
{
@@ -3101,7 +3100,7 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the lifecycle callbacks for entities of this class.
* Any previously registered callbacks are overwritten.
*
* @psalm-param array<string, list<string>> $callbacks
* @phpstan-param array<string, list<string>> $callbacks
*
* @return void
*/
@@ -3151,7 +3150,7 @@ class ClassMetadataInfo implements ClassMetadata
* @see getDiscriminatorColumn()
*
* @param mixed[]|null $columnDef
* @psalm-param array{name: string|null, fieldName?: string, type?: string, length?: int, columnDefinition?: string|null, enumType?: class-string<BackedEnum>|null, options?: array<string, mixed>}|null $columnDef
* @phpstan-param array{name: string|null, fieldName?: string, type?: string, length?: int, columnDefinition?: string|null, enumType?: class-string<BackedEnum>|null, options?: array<string, mixed>}|null $columnDef
*
* @return void
*
@@ -3186,7 +3185,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* @return array<string, mixed>
* @psalm-return DiscriminatorColumnMapping
* @phpstan-return DiscriminatorColumnMapping
*/
final public function getDiscriminatorColumn(): array
{
@@ -3415,7 +3414,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Sets definition.
*
* @psalm-param array<string, string|null> $definition
* @phpstan-param array<string, string|null> $definition
*
* @return void
*/
@@ -3437,7 +3436,7 @@ class ClassMetadataInfo implements ClassMetadata
* )
* </code>
*
* @psalm-param array{sequenceName?: string, allocationSize?: int|string, initialValue?: int|string, quoted?: mixed} $definition
* @phpstan-param array{sequenceName?: string, allocationSize?: int|string, initialValue?: int|string, quoted?: mixed} $definition
*
* @return void
*
@@ -3472,7 +3471,7 @@ class ClassMetadataInfo implements ClassMetadata
* Sets the version field mapping used for versioning. Sets the default
* value to use depending on the column type.
*
* @psalm-param array<string, mixed> $mapping The version field mapping array.
* @phpstan-param array<string, mixed> $mapping The version field mapping array.
*
* @return void
*
@@ -3584,7 +3583,7 @@ class ClassMetadataInfo implements ClassMetadata
* @param AbstractPlatform $platform
*
* @return string[]
* @psalm-return list<string>
* @phpstan-return list<string>
*/
public function getQuotedIdentifierColumnNames($platform)
{
@@ -3698,7 +3697,7 @@ class ClassMetadataInfo implements ClassMetadata
* @param string $targetClass
*
* @return mixed[][]
* @psalm-return array<string, array<string, mixed>>
* @phpstan-return array<string, array<string, mixed>>
*/
public function getAssociationsByTargetClass($targetClass)
{
@@ -3748,7 +3747,7 @@ class ClassMetadataInfo implements ClassMetadata
/**
* Map Embedded Class
*
* @psalm-param array<string, mixed> $mapping
* @phpstan-param array<string, mixed> $mapping
*
* @return void
*
@@ -3867,7 +3866,7 @@ class ClassMetadataInfo implements ClassMetadata
return $sequencePrefix;
}
/** @psalm-param AssociationMapping $mapping */
/** @phpstan-param AssociationMapping $mapping */
private function assertMappingOrderBy(array $mapping): void
{
if (isset($mapping['orderBy']) && ! is_array($mapping['orderBy'])) {

View File

@@ -95,7 +95,7 @@ final class Column implements MappingAttribute
/**
* @var string|null
* @readonly
* @psalm-var 'NEVER'|'INSERT'|'ALWAYS'|null
* @phpstan-var 'NEVER'|'INSERT'|'ALWAYS'|null
* @Enum({"NEVER", "INSERT", "ALWAYS"})
*/
public $generated;
@@ -103,7 +103,7 @@ final class Column implements MappingAttribute
/**
* @param class-string<BackedEnum>|null $enumType
* @param array<string,mixed> $options
* @psalm-param 'NEVER'|'INSERT'|'ALWAYS'|null $generated
* @phpstan-param 'NEVER'|'INSERT'|'ALWAYS'|null $generated
*/
public function __construct(
?string $name = null,

View File

@@ -21,7 +21,7 @@ use function is_a;
use const PHP_VERSION_ID;
/** @psalm-type ScalarName = 'array'|'bool'|'float'|'int'|'string' */
/** @phpstan-type ScalarName = 'array'|'bool'|'float'|'int'|'string' */
final class DefaultTypedFieldMapper implements TypedFieldMapper
{
/** @var array<class-string|ScalarName, class-string<Type>|string> $typedFieldMappings */
@@ -68,8 +68,6 @@ final class DefaultTypedFieldMapper implements TypedFieldMapper
assert(is_a($type->getName(), BackedEnum::class, true));
$mapping['enumType'] = $type->getName();
$type = $reflection->getBackingType();
assert($type instanceof ReflectionNamedType);
}
if (isset($this->typedFieldMappings[$type->getName()])) {

View File

@@ -671,7 +671,7 @@ class AnnotationDriver extends CompatibilityAnnotationDriver
*
* @param class-string $className
*
* @psalm-return ClassMetadata::FETCH_* The fetch mode as defined in ClassMetadata.
* @phpstan-return ClassMetadata::FETCH_* The fetch mode as defined in ClassMetadata.
*
* @throws MappingException If the fetch mode is not valid.
*/
@@ -687,7 +687,7 @@ class AnnotationDriver extends CompatibilityAnnotationDriver
/**
* Attempts to resolve the generated mode.
*
* @psalm-return ClassMetadata::GENERATED_*
* @phpstan-return ClassMetadata::GENERATED_*
*
* @throws MappingException If the fetch mode is not valid.
*/
@@ -704,7 +704,7 @@ class AnnotationDriver extends CompatibilityAnnotationDriver
* Parses the given method.
*
* @return list<array{string, string}>
* @psalm-return list<array{string, (Events::*)}>
* @phpstan-return list<array{string, (Events::*)}>
*/
private function getMethodCallbacks(ReflectionMethod $method): array
{
@@ -752,7 +752,7 @@ class AnnotationDriver extends CompatibilityAnnotationDriver
* Parse the given JoinColumn as array
*
* @return mixed[]
* @psalm-return array{
* @phpstan-return array{
* name: string|null,
* unique: bool,
* nullable: bool,
@@ -784,7 +784,7 @@ class AnnotationDriver extends CompatibilityAnnotationDriver
* Parse the given Column as array
*
* @return mixed[]
* @psalm-return array{
* @phpstan-return array{
* fieldName: string,
* type: mixed,
* scale: int,

View File

@@ -16,9 +16,7 @@ use Doctrine\Persistence\Mapping\Driver\ColocatedMappingDriver;
use LogicException;
use ReflectionClass;
use ReflectionMethod;
use ReflectionProperty;
use function assert;
use function class_exists;
use function constant;
use function defined;
@@ -310,8 +308,6 @@ class AttributeDriver extends CompatibilityAnnotationDriver
}
foreach ($reflectionClass->getProperties() as $property) {
assert($property instanceof ReflectionProperty);
if ($this->isRepeatedPropertyDeclaration($property, $metadata)) {
continue;
}
@@ -322,8 +318,6 @@ class AttributeDriver extends CompatibilityAnnotationDriver
// Evaluate #[Cache] attribute
$cacheAttribute = $this->reader->getPropertyAttribute($property, Mapping\Cache::class);
if ($cacheAttribute !== null) {
assert($cacheAttribute instanceof Mapping\Cache);
$mapping['cache'] = $metadata->getAssociationCacheDefaults(
$mapping['fieldName'],
[
@@ -569,7 +563,6 @@ class AttributeDriver extends CompatibilityAnnotationDriver
$listenerClass = new ReflectionClass($listenerClassName);
foreach ($listenerClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
assert($method instanceof ReflectionMethod);
// find method callbacks.
$callbacks = $this->getMethodCallbacks($method);
$hasMapping = $hasMapping ?: ! empty($callbacks);
@@ -589,7 +582,6 @@ class AttributeDriver extends CompatibilityAnnotationDriver
// Evaluate #[HasLifecycleCallbacks] attribute
if (isset($classAttributes[Mapping\HasLifecycleCallbacks::class])) {
foreach ($reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
assert($method instanceof ReflectionMethod);
foreach ($this->getMethodCallbacks($method) as $value) {
$metadata->addLifecycleCallback($value[0], $value[1]);
}
@@ -634,7 +626,7 @@ class AttributeDriver extends CompatibilityAnnotationDriver
* Parses the given method.
*
* @return list<array{string, string}>
* @psalm-return list<array{string, (Events::*)}>
* @phpstan-return list<array{string, (Events::*)}>
*/
private function getMethodCallbacks(ReflectionMethod $method): array
{
@@ -684,7 +676,7 @@ class AttributeDriver extends CompatibilityAnnotationDriver
* @param Mapping\JoinColumn|Mapping\InverseJoinColumn $joinColumn
*
* @return mixed[]
* @psalm-return array{
* @phpstan-return array{
* name: string|null,
* unique: bool,
* nullable: bool,
@@ -716,7 +708,7 @@ class AttributeDriver extends CompatibilityAnnotationDriver
* Parse the given Column as array
*
* @return mixed[]
* @psalm-return array{
* @phpstan-return array{
* fieldName: string,
* type: mixed,
* scale: int,

View File

@@ -24,7 +24,7 @@ final class AttributeReader
private array $isRepeatableAttribute = [];
/**
* @psalm-return class-string-map<T, T|RepeatableAttributeCollection<T>>
* @phpstan-return class-string-map<T, T|RepeatableAttributeCollection<T>>
*
* @template T of Annotation
*/

View File

@@ -69,7 +69,7 @@ class DatabaseDriver implements MappingDriver
/** @var array<class-string, string> */
private $classToTableNames = [];
/** @psalm-var array<string, Table> */
/** @phpstan-var array<string, Table> */
private $manyToManyTables = [];
/** @var mixed[] */
@@ -156,8 +156,8 @@ class DatabaseDriver implements MappingDriver
*
* @param Table[] $entityTables
* @param Table[] $manyToManyTables
* @psalm-param list<Table> $entityTables
* @psalm-param list<Table> $manyToManyTables
* @phpstan-param list<Table> $entityTables
* @phpstan-param list<Table> $manyToManyTables
*
* @return void
*/
@@ -400,7 +400,7 @@ class DatabaseDriver implements MappingDriver
* Build field mapping from a schema column definition
*
* @return mixed[]
* @psalm-return array{
* @phpstan-return array{
* fieldName: string,
* columnName: string,
* type: string,

View File

@@ -32,8 +32,13 @@ trait ReflectionBasedDriver
|| $metadata->isInheritedEmbeddedClass($property->name);
}
/** @var class-string $declaringClass */
$declaringClass = $property->class;
if ($this->isTransient($declaringClass)) {
return isset($metadata->fieldMappings[$property->name]);
}
if (
isset($metadata->fieldMappings[$property->name]['declared'])
&& $metadata->fieldMappings[$property->name]['declared'] === $declaringClass

View File

@@ -488,7 +488,6 @@ class XmlDriver extends FileDriver
if (isset($oneToManyElement->{'order-by'})) {
$orderBy = [];
foreach ($oneToManyElement->{'order-by'}->{'order-by-field'} ?? [] as $orderByField) {
/** @psalm-suppress DeprecatedConstant */
$orderBy[(string) $orderByField['name']] = isset($orderByField['direction'])
? (string) $orderByField['direction']
// @phpstan-ignore classConstant.deprecated
@@ -618,7 +617,6 @@ class XmlDriver extends FileDriver
if (isset($manyToManyElement->{'order-by'})) {
$orderBy = [];
foreach ($manyToManyElement->{'order-by'}->{'order-by-field'} ?? [] as $orderByField) {
/** @psalm-suppress DeprecatedConstant */
$orderBy[(string) $orderByField['name']] = isset($orderByField['direction'])
? (string) $orderByField['direction']
// @phpstan-ignore classConstant.deprecated
@@ -746,7 +744,7 @@ class XmlDriver extends FileDriver
* Parses (nested) option elements.
*
* @return mixed[] The options array.
* @psalm-return array<int|string, array<int|string, mixed|string>|bool|string>
* @phpstan-return array<int|string, array<int|string, mixed|string>|bool|string>
*/
private function parseOptions(?SimpleXMLElement $options): array
{
@@ -781,7 +779,7 @@ class XmlDriver extends FileDriver
* @param SimpleXMLElement $joinColumnElement The XML element.
*
* @return mixed[] The mapping array.
* @psalm-return array{
* @phpstan-return array{
* name: string,
* referencedColumnName: string,
* unique?: bool,
@@ -825,7 +823,7 @@ class XmlDriver extends FileDriver
* Parses the given field as array.
*
* @return mixed[]
* @psalm-return array{
* @phpstan-return array{
* fieldName: string,
* type?: string,
* columnName?: string,
@@ -911,7 +909,7 @@ class XmlDriver extends FileDriver
* Parse / Normalize the cache configuration
*
* @return mixed[]
* @psalm-return array{usage: int|null, region?: string}
* @phpstan-return array{usage: int|null, region?: string}
*/
private function cacheToArray(SimpleXMLElement $cacheMapping): array
{
@@ -938,7 +936,7 @@ class XmlDriver extends FileDriver
* @param SimpleXMLElement $cascadeElement The cascade element.
*
* @return string[] The list of cascade options.
* @psalm-return list<string>
* @phpstan-return list<string>
*/
private function getCascadeMappings(SimpleXMLElement $cascadeElement): array
{

View File

@@ -738,7 +738,7 @@ class YamlDriver extends FileDriver
* Constructs a joinColumn mapping array based on the information
* found in the given join column element.
*
* @psalm-param array{
* @phpstan-param array{
* referencedColumnName?: mixed,
* name?: mixed,
* fieldName?: mixed,
@@ -749,7 +749,7 @@ class YamlDriver extends FileDriver
* } $joinColumnElement The array join column element.
*
* @return mixed[] The mapping array.
* @psalm-return array{
* @phpstan-return array{
* referencedColumnName?: string,
* name?: string,
* fieldName?: string,
@@ -796,7 +796,7 @@ class YamlDriver extends FileDriver
/**
* Parses the given column as array.
*
* @psalm-param array{
* @phpstan-param array{
* type?: string,
* column?: string,
* precision?: mixed,
@@ -813,7 +813,7 @@ class YamlDriver extends FileDriver
* }|null $column
*
* @return mixed[]
* @psalm-return array{
* @phpstan-return array{
* fieldName: string,
* type?: string,
* columnName?: string,
@@ -905,10 +905,10 @@ class YamlDriver extends FileDriver
* Parse / Normalize the cache configuration
*
* @param mixed[] $cacheMapping
* @psalm-param array{usage: string|null, region?: mixed} $cacheMapping
* @phpstan-param array{usage: string|null, region?: mixed} $cacheMapping
*
* @return mixed[]
* @psalm-return array{usage: int|null, region: string|null}
* @phpstan-return array{usage: int|null, region: string|null}
*/
private function cacheToArray(array $cacheMapping): array
{

View File

@@ -29,7 +29,7 @@ final class Entity implements MappingAttribute
*/
public $readOnly = false;
/** @psalm-param class-string<EntityRepository<T>>|null $repositoryClass */
/** @phpstan-param class-string<EntityRepository<T>>|null $repositoryClass */
public function __construct(?string $repositoryClass = null, bool $readOnly = false)
{
$this->repositoryClass = $repositoryClass;

View File

@@ -19,13 +19,13 @@ final class GeneratedValue implements MappingAttribute
* The type of ID generator.
*
* @var string
* @psalm-var 'AUTO'|'SEQUENCE'|'IDENTITY'|'NONE'|'CUSTOM'
* @phpstan-var 'AUTO'|'SEQUENCE'|'IDENTITY'|'NONE'|'CUSTOM'
* @readonly
* @Enum({"AUTO", "SEQUENCE", "TABLE", "IDENTITY", "NONE", "UUID", "CUSTOM"})
*/
public $strategy = 'AUTO';
/** @psalm-param 'AUTO'|'SEQUENCE'|'IDENTITY'|'NONE'|'CUSTOM' $strategy */
/** @phpstan-param 'AUTO'|'SEQUENCE'|'IDENTITY'|'NONE'|'CUSTOM' $strategy */
public function __construct(string $strategy = 'AUTO')
{
$this->strategy = $strategy;

View File

@@ -20,13 +20,13 @@ final class InheritanceType implements MappingAttribute
* The inheritance type used by the class and its subclasses.
*
* @var string
* @psalm-var 'NONE'|'JOINED'|'SINGLE_TABLE'|'TABLE_PER_CLASS'
* @phpstan-var 'NONE'|'JOINED'|'SINGLE_TABLE'|'TABLE_PER_CLASS'
* @readonly
* @Enum({"NONE", "JOINED", "SINGLE_TABLE", "TABLE_PER_CLASS"})
*/
public $value;
/** @psalm-param 'NONE'|'JOINED'|'SINGLE_TABLE'|'TABLE_PER_CLASS' $value */
/** @phpstan-param 'NONE'|'JOINED'|'SINGLE_TABLE'|'TABLE_PER_CLASS' $value */
public function __construct(string $value)
{
if ($value === 'TABLE_PER_CLASS') {

View File

@@ -44,7 +44,7 @@ final class ManyToMany implements MappingAttribute
* The fetching strategy to use for the association.
*
* @var string
* @psalm-var 'LAZY'|'EAGER'|'EXTRA_LAZY'
* @phpstan-var 'LAZY'|'EAGER'|'EXTRA_LAZY'
* @readonly
* @Enum({"LAZY", "EAGER", "EXTRA_LAZY"})
*/
@@ -65,7 +65,7 @@ final class ManyToMany implements MappingAttribute
/**
* @param class-string|null $targetEntity
* @param string[]|null $cascade
* @psalm-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
* @phpstan-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
*/
public function __construct(
?string $targetEntity = null,

View File

@@ -31,7 +31,7 @@ final class ManyToOne implements MappingAttribute
* The fetching strategy to use for the association.
*
* @var string
* @psalm-var 'LAZY'|'EAGER'|'EXTRA_LAZY'
* @phpstan-var 'LAZY'|'EAGER'|'EXTRA_LAZY'
* @readonly
* @Enum({"LAZY", "EAGER", "EXTRA_LAZY"})
*/
@@ -46,7 +46,7 @@ final class ManyToOne implements MappingAttribute
/**
* @param class-string|null $targetEntity
* @param string[]|null $cascade
* @psalm-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
* @phpstan-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
*/
public function __construct(
?string $targetEntity = null,

View File

@@ -37,7 +37,7 @@ final class OneToMany implements MappingAttribute
* The fetching strategy to use for the association.
*
* @var string
* @psalm-var 'LAZY'|'EAGER'|'EXTRA_LAZY'
* @phpstan-var 'LAZY'|'EAGER'|'EXTRA_LAZY'
* @readonly
* @Enum({"LAZY", "EAGER", "EXTRA_LAZY"})
*/
@@ -58,7 +58,7 @@ final class OneToMany implements MappingAttribute
/**
* @param class-string|null $targetEntity
* @param string[]|null $cascade
* @psalm-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
* @phpstan-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
*/
public function __construct(
?string $mappedBy = null,

View File

@@ -43,7 +43,7 @@ final class OneToOne implements MappingAttribute
* The fetching strategy to use for the association.
*
* @var string
* @psalm-var 'LAZY'|'EAGER'|'EXTRA_LAZY'
* @phpstan-var 'LAZY'|'EAGER'|'EXTRA_LAZY'
* @readonly
* @Enum({"LAZY", "EAGER", "EXTRA_LAZY"})
*/
@@ -58,7 +58,7 @@ final class OneToOne implements MappingAttribute
/**
* @param class-string|null $targetEntity
* @param array<string>|null $cascade
* @psalm-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
* @phpstan-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
*/
public function __construct(
?string $mappedBy = null,

View File

@@ -9,8 +9,8 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* A set of rules for determining the column, alias and table quotes.
*
* @psalm-import-type AssociationMapping from ClassMetadata
* @psalm-import-type JoinColumnData from ClassMetadata
* @phpstan-import-type AssociationMapping from ClassMetadata
* @phpstan-import-type JoinColumnData from ClassMetadata
*/
interface QuoteStrategy
{
@@ -69,7 +69,7 @@ interface QuoteStrategy
/**
* Gets the (possibly quoted) identifier column names for safe use in an SQL statement.
*
* @psalm-return list<string>
* @phpstan-return list<string>
*/
public function getIdentifierColumnNames(ClassMetadata $class, AbstractPlatform $platform);

View File

@@ -59,7 +59,7 @@ final class ReflectionPropertiesGetter
* @param class-string $className
*
* @return ReflectionClass[]
* @psalm-return list<ReflectionClass<object>>
* @phpstan-return list<ReflectionClass<object>>
*/
private function getHierarchyClasses(string $className): array
{
@@ -83,7 +83,7 @@ final class ReflectionPropertiesGetter
/**
* @return ReflectionProperty[]
* @psalm-return array<string, ReflectionProperty>
* @phpstan-return array<string, ReflectionProperty>
*/
private function getClassProperties(ReflectionClass $reflectionClass): array
{

View File

@@ -32,7 +32,7 @@ class UnderscoreNamingStrategy implements NamingStrategy
/**
* @var string
* @psalm-var non-empty-string
* @phpstan-var non-empty-string
*/
private $pattern;

View File

@@ -24,7 +24,7 @@ use function sprintf;
/**
* Contains exception messages for all invalid lifecycle state exceptions inside UnitOfWork
*
* @psalm-import-type AssociationMapping from ClassMetadata
* @phpstan-import-type AssociationMapping from ClassMetadata
*/
class ORMInvalidArgumentException extends InvalidArgumentException
{
@@ -83,7 +83,7 @@ class ORMInvalidArgumentException extends InvalidArgumentException
}
/**
* @psalm-param non-empty-list<array{AssociationMapping, object}> $newEntitiesWithAssociations non-empty an array
* @phpstan-param non-empty-list<array{AssociationMapping, object}> $newEntitiesWithAssociations non-empty an array
* of [array $associationMapping, object $entity] pairs
*
* @return ORMInvalidArgumentException
@@ -112,7 +112,7 @@ class ORMInvalidArgumentException extends InvalidArgumentException
/**
* @param object $entry
* @psalm-param AssociationMapping $associationMapping
* @phpstan-param AssociationMapping $associationMapping
*
* @return ORMInvalidArgumentException
*/
@@ -123,7 +123,7 @@ class ORMInvalidArgumentException extends InvalidArgumentException
/**
* @param object $entry
* @psalm-param AssociationMapping $assoc
* @phpstan-param AssociationMapping $assoc
*
* @return ORMInvalidArgumentException
*/
@@ -300,7 +300,7 @@ EXCEPTION
/**
* @param object $entity
* @psalm-param AssociationMapping $associationMapping
* @phpstan-param AssociationMapping $associationMapping
*/
private static function newEntityFoundThroughRelationshipMessage(array $associationMapping, $entity): string
{
@@ -309,7 +309,7 @@ EXCEPTION
. ' configured to cascade persist operations for entity: ' . self::objToStr($entity) . '.'
. ' To solve this issue: Either explicitly call EntityManager#persist()'
. ' on this unknown entity or configure cascade persist'
. ' this association in the mapping for example @ManyToOne(..,cascade={"persist"}).'
. ' this association in the mapping for example #[ORM\ManyToOne(..., cascade: [\'persist\'])].'
. (method_exists($entity, '__toString')
? ''
: ' If you cannot find out which entity causes the problem implement \''

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