mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 15:02:22 +01:00
Compare commits
118 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c9557c588b | ||
|
|
19912de927 | ||
|
|
737cca5b78 | ||
|
|
aff82af7de | ||
|
|
9e999ea1ff | ||
|
|
6755bb0c7b | ||
|
|
aa141bf001 | ||
|
|
cf39e00553 | ||
|
|
27b47841be | ||
|
|
c2a49327a7 | ||
|
|
9bd7242376 | ||
|
|
fff085b63f | ||
|
|
5ad5b11ae1 | ||
|
|
c12fd2cb94 | ||
|
|
44d5d4a779 | ||
|
|
5a599233c9 | ||
|
|
596da353c2 | ||
|
|
68c87740aa | ||
|
|
55dc02c39f | ||
|
|
b1f8253105 | ||
|
|
e3cabade99 | ||
|
|
9402f9e0f7 | ||
|
|
4feaa470af | ||
|
|
4a9101f383 | ||
|
|
f91da5b950 | ||
|
|
66f654d4e2 | ||
|
|
7b9c0d91f6 | ||
|
|
53b51ae40e | ||
|
|
95b0f5c328 | ||
|
|
46c94e3729 | ||
|
|
4e01567816 | ||
|
|
f7f3104451 | ||
|
|
a5c80a4c75 | ||
|
|
417444d4b5 | ||
|
|
6fd26a3933 | ||
|
|
8ef9253999 | ||
|
|
360b80afab | ||
|
|
0ed0be089c | ||
|
|
8fb1043e96 | ||
|
|
fd041fbe80 | ||
|
|
5d73458f0b | ||
|
|
6c70d11f4e | ||
|
|
eadf96c879 | ||
|
|
0d770c89d6 | ||
|
|
0a635c1ece | ||
|
|
69a4199434 | ||
|
|
4bda5147f3 | ||
|
|
cbda7e2322 | ||
|
|
38c6569645 | ||
|
|
7c0eebe90a | ||
|
|
8784f2bce9 | ||
|
|
fbcac42ebd | ||
|
|
619302dc9a | ||
|
|
50d7a0f95e | ||
|
|
d7f13a82ef | ||
|
|
9e1038075e | ||
|
|
dd3604f523 | ||
|
|
65e9f607e5 | ||
|
|
a42134ccee | ||
|
|
71e038c81d | ||
|
|
2ff998da0e | ||
|
|
82e2c981da | ||
|
|
8422a41423 | ||
|
|
58ad1d9678 | ||
|
|
346c49832c | ||
|
|
f140651ff0 | ||
|
|
bb5b2a3300 | ||
|
|
5013d5dbef | ||
|
|
ba11851ac4 | ||
|
|
4fbce94999 | ||
|
|
486e406236 | ||
|
|
7d1b24f3b1 | ||
|
|
43ce0bef78 | ||
|
|
da51234d5a | ||
|
|
d9aa6ef6dc | ||
|
|
ff3ccff36a | ||
|
|
4b03ec7789 | ||
|
|
f41dc4a503 | ||
|
|
81c0d599c9 | ||
|
|
9e2bfa8169 | ||
|
|
44fa8bbde8 | ||
|
|
3ca9529c32 | ||
|
|
439b4dacf4 | ||
|
|
05f54860f7 | ||
|
|
021a9cce3d | ||
|
|
0f11a97c8e | ||
|
|
c9253ef64b | ||
|
|
af54a1696c | ||
|
|
4d821cb139 | ||
|
|
85fc95060f | ||
|
|
039b03255a | ||
|
|
e7efdede15 | ||
|
|
74155c8672 | ||
|
|
9c0e62ad44 | ||
|
|
94702d14b9 | ||
|
|
5aad44cff6 | ||
|
|
182469b346 | ||
|
|
0893d8511e | ||
|
|
e47398ecc5 | ||
|
|
9e884ccf1f | ||
|
|
fac0899ef7 | ||
|
|
d5c400e8d1 | ||
|
|
6648d68ddf | ||
|
|
982d6060a3 | ||
|
|
013f850c76 | ||
|
|
ef4508e52f | ||
|
|
6dae89ce0d | ||
|
|
f53350934f | ||
|
|
efaba02ef5 | ||
|
|
4ff909044e | ||
|
|
32682aa14d | ||
|
|
e9f3ca2a45 | ||
|
|
737aee7d98 | ||
|
|
bd20df1043 | ||
|
|
2ec2030ab2 | ||
|
|
129553da90 | ||
|
|
73e30df52b | ||
|
|
0a49274f9b |
@@ -11,17 +11,23 @@
|
||||
"slug": "latest",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "3.4",
|
||||
"branchName": "3.4.x",
|
||||
"slug": "3.4",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "3.3",
|
||||
"branchName": "3.3.x",
|
||||
"slug": "3.3",
|
||||
"upcoming": true
|
||||
"current": true
|
||||
},
|
||||
{
|
||||
"name": "3.2",
|
||||
"branchName": "3.2.x",
|
||||
"slug": "3.2",
|
||||
"current": true
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "3.1",
|
||||
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -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
|
||||
|
||||
37
.github/ISSUE_TEMPLATE/BC_Break.md
vendored
37
.github/ISSUE_TEMPLATE/BC_Break.md
vendored
@@ -1,37 +0,0 @@
|
||||
---
|
||||
name: 💥 BC Break
|
||||
about: Have you encountered an issue during upgrade? 💣
|
||||
---
|
||||
|
||||
<!--
|
||||
Before reporting a BC break, please consult the upgrading document to make sure it's not an expected change: https://github.com/doctrine/orm/blob/2.9.x/UPGRADE.md
|
||||
-->
|
||||
|
||||
### BC Break Report
|
||||
|
||||
<!-- Fill in the relevant information below to help triage your issue. -->
|
||||
|
||||
| Q | A
|
||||
|------------ | ------
|
||||
| BC Break | yes
|
||||
| Version | x.y.z
|
||||
|
||||
#### Summary
|
||||
|
||||
<!-- Provide a summary describing the problem you are experiencing. -->
|
||||
|
||||
#### Previous behavior
|
||||
|
||||
<!-- What was the previous (working) behavior? -->
|
||||
|
||||
#### Current behavior
|
||||
|
||||
<!-- What is the current (broken) behavior? -->
|
||||
|
||||
#### How to reproduce
|
||||
|
||||
<!--
|
||||
Provide steps to reproduce the BC break.
|
||||
If possible, also add a code snippet with relevant configuration, entity mappings, DQL etc.
|
||||
Adding a failing Unit or Functional Test would help us a lot - you can submit it in a Pull Request separately, referencing this bug report.
|
||||
-->
|
||||
34
.github/ISSUE_TEMPLATE/Bug.md
vendored
34
.github/ISSUE_TEMPLATE/Bug.md
vendored
@@ -1,34 +0,0 @@
|
||||
---
|
||||
name: 🐞 Bug Report
|
||||
about: Something is broken? 🔨
|
||||
---
|
||||
|
||||
### Bug Report
|
||||
|
||||
<!-- Fill in the relevant information below to help triage your issue. -->
|
||||
|
||||
| Q | A
|
||||
|------------ | ------
|
||||
| BC Break | yes/no
|
||||
| Version | x.y.z
|
||||
|
||||
#### Summary
|
||||
|
||||
<!-- Provide a summary describing the problem you are experiencing. -->
|
||||
|
||||
#### Current behavior
|
||||
|
||||
<!-- What is the current (buggy) behavior? -->
|
||||
|
||||
#### How to reproduce
|
||||
|
||||
<!--
|
||||
Provide steps to reproduce the bug.
|
||||
If possible, also add a code snippet with relevant configuration, entity mappings, DQL etc.
|
||||
Adding a failing Unit or Functional Test would help us a lot - you can submit one in a Pull Request separately, referencing this bug report.
|
||||
-->
|
||||
|
||||
#### Expected behavior
|
||||
|
||||
<!-- What was the expected (correct) behavior? -->
|
||||
|
||||
18
.github/ISSUE_TEMPLATE/Feature_Request.md
vendored
18
.github/ISSUE_TEMPLATE/Feature_Request.md
vendored
@@ -1,18 +0,0 @@
|
||||
---
|
||||
name: 🎉 Feature Request
|
||||
about: You have a neat idea that should be implemented? 🎩
|
||||
---
|
||||
|
||||
### Feature Request
|
||||
|
||||
<!-- Fill in the relevant information below to help triage your issue. -->
|
||||
|
||||
| Q | A
|
||||
|------------ | ------
|
||||
| New Feature | yes
|
||||
| RFC | yes/no
|
||||
| BC Break | yes/no
|
||||
|
||||
#### Summary
|
||||
|
||||
<!-- Provide a summary of the feature you would like to see implemented. -->
|
||||
6
.github/ISSUE_TEMPLATE/Support_Question.md
vendored
6
.github/ISSUE_TEMPLATE/Support_Question.md
vendored
@@ -1,6 +0,0 @@
|
||||
---
|
||||
name: ❓ Support Question
|
||||
about: Have a problem that you can't figure out? 🤔
|
||||
---
|
||||
|
||||
Please use https://github.com/doctrine/orm/discussions instead.
|
||||
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
@@ -6,4 +6,4 @@ updates:
|
||||
interval: "weekly"
|
||||
labels:
|
||||
- "CI"
|
||||
target-branch: "2.19.x"
|
||||
target-branch: "2.20.x"
|
||||
|
||||
2
.github/workflows/coding-standards.yml
vendored
2
.github/workflows/coding-standards.yml
vendored
@@ -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.2.1"
|
||||
|
||||
6
.github/workflows/continuous-integration.yml
vendored
6
.github/workflows/continuous-integration.yml
vendored
@@ -113,7 +113,7 @@ jobs:
|
||||
- "default"
|
||||
- "3.7"
|
||||
postgres-version:
|
||||
- "15"
|
||||
- "17"
|
||||
extension:
|
||||
- pdo_pgsql
|
||||
- pgsql
|
||||
@@ -323,6 +323,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"
|
||||
@@ -341,7 +343,7 @@ jobs:
|
||||
path: "reports"
|
||||
|
||||
- name: "Upload to Codecov"
|
||||
uses: "codecov/codecov-action@v4"
|
||||
uses: "codecov/codecov-action@v5"
|
||||
with:
|
||||
directory: reports
|
||||
env:
|
||||
|
||||
2
.github/workflows/documentation.yml
vendored
2
.github/workflows/documentation.yml
vendored
@@ -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.2.1"
|
||||
|
||||
@@ -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.2.1"
|
||||
secrets:
|
||||
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
|
||||
24
.github/workflows/stale.yml
vendored
Normal file
24
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: 'Close stale pull requests'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 3 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
with:
|
||||
stale-pr-message: >
|
||||
There hasn't been any activity on this pull request in the past 90 days, so
|
||||
it has been marked as stale and it will be closed automatically if no
|
||||
further activity occurs in the next 7 days.
|
||||
|
||||
If you want to continue working on it, please leave a comment.
|
||||
|
||||
close-pr-message: >
|
||||
This pull request was closed due to inactivity.
|
||||
|
||||
days-before-stale: -1
|
||||
days-before-pr-stale: 90
|
||||
days-before-pr-close: 7
|
||||
35
.github/workflows/static-analysis.yml
vendored
35
.github/workflows/static-analysis.yml
vendored
@@ -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:
|
||||
@@ -43,7 +41,7 @@ jobs:
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
coverage: none
|
||||
php-version: "8.3"
|
||||
php-version: "8.4"
|
||||
tools: cs2pr
|
||||
|
||||
- name: Require specific DBAL version
|
||||
@@ -56,34 +54,3 @@ jobs:
|
||||
|
||||
- name: Run static analysis with phpstan/phpstan
|
||||
run: "vendor/bin/phpstan analyse -c ${{ matrix.config }} --error-format=checkstyle | cs2pr"
|
||||
|
||||
static-analysis-psalm:
|
||||
name: Static Analysis with Psalm
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
dbal-version:
|
||||
- default
|
||||
- 3.8.2
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: "actions/checkout@v4"
|
||||
|
||||
- name: Install PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
coverage: none
|
||||
php-version: "8.3"
|
||||
tools: cs2pr
|
||||
|
||||
- name: Require specific DBAL version
|
||||
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
|
||||
if: "${{ matrix.dbal-version != 'default' }}"
|
||||
|
||||
- name: Install dependencies with Composer
|
||||
uses: ramsey/composer-install@v3
|
||||
|
||||
- name: Run static analysis with Vimeo Psalm
|
||||
run: vendor/bin/psalm --shepherd
|
||||
|
||||
21
.github/workflows/website-schema.yml
vendored
Normal file
21
.github/workflows/website-schema.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
name: "Website config validation"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*.x"
|
||||
paths:
|
||||
- ".doctrine-project.json"
|
||||
- ".github/workflows/website-schema.yml"
|
||||
push:
|
||||
branches:
|
||||
- "*.x"
|
||||
paths:
|
||||
- ".doctrine-project.json"
|
||||
- ".github/workflows/website-schema.yml"
|
||||
|
||||
jobs:
|
||||
json-validate:
|
||||
name: "Validate JSON schema"
|
||||
uses: "doctrine/.github/.github/workflows/website-schema.yml@7.1.0"
|
||||
24
README.md
24
README.md
@@ -1,9 +1,7 @@
|
||||
| [4.0.x][4.0] | [3.3.x][3.3] | [3.2.x][3.2] | [2.20.x][2.20] | [2.19.x][2.19] |
|
||||
| [4.0.x][4.0] | [3.4.x][3.4] | [3.3.x][3.3] | [2.21.x][2.21] | [2.20.x][2.20] |
|
||||
|:------------------------------------------------------:|:------------------------------------------------------:|:------------------------------------------------------:|:--------------------------------------------------------:|:--------------------------------------------------------:|
|
||||
| [![Build status][4.0 image]][4.0] | [![Build status][3.3 image]][3.3] | [![Build status][3.2 image]][3.2] | [![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.3 coverage image]][3.3 coverage] | [![Coverage Status][3.2 coverage image]][3.2 coverage] | [![Coverage Status][2.20 coverage image]][2.20 coverage] | [![Coverage Status][2.19 coverage image]][2.19 coverage] |
|
||||
|
||||
[<h1 align="center">🇺🇦 UKRAINE NEEDS YOUR HELP NOW!</h1>](https://www.doctrine-project.org/stop-war.html)
|
||||
| [![Build status][4.0 image]][4.0] | [![Build status][3.4 image]][3.4] | [![Build status][3.3 image]][3.3] | [![Build status][2.21 image]][2.21] | [![Build status][2.20 image]][2.20] |
|
||||
| [![Coverage Status][4.0 coverage image]][4.0 coverage] | [![Coverage Status][3.4 coverage image]][3.4 coverage] | [![Coverage Status][3.3 coverage image]][3.3 coverage] | [![Coverage Status][2.21 coverage image]][2.21 coverage] | [![Coverage Status][2.20 coverage image]][2.20 coverage] |
|
||||
|
||||
Doctrine ORM is an object-relational mapper for PHP 8.1+ that provides transparent persistence
|
||||
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
|
||||
@@ -22,19 +20,19 @@ without requiring unnecessary code duplication.
|
||||
[4.0]: https://github.com/doctrine/orm/tree/4.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.4 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.4.x
|
||||
[3.4]: https://github.com/doctrine/orm/tree/3.4.x
|
||||
[3.4 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.4.x/graph/badge.svg
|
||||
[3.4 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.4.x
|
||||
[3.3 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.3.x
|
||||
[3.3]: https://github.com/doctrine/orm/tree/3.3.x
|
||||
[3.3 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.3.x/graph/badge.svg
|
||||
[3.3 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.3.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
|
||||
[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 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 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
|
||||
|
||||
49
UPGRADE.md
49
UPGRADE.md
@@ -1,9 +1,24 @@
|
||||
# Upgrade to 3.4
|
||||
|
||||
Using the same class several times in a discriminator map is deprecated.
|
||||
In 4.0, this will be an error.
|
||||
|
||||
# Upgrade to 3.3
|
||||
|
||||
## Deprecate `DatabaseDriver`
|
||||
|
||||
The class `Doctrine\ORM\Mapping\Driver\DatabaseDriver` is deprecated without replacement.
|
||||
|
||||
## Add `Doctrine\ORM\Query\OutputWalker` interface, deprecate `Doctrine\ORM\Query\SqlWalker::getExecutor()`
|
||||
|
||||
Output walkers should implement the new `\Doctrine\ORM\Query\OutputWalker` interface and create
|
||||
`Doctrine\ORM\Query\Exec\SqlFinalizer` instances instead of `Doctrine\ORM\Query\Exec\AbstractSqlExecutor`s.
|
||||
The output walker must not base its workings on the query `firstResult`/`maxResult` values, so that the
|
||||
`SqlFinalizer` can be kept in the query cache and used regardless of the actual `firstResult`/`maxResult` values.
|
||||
Any operation dependent on `firstResult`/`maxResult` should take place within the `SqlFinalizer::createExecutor()`
|
||||
method. Details can be found at https://github.com/doctrine/orm/pull/11188.
|
||||
|
||||
|
||||
# Upgrade to 3.2
|
||||
|
||||
## Deprecate the `NotSupported` exception
|
||||
@@ -109,6 +124,36 @@ WARNING: This was relaxed in ORM 3.2 when partial was re-allowed for array-hydra
|
||||
`Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD` are removed.
|
||||
- `Doctrine\ORM\EntityManager*::getPartialReference()` is removed.
|
||||
|
||||
## BC BREAK: Enforce ArrayCollection Type on `\Doctrine\ORM\QueryBuilder::setParameters(ArrayCollection $parameters)`
|
||||
|
||||
The argument $parameters can no longer be a key=>value array. Only ArrayCollection types are allowed.
|
||||
|
||||
### Before
|
||||
|
||||
```php
|
||||
$qb = $em->createQueryBuilder()
|
||||
->select('u')
|
||||
->from('User', 'u')
|
||||
->where('u.id = :user_id1 OR u.id = :user_id2')
|
||||
->setParameter(array(
|
||||
'user_id1' => 1,
|
||||
'user_id2' => 2
|
||||
));
|
||||
```
|
||||
|
||||
### After
|
||||
|
||||
```php
|
||||
$qb = $em->createQueryBuilder()
|
||||
->select('u')
|
||||
->from('User', 'u')
|
||||
->where('u.id = :user_id1 OR u.id = :user_id2')
|
||||
->setParameter(new ArrayCollection(array(
|
||||
new Parameter('user_id1', 1),
|
||||
new Parameter('user_id2', 2)
|
||||
)));
|
||||
```
|
||||
|
||||
## BC BREAK: `Doctrine\ORM\Persister\Entity\EntityPersister::executeInserts()` return type changed to `void`
|
||||
|
||||
Implementors should adapt to the new signature, and should call
|
||||
@@ -737,7 +782,7 @@ Use `toIterable()` instead.
|
||||
|
||||
Output walkers should implement the new `\Doctrine\ORM\Query\OutputWalker` interface and create
|
||||
`Doctrine\ORM\Query\Exec\SqlFinalizer` instances instead of `Doctrine\ORM\Query\Exec\AbstractSqlExecutor`s.
|
||||
The output walker must not base its workings on the query `firstResult`/`maxResult` values, so that the
|
||||
The output walker must not base its workings on the query `firstResult`/`maxResult` values, so that the
|
||||
`SqlFinalizer` can be kept in the query cache and used regardless of the actual `firstResult`/`maxResult` values.
|
||||
Any operation dependent on `firstResult`/`maxResult` should take place within the `SqlFinalizer::createExecutor()`
|
||||
method. Details can be found at https://github.com/doctrine/orm/pull/11188.
|
||||
@@ -750,7 +795,7 @@ change in behavior.
|
||||
|
||||
Progress on this is tracked at https://github.com/doctrine/orm/issues/11624 .
|
||||
|
||||
## PARTIAL DQL syntax is undeprecated
|
||||
## PARTIAL DQL syntax is undeprecated
|
||||
|
||||
Use of the PARTIAL keyword is not deprecated anymore in DQL, because we will be
|
||||
able to support PARTIAL objects with PHP 8.4 Lazy Objects and
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
"doctrine/inflector": "^1.4 || ^2.0",
|
||||
"doctrine/instantiator": "^1.3 || ^2",
|
||||
"doctrine/lexer": "^3",
|
||||
"doctrine/persistence": "^3.3.1",
|
||||
"doctrine/persistence": "^3.3.1 || ^4",
|
||||
"psr/cache": "^1 || ^2 || ^3",
|
||||
"symfony/console": "^5.4 || ^6.0 || ^7.0",
|
||||
"symfony/var-exporter": "^6.3.9 || ^7.0"
|
||||
@@ -41,13 +41,12 @@
|
||||
"phpbench/phpbench": "^1.0",
|
||||
"phpdocumentor/guides-cli": "^1.4",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan": "1.12.6",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.2",
|
||||
"phpstan/phpstan": "2.0.3",
|
||||
"phpstan/phpstan-deprecation-rules": "^2",
|
||||
"phpunit/phpunit": "^10.4.0",
|
||||
"psr/log": "^1 || ^2 || ^3",
|
||||
"squizlabs/php_codesniffer": "3.7.2",
|
||||
"symfony/cache": "^5.4 || ^6.2 || ^7.0",
|
||||
"vimeo/psalm": "5.24.0"
|
||||
"symfony/cache": "^5.4 || ^6.2 || ^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "Provides support for XSD validation for XML mapping files",
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
#Copyright (c) 2010 Fabien Potencier
|
||||
#
|
||||
#Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
#of this software and associated documentation files (the "Software"), to deal
|
||||
#in the Software without restriction, including without limitation the rights
|
||||
#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
#copies of the Software, and to permit persons to whom the Software is furnished
|
||||
#to do so, subject to the following conditions:
|
||||
#
|
||||
#The above copyright notice and this permission notice shall be included in all
|
||||
#copies or substantial portions of the Software.
|
||||
#
|
||||
#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
#THE SOFTWARE.
|
||||
|
||||
from docutils.parsers.rst import Directive, directives
|
||||
from docutils import nodes
|
||||
from string import upper
|
||||
|
||||
class configurationblock(nodes.General, nodes.Element):
|
||||
pass
|
||||
|
||||
class ConfigurationBlock(Directive):
|
||||
has_content = True
|
||||
required_arguments = 0
|
||||
optional_arguments = 0
|
||||
final_argument_whitespace = True
|
||||
option_spec = {}
|
||||
formats = {
|
||||
'html': 'HTML',
|
||||
'xml': 'XML',
|
||||
'php': 'PHP',
|
||||
'jinja': 'Twig',
|
||||
'html+jinja': 'Twig',
|
||||
'jinja+html': 'Twig',
|
||||
'php+html': 'PHP',
|
||||
'html+php': 'PHP',
|
||||
'ini': 'INI',
|
||||
}
|
||||
|
||||
def run(self):
|
||||
env = self.state.document.settings.env
|
||||
|
||||
node = nodes.Element()
|
||||
node.document = self.state.document
|
||||
self.state.nested_parse(self.content, self.content_offset, node)
|
||||
|
||||
entries = []
|
||||
for i, child in enumerate(node):
|
||||
if isinstance(child, nodes.literal_block):
|
||||
# add a title (the language name) before each block
|
||||
#targetid = "configuration-block-%d" % env.new_serialno('configuration-block')
|
||||
#targetnode = nodes.target('', '', ids=[targetid])
|
||||
#targetnode.append(child)
|
||||
|
||||
innernode = nodes.emphasis(self.formats[child['language']], self.formats[child['language']])
|
||||
|
||||
para = nodes.paragraph()
|
||||
para += [innernode, child]
|
||||
|
||||
entry = nodes.list_item('')
|
||||
entry.append(para)
|
||||
entries.append(entry)
|
||||
|
||||
resultnode = configurationblock()
|
||||
resultnode.append(nodes.bullet_list('', *entries))
|
||||
|
||||
return [resultnode]
|
||||
|
||||
def visit_configurationblock_html(self, node):
|
||||
self.body.append(self.starttag(node, 'div', CLASS='configuration-block'))
|
||||
|
||||
def depart_configurationblock_html(self, node):
|
||||
self.body.append('</div>\n')
|
||||
|
||||
def visit_configurationblock_latex(self, node):
|
||||
pass
|
||||
|
||||
def depart_configurationblock_latex(self, node):
|
||||
pass
|
||||
|
||||
def setup(app):
|
||||
app.add_node(configurationblock,
|
||||
html=(visit_configurationblock_html, depart_configurationblock_html),
|
||||
latex=(visit_configurationblock_latex, depart_configurationblock_latex))
|
||||
app.add_directive('configuration-block', ConfigurationBlock)
|
||||
@@ -352,7 +352,7 @@ the database using a FOR UPDATE.
|
||||
use Bank\Entities\Account;
|
||||
use Doctrine\DBAL\LockMode;
|
||||
|
||||
$account = $em->find(Account::class, $accId, LockMode::PESSIMISTIC_READ);
|
||||
$account = $em->find(Account::class, $accId, LockMode::PESSIMISTIC_WRITE);
|
||||
|
||||
Keeping Updates and Deletes in Sync
|
||||
-----------------------------------
|
||||
|
||||
113
docs/en/make.bat
113
docs/en/make.bat
@@ -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
|
||||
@@ -33,14 +33,13 @@ Doctrine ORM is divided into four main packages.
|
||||
- ORM (depends on DBAL+Persistence+Collections)
|
||||
|
||||
This manual mainly covers the ORM package, sometimes touching parts
|
||||
of the underlying DBAL and Persistence packages. The Doctrine code base
|
||||
is split in to these packages for a few reasons and they are to...
|
||||
of the underlying DBAL and Persistence packages. The Doctrine codebase
|
||||
is split into these packages for a few reasons:
|
||||
|
||||
|
||||
- ...make things more maintainable and decoupled
|
||||
- ...allow you to use the code in Doctrine Persistence and Collections
|
||||
without the ORM or DBAL
|
||||
- ...allow you to use the DBAL without the ORM
|
||||
- to make things more maintainable and decoupled
|
||||
- to allow you to use the code in Doctrine Persistence and Collections without the ORM or DBAL
|
||||
- to allow you to use the DBAL without the ORM
|
||||
|
||||
Collection, Event Manager and Persistence
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -903,8 +903,7 @@ defaults to "id", just as in one-to-one or many-to-one mappings.
|
||||
|
||||
Additionally, when using typed properties with Doctrine 2.9 or newer
|
||||
you can skip ``targetEntity`` in ``ManyToOne`` and ``OneToOne``
|
||||
associations as they will be set based on type. Also ``nullable``
|
||||
attribute on ``JoinColumn`` will be inherited from PHP type. So that:
|
||||
associations as they will be set based on type. So that:
|
||||
|
||||
.. configuration-block::
|
||||
|
||||
@@ -931,7 +930,7 @@ Is essentially the same as following:
|
||||
<?php
|
||||
/** One Product has One Shipment. */
|
||||
#[OneToOne(targetEntity: Shipment::class)]
|
||||
#[JoinColumn(name: 'shipment_id', referencedColumnName: 'id', nullable: false)]
|
||||
#[JoinColumn(name: 'shipment_id', referencedColumnName: 'id')]
|
||||
private Shipment $shipment;
|
||||
|
||||
.. code-block:: annotation
|
||||
@@ -940,7 +939,7 @@ Is essentially the same as following:
|
||||
/**
|
||||
* One Product has One Shipment.
|
||||
* @OneToOne(targetEntity="Shipment")
|
||||
* @JoinColumn(name="shipment_id", referencedColumnName="id", nullable=false)
|
||||
* @JoinColumn(name="shipment_id", referencedColumnName="id")
|
||||
*/
|
||||
private Shipment $shipment;
|
||||
|
||||
|
||||
@@ -167,6 +167,7 @@ Here is a complete list of ``Column``s attributes (all optional):
|
||||
- ``nullable`` (default: ``false``): Whether the column is nullable.
|
||||
- ``insertable`` (default: ``true``): Whether the column should be inserted.
|
||||
- ``updatable`` (default: ``true``): Whether the column should be updated.
|
||||
- ``generated`` (default: ``null``): Whether the generated strategy should be ``'NEVER'``, ``'INSERT'`` and ``ALWAYS``.
|
||||
- ``enumType`` (requires PHP 8.1 and ``doctrine/orm`` 2.11): The PHP enum class name to convert the database value into.
|
||||
- ``precision`` (default: 0): The precision for a decimal (exact numeric) column
|
||||
(applies only for decimal column),
|
||||
|
||||
@@ -16,7 +16,7 @@ is common to multiple entity classes.
|
||||
Mapped superclasses, just as regular, non-mapped classes, can
|
||||
appear in the middle of an otherwise mapped inheritance hierarchy
|
||||
(through Single Table Inheritance or Class Table Inheritance). They
|
||||
are not query-able, and need not have an ``#[Id]`` property.
|
||||
are not query-able, and do not require an ``#[Id]`` property.
|
||||
|
||||
No database table will be created for a mapped superclass itself,
|
||||
only for entity classes inheriting from it. That implies that a
|
||||
|
||||
@@ -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?".
|
||||
|
||||
|
||||
@@ -166,7 +166,7 @@ your code. See the following code:
|
||||
|
||||
Traversing the object graph for parts that are lazy-loaded will
|
||||
easily trigger lots of SQL queries and will perform badly if used
|
||||
to heavily. Make sure to use DQL to fetch-join all the parts of the
|
||||
too heavily. Make sure to use DQL to fetch-join all the parts of the
|
||||
object-graph that you need as efficiently as possible.
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,9 @@ can be called without triggering a full load of the collection:
|
||||
- ``Collection#contains($entity)``
|
||||
- ``Collection#containsKey($key)``
|
||||
- ``Collection#count()``
|
||||
- ``Collection#first()``
|
||||
- ``Collection#get($key)``
|
||||
- ``Collection#isEmpty()``
|
||||
- ``Collection#slice($offset, $length = null)``
|
||||
|
||||
For each of the above methods the following semantics apply:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -29,83 +29,11 @@ You can map indexed associations by adding:
|
||||
The code and mappings for the Market entity looks like this:
|
||||
|
||||
.. configuration-block::
|
||||
.. code-block:: attribute
|
||||
.. literalinclude:: working-with-indexed-associations/Market.php
|
||||
:language: attribute
|
||||
|
||||
<?php
|
||||
namespace Doctrine\Tests\Models\StockExchange;
|
||||
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
|
||||
#[Entity]
|
||||
#[Table(name: 'exchange_markets')]
|
||||
class Market
|
||||
{
|
||||
#[Id, Column(type: 'integer'), GeneratedValue]
|
||||
private int|null $id = null;
|
||||
|
||||
#[Column(type: 'string')]
|
||||
private string $name;
|
||||
|
||||
/** @var Collection<string, Stock> */
|
||||
#[OneToMany(targetEntity: Stock::class, mappedBy: 'market', indexBy: 'symbol')]
|
||||
private Collection $stocks;
|
||||
|
||||
public function __construct(string $name)
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->stocks = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): int|null
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function addStock(Stock $stock): void
|
||||
{
|
||||
$this->stocks[$stock->getSymbol()] = $stock;
|
||||
}
|
||||
|
||||
public function getStock(string $symbol): Stock
|
||||
{
|
||||
if (!isset($this->stocks[$symbol])) {
|
||||
throw new \InvalidArgumentException("Symbol is not traded on this market.");
|
||||
}
|
||||
|
||||
return $this->stocks[$symbol];
|
||||
}
|
||||
|
||||
/** @return array<string, Stock> */
|
||||
public function getStocks(): array
|
||||
{
|
||||
return $this->stocks->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
.. code-block:: xml
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
|
||||
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
|
||||
|
||||
<entity name="Doctrine\Tests\Models\StockExchange\Market">
|
||||
<id name="id" type="integer">
|
||||
<generator strategy="AUTO" />
|
||||
</id>
|
||||
|
||||
<field name="name" type="string"/>
|
||||
|
||||
<one-to-many target-entity="Stock" mapped-by="market" field="stocks" index-by="symbol" />
|
||||
</entity>
|
||||
</doctrine-mapping>
|
||||
.. literalinclude:: working-with-indexed-associations/market.xml
|
||||
:language: xml
|
||||
|
||||
Inside the ``addStock()`` method you can see how we directly set the key of the association to the symbol,
|
||||
so that we can work with the indexed association directly after invoking ``addStock()``. Inside ``getStock($symbol)``
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?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>
|
||||
@@ -321,7 +321,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>
|
||||
|
||||
@@ -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"/>
|
||||
@@ -48,6 +50,8 @@
|
||||
</rule>
|
||||
|
||||
<rule ref="PSR1.Classes.ClassDeclaration.MultipleClasses">
|
||||
<exclude-pattern>src/Mapping/Driver/LoadMappingFileImplementation.php</exclude-pattern>
|
||||
<exclude-pattern>src/Mapping/GetReflectionClassImplementation.php</exclude-pattern>
|
||||
<exclude-pattern>tests/*</exclude-pattern>
|
||||
</rule>
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@ includes:
|
||||
- phpstan-params.neon
|
||||
|
||||
parameters:
|
||||
reportUnmatchedIgnoredErrors: false # Some errors in the baseline only apply to DBAL 4
|
||||
ignoreErrors:
|
||||
# Symfony cache supports passing a key prefix to the clear method.
|
||||
- '/^Method Psr\\Cache\\CacheItemPoolInterface\:\:clear\(\) invoked with 1 parameter, 0 required\.$/'
|
||||
@@ -16,9 +17,10 @@ parameters:
|
||||
-
|
||||
message: '~^Method Doctrine\\ORM\\Query\\AST\\Functions\\TrimFunction::getTrimMode\(\) never returns .* so it can be removed from the return type\.$~'
|
||||
path: src/Query/AST/Functions/TrimFunction.php
|
||||
|
||||
-
|
||||
message: '~^Method Doctrine\\ORM\\Persisters\\Entity\\BasicEntityPersister\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~'
|
||||
path: src/Persisters/Entity/BasicEntityPersister.php
|
||||
message: '~.*getTrimExpression.*expects int.*~'
|
||||
path: src/Query/AST/Functions/TrimFunction.php
|
||||
|
||||
- '~^Class Doctrine\\DBAL\\Platforms\\SQLitePlatform not found\.$~'
|
||||
|
||||
@@ -34,3 +36,42 @@ parameters:
|
||||
-
|
||||
message: '~deprecated class Doctrine\\DBAL\\Tools\\Console\\Command\\ReservedWordsCommand\:~'
|
||||
path: src/Tools/Console/ConsoleRunner.php
|
||||
|
||||
# Compatibility with Persistence 3
|
||||
-
|
||||
message: '#Expression on left side of \?\? is not nullable.#'
|
||||
path: src/Mapping/Driver/AttributeDriver.php
|
||||
|
||||
-
|
||||
message: '~^Method Doctrine\\ORM\\Persisters\\Entity\\BasicEntityPersister\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~'
|
||||
path: src/Persisters/Entity/BasicEntityPersister.php
|
||||
|
||||
-
|
||||
message: '~getTypes.*should return~'
|
||||
path: src/Persisters/Entity/BasicEntityPersister.php
|
||||
|
||||
-
|
||||
message: '~.*appendLockHint.*expects.*LockMode given~'
|
||||
paths:
|
||||
- src/Persisters/Entity/BasicEntityPersister.php
|
||||
- src/Persisters/Entity/JoinedSubclassPersister.php
|
||||
|
||||
-
|
||||
message: '~.*executeStatement.*expects~'
|
||||
path: src/Query/Exec/MultiTableUpdateExecutor.php
|
||||
|
||||
-
|
||||
message: '~method_exists.*getEventManager~'
|
||||
path: src/EntityManager.php
|
||||
|
||||
-
|
||||
message: '~method_exists.*getIdentitySequence~'
|
||||
path: src/Mapping/ClassMetadataFactory.php
|
||||
|
||||
-
|
||||
message: '~expand(Criteria)?Parameters.*should return array~'
|
||||
path: src/Persisters/Entity/BasicEntityPersister.php
|
||||
|
||||
-
|
||||
message: '~inferType.*never returns~'
|
||||
path: src/Query/ParameterTypeInferer.php
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
parameters:
|
||||
level: 5
|
||||
level: 7
|
||||
paths:
|
||||
- src
|
||||
- tests/StaticAnalysis
|
||||
@@ -8,4 +8,4 @@ parameters:
|
||||
earlyTerminatingMethodCalls:
|
||||
Doctrine\ORM\Query\Parser:
|
||||
- syntaxError
|
||||
phpVersion: 80200
|
||||
phpVersion: 80400
|
||||
|
||||
@@ -45,3 +45,8 @@ parameters:
|
||||
message: '#Negated boolean expression is always false\.#'
|
||||
paths:
|
||||
- src/Mapping/Driver/AttributeDriver.php
|
||||
|
||||
# Compatibility with Persistence 3
|
||||
-
|
||||
message: '#Expression on left side of \?\? is not nullable.#'
|
||||
path: src/Mapping/Driver/AttributeDriver.php
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
colors="true"
|
||||
displayDetailsOnTestsThatTriggerDeprecations="true"
|
||||
displayDetailsOnTestsThatTriggerNotices="true"
|
||||
displayDetailsOnTestsThatTriggerWarnings="true"
|
||||
failOnNotice="true"
|
||||
@@ -67,5 +68,12 @@
|
||||
<var name="privileged_db_port" value="3306"/>
|
||||
-->
|
||||
<env name="COLUMNS" value="120"/>
|
||||
<env name="DOCTRINE_DEPRECATIONS" value="trigger"/>
|
||||
</php>
|
||||
|
||||
<source ignoreSuppressionOfDeprecations="true">
|
||||
<include>
|
||||
<directory>src</directory>
|
||||
</include>
|
||||
</source>
|
||||
</phpunit>
|
||||
|
||||
1233
psalm-baseline.xml
1233
psalm-baseline.xml
File diff suppressed because it is too large
Load Diff
245
psalm.xml
245
psalm.xml
@@ -1,245 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<psalm
|
||||
errorLevel="2"
|
||||
phpVersion="8.2"
|
||||
resolveFromConfigFile="true"
|
||||
findUnusedBaselineEntry="true"
|
||||
findUnusedCode="false"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="https://getpsalm.org/schema/config"
|
||||
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
|
||||
errorBaseline="psalm-baseline.xml"
|
||||
>
|
||||
<projectFiles>
|
||||
<directory name="src" />
|
||||
<directory name="tests/StaticAnalysis" />
|
||||
<ignoreFiles>
|
||||
<directory name="vendor" />
|
||||
<file name="src/Mapping/Driver/AttributeReader.php" />
|
||||
</ignoreFiles>
|
||||
</projectFiles>
|
||||
<enableExtensions>
|
||||
<extension name="simplexml" />
|
||||
</enableExtensions>
|
||||
<issueHandlers>
|
||||
<DeprecatedClass>
|
||||
<errorLevel type="suppress">
|
||||
<!-- We wire the command as long as DBAL ships it -->
|
||||
<referencedClass name="Doctrine\DBAL\Tools\Console\Command\ReservedWordsCommand" />
|
||||
<!-- Remove on 3.0.x -->
|
||||
<referencedClass name="Doctrine\ORM\Event\LifecycleEventArgs"/>
|
||||
<referencedClass name="Doctrine\ORM\Exception\UnknownEntityNamespace"/>
|
||||
<referencedClass name="Doctrine\ORM\Mapping\Driver\AnnotationDriver"/>
|
||||
<referencedClass name="Doctrine\ORM\Mapping\Driver\YamlDriver"/>
|
||||
<referencedClass name="Doctrine\ORM\Mapping\NamedNativeQueries"/>
|
||||
<referencedClass name="Doctrine\ORM\Mapping\NamedNativeQuery"/>
|
||||
<referencedClass name="Doctrine\ORM\Mapping\NamedQueries"/>
|
||||
<referencedClass name="Doctrine\ORM\Mapping\NamedQuery"/>
|
||||
<referencedClass name="Doctrine\ORM\Query\AST\InExpression"/>
|
||||
<referencedClass name="Doctrine\ORM\Tools\Console\Command\ConvertDoctrine1SchemaCommand"/>
|
||||
<referencedClass name="Doctrine\ORM\Tools\Console\Command\ConvertMappingCommand"/>
|
||||
<referencedClass name="Doctrine\ORM\Tools\Console\Command\EnsureProductionSettingsCommand"/>
|
||||
<referencedClass name="Doctrine\ORM\Tools\Console\Command\GenerateEntitiesCommand"/>
|
||||
<referencedClass name="Doctrine\ORM\Tools\Console\Command\GenerateRepositoriesCommand"/>
|
||||
<referencedClass name="Doctrine\ORM\Tools\Console\Helper\EntityManagerHelper"/>
|
||||
<referencedClass name="Doctrine\ORM\Tools\Console\EntityManagerProvider\HelperSetManagerProvider"/>
|
||||
</errorLevel>
|
||||
</DeprecatedClass>
|
||||
<DeprecatedMethod>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Remove on 3.0.x -->
|
||||
<!-- Compatibility with DBAL 3 -->
|
||||
<referencedMethod name="Doctrine\DBAL\Connection::getEventManager"/>
|
||||
<file name="src/Query/TreeWalkerChain.php"/>
|
||||
</errorLevel>
|
||||
</DeprecatedMethod>
|
||||
<DocblockTypeContradiction>
|
||||
<errorLevel type="suppress">
|
||||
<!-- We're catching invalid input here. -->
|
||||
<file name="src/Internal/Hydration/AbstractHydrator.php"/>
|
||||
|
||||
<!-- DBAL 3.2 forward compatibility -->
|
||||
<file name="src/Tools/Pagination/CountOutputWalker.php"/>
|
||||
<file name="src/Tools/Pagination/LimitSubqueryOutputWalker.php"/>
|
||||
<!-- https://github.com/vimeo/psalm/issues/8520 -->
|
||||
<file name="src/PersistentCollection.php"/>
|
||||
<!-- Remove on 4.0.x -->
|
||||
<file name="src/Mapping/Driver/AttributeDriver.php"/>
|
||||
<file name="src/Mapping/Driver/XmlDriver.php"/>
|
||||
<file name="src/ORMSetup.php"/>
|
||||
</errorLevel>
|
||||
</DocblockTypeContradiction>
|
||||
<ForbiddenCode>
|
||||
<errorLevel type="suppress">
|
||||
<file name="src/Tools/Debug.php"/>
|
||||
</errorLevel>
|
||||
</ForbiddenCode>
|
||||
<InvalidArgument>
|
||||
<errorLevel type="suppress">
|
||||
<referencedFunction name="Doctrine\ORM\Mapping\ClassMetadata::addInheritedAssociationMapping"/>
|
||||
</errorLevel>
|
||||
</InvalidArgument>
|
||||
<InvalidArrayAccess>
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/9160 -->
|
||||
<file name="src/Mapping/ClassMetadataFactory.php"/>
|
||||
</errorLevel>
|
||||
</InvalidArrayAccess>
|
||||
<InvalidArrayAssignment>
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/9160 -->
|
||||
<file name="src/Mapping/ClassMetadataFactory.php"/>
|
||||
</errorLevel>
|
||||
</InvalidArrayAssignment>
|
||||
<LessSpecificReturnStatement>
|
||||
<errorLevel type="suppress">
|
||||
<!-- In DBAL 4, column precision is nullable. See https://github.com/doctrine/dbal/pull/3511 -->
|
||||
<file name="src/Mapping/Driver/DatabaseDriver.php"/>
|
||||
</errorLevel>
|
||||
</LessSpecificReturnStatement>
|
||||
<MoreSpecificReturnType>
|
||||
<errorLevel type="suppress">
|
||||
<!-- In DBAL 4, the default column value is mixed. See https://github.com/doctrine/dbal/pull/3511 -->
|
||||
<file name="src/Mapping/Driver/DatabaseDriver.php"/>
|
||||
</errorLevel>
|
||||
</MoreSpecificReturnType>
|
||||
<InvalidReturnType>
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/8819 -->
|
||||
<file name="src/Internal/Hydration/AbstractHydrator.php"/>
|
||||
</errorLevel>
|
||||
</InvalidReturnType>
|
||||
<InvalidParamDefault>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Remove on 3.0.x -->
|
||||
<file name="src/Query/AST/InstanceOfExpression.php"/>
|
||||
</errorLevel>
|
||||
</InvalidParamDefault>
|
||||
<InvalidPropertyAssignmentValue>
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/9155 -->
|
||||
<file name="src/Mapping/ClassMetadataFactory.php"/>
|
||||
</errorLevel>
|
||||
</InvalidPropertyAssignmentValue>
|
||||
<MethodSignatureMismatch>
|
||||
<errorLevel type="suppress">
|
||||
<!-- See https://github.com/vimeo/psalm/issues/7357 -->
|
||||
<file name="src/Mapping/ReflectionReadonlyProperty.php"/>
|
||||
</errorLevel>
|
||||
</MethodSignatureMismatch>
|
||||
<MissingParamType>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Persistence 2 compatibility -->
|
||||
<file name="src/EntityManager.php"/>
|
||||
<file name="src/Mapping/ClassMetadataFactory.php"/>
|
||||
<file name="src/Mapping/ClassMetadata.php"/>
|
||||
</errorLevel>
|
||||
</MissingParamType>
|
||||
<PossiblyInvalidArgument>
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/9155 -->
|
||||
<file name="src/Mapping/ClassMetadataFactory.php"/>
|
||||
</errorLevel>
|
||||
</PossiblyInvalidArgument>
|
||||
<PossiblyNullArrayOffset>
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/7878 -->
|
||||
<file name="src/Persisters/Collection/ManyToManyPersister.php"/>
|
||||
</errorLevel>
|
||||
</PossiblyNullArrayOffset>
|
||||
<PropertyNotSetInConstructor>
|
||||
<errorLevel type="suppress">
|
||||
<directory name="src/Query/AST" />
|
||||
</errorLevel>
|
||||
</PropertyNotSetInConstructor>
|
||||
<PropertyTypeCoercion>
|
||||
<errorLevel type="suppress">
|
||||
<file name="src/Mapping/ClassMetadata.php"/>
|
||||
</errorLevel>
|
||||
</PropertyTypeCoercion>
|
||||
<RedundantCastGivenDocblockType>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Can be removed once the "getMaxResults" methods of those classes have native parameter types -->
|
||||
<file name="src/Query.php"/>
|
||||
<file name="src/QueryBuilder.php"/>
|
||||
</errorLevel>
|
||||
</RedundantCastGivenDocblockType>
|
||||
<ReferenceConstraintViolation>
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/9155 -->
|
||||
<file name="src/Mapping/ClassMetadataFactory.php"/>
|
||||
</errorLevel>
|
||||
</ReferenceConstraintViolation>
|
||||
<RiskyTruthyFalsyComparison>
|
||||
<!-- TODO: Enable this new rule on higher branches. -->
|
||||
<errorLevel type="suppress">
|
||||
<directory name="src" />
|
||||
</errorLevel>
|
||||
</RiskyTruthyFalsyComparison>
|
||||
<TooManyArguments>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Symfony cache supports passing a key prefix to the clear method. -->
|
||||
<referencedFunction name="Psr\Cache\CacheItemPoolInterface::clear"/>
|
||||
|
||||
<!-- Persistence 2 compatibility -->
|
||||
<referencedFunction name="Doctrine\Persistence\ObjectManager::clear"/>
|
||||
|
||||
<!-- See https://github.com/doctrine/orm/issues/8850 -->
|
||||
<referencedFunction name="Doctrine\DBAL\Connection::lastInsertId"/>
|
||||
|
||||
<!-- FIXME -->
|
||||
<referencedFunction name="Doctrine\DBAL\DriverManager::getConnection"/>
|
||||
</errorLevel>
|
||||
</TooManyArguments>
|
||||
<TypeDoesNotContainNull>
|
||||
<errorLevel type="suppress">
|
||||
<!-- DBAL 3 compatibility -->
|
||||
<file name="src/Tools/SchemaTool.php"/>
|
||||
</errorLevel>
|
||||
</TypeDoesNotContainNull>
|
||||
<TypeDoesNotContainType>
|
||||
<errorLevel type="suppress">
|
||||
<file name="src/Internal/SQLResultCasing.php"/>
|
||||
<file name="src/Mapping/ClassMetadataFactory.php"/>
|
||||
<!-- DBAL 3 compatibility -->
|
||||
<file name="src/UnitOfWork.php"/>
|
||||
<file name="src/Utility/LockSqlHelper.php"/>
|
||||
</errorLevel>
|
||||
</TypeDoesNotContainType>
|
||||
<UndefinedClass>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Compatibility with DBAL 3 -->
|
||||
<referencedClass name="Doctrine\DBAL\Platforms\SQLitePlatform"/>
|
||||
</errorLevel>
|
||||
</UndefinedClass>
|
||||
<UndefinedMethod>
|
||||
<errorLevel type="suppress">
|
||||
<!-- Compatibility with DBAL 3 -->
|
||||
<referencedMethod name="Doctrine\DBAL\Connection::getEventManager"/>
|
||||
<!-- FIXME -->
|
||||
<referencedMethod name="Doctrine\DBAL\Schema\SchemaDiff::toSaveSql"/>
|
||||
</errorLevel>
|
||||
</UndefinedMethod>
|
||||
<UndefinedPropertyFetch>
|
||||
<errorLevel type="suppress">
|
||||
<!-- https://github.com/vimeo/psalm/issues/7878 -->
|
||||
<file name="src/Persisters/Collection/ManyToManyPersister.php"/>
|
||||
<file name="src/PersistentCollection.php"/>
|
||||
<file name="src/Utility/PersisterHelper.php"/>
|
||||
<file name="src/Tools/SchemaValidator.php"/>
|
||||
</errorLevel>
|
||||
</UndefinedPropertyFetch>
|
||||
<UnhandledMatchCondition>
|
||||
<errorLevel type="suppress">
|
||||
<!-- We can be certain that those values are not matched. -->
|
||||
<file name="src/Persisters/Entity/BasicEntityPersister.php"/>
|
||||
</errorLevel>
|
||||
</UnhandledMatchCondition>
|
||||
<ArgumentTypeCoercion>
|
||||
<errorLevel type="suppress">
|
||||
<!-- See https://github.com/JetBrains/phpstorm-stubs/pull/1383 -->
|
||||
<file name="src/Mapping/ClassMetadata.php"/>
|
||||
</errorLevel>
|
||||
</ArgumentTypeCoercion>
|
||||
</issueHandlers>
|
||||
</psalm>
|
||||
@@ -83,7 +83,7 @@ abstract class AbstractQuery
|
||||
* The parameter map of this query.
|
||||
*
|
||||
* @var ArrayCollection|Parameter[]
|
||||
* @psalm-var ArrayCollection<int, Parameter>
|
||||
* @phpstan-var ArrayCollection<int, Parameter>
|
||||
*/
|
||||
protected ArrayCollection $parameters;
|
||||
|
||||
@@ -95,14 +95,14 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* The map of query hints.
|
||||
*
|
||||
* @psalm-var array<string, mixed>
|
||||
* @phpstan-var array<string, mixed>
|
||||
*/
|
||||
protected array $hints = [];
|
||||
|
||||
/**
|
||||
* The hydration mode.
|
||||
*
|
||||
* @psalm-var string|AbstractQuery::HYDRATE_*
|
||||
* @phpstan-var string|AbstractQuery::HYDRATE_*
|
||||
*/
|
||||
protected string|int $hydrationMode = self::HYDRATE_OBJECT;
|
||||
|
||||
@@ -130,7 +130,7 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* Second level query cache mode.
|
||||
*
|
||||
* @psalm-var Cache::MODE_*|null
|
||||
* @phpstan-var Cache::MODE_*|null
|
||||
*/
|
||||
protected int|null $cacheMode = null;
|
||||
|
||||
@@ -217,14 +217,14 @@ abstract class AbstractQuery
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @psalm-return Cache::MODE_*|null */
|
||||
/** @phpstan-return Cache::MODE_*|null */
|
||||
public function getCacheMode(): int|null
|
||||
{
|
||||
return $this->cacheMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param Cache::MODE_* $cacheMode
|
||||
* @phpstan-param Cache::MODE_* $cacheMode
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -267,7 +267,7 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* Get all defined parameters.
|
||||
*
|
||||
* @psalm-return ArrayCollection<int, Parameter>
|
||||
* @phpstan-return ArrayCollection<int, Parameter>
|
||||
*/
|
||||
public function getParameters(): ArrayCollection
|
||||
{
|
||||
@@ -296,14 +296,14 @@ abstract class AbstractQuery
|
||||
* Sets a collection of query parameters.
|
||||
*
|
||||
* @param ArrayCollection|mixed[] $parameters
|
||||
* @psalm-param ArrayCollection<int, Parameter>|mixed[] $parameters
|
||||
* @phpstan-param ArrayCollection<int, Parameter>|mixed[] $parameters
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParameters(ArrayCollection|array $parameters): static
|
||||
{
|
||||
if (is_array($parameters)) {
|
||||
/** @psalm-var ArrayCollection<int, Parameter> $parameterCollection */
|
||||
/** @phpstan-var ArrayCollection<int, Parameter> $parameterCollection */
|
||||
$parameterCollection = new ArrayCollection();
|
||||
|
||||
foreach ($parameters as $key => $value) {
|
||||
@@ -642,7 +642,7 @@ abstract class AbstractQuery
|
||||
* Change the default fetch mode of an association for this query.
|
||||
*
|
||||
* @param class-string $class
|
||||
* @psalm-param Mapping\ClassMetadata::FETCH_EAGER|Mapping\ClassMetadata::FETCH_LAZY $fetchMode
|
||||
* @phpstan-param Mapping\ClassMetadata::FETCH_EAGER|Mapping\ClassMetadata::FETCH_LAZY $fetchMode
|
||||
*/
|
||||
public function setFetchMode(string $class, string $assocName, int $fetchMode): static
|
||||
{
|
||||
@@ -656,7 +656,7 @@ abstract class AbstractQuery
|
||||
*
|
||||
* @param string|int $hydrationMode Doctrine processing mode to be used during hydration process.
|
||||
* One of the Query::HYDRATE_* constants.
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_* $hydrationMode
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -670,7 +670,7 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* Gets the hydration mode currently used by the query.
|
||||
*
|
||||
* @psalm-return string|AbstractQuery::HYDRATE_*
|
||||
* @phpstan-return string|AbstractQuery::HYDRATE_*
|
||||
*/
|
||||
public function getHydrationMode(): string|int
|
||||
{
|
||||
@@ -682,7 +682,7 @@ abstract class AbstractQuery
|
||||
*
|
||||
* Alias for execute(null, $hydrationMode = HYDRATE_OBJECT).
|
||||
*
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_* $hydrationMode
|
||||
*/
|
||||
public function getResult(string|int $hydrationMode = self::HYDRATE_OBJECT): mixed
|
||||
{
|
||||
@@ -728,7 +728,7 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* Get exactly one result or null.
|
||||
*
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
*
|
||||
* @throws NonUniqueResultException
|
||||
*/
|
||||
@@ -763,7 +763,7 @@ abstract class AbstractQuery
|
||||
* If the result is not unique, a NonUniqueResultException is thrown.
|
||||
* If there is no result, a NoResultException is thrown.
|
||||
*
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
*
|
||||
* @throws NonUniqueResultException If the query result is not unique.
|
||||
* @throws NoResultException If the query returned no result.
|
||||
@@ -843,8 +843,8 @@ abstract class AbstractQuery
|
||||
* Executes the query and returns an iterable that can be used to incrementally
|
||||
* iterate over the result.
|
||||
*
|
||||
* @psalm-param ArrayCollection<int, Parameter>|mixed[] $parameters
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
* @phpstan-param ArrayCollection<int, Parameter>|mixed[] $parameters
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
*
|
||||
* @return iterable<mixed>
|
||||
*/
|
||||
@@ -877,8 +877,8 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* Executes the query.
|
||||
*
|
||||
* @psalm-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
* @phpstan-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
*/
|
||||
public function execute(
|
||||
ArrayCollection|array|null $parameters = null,
|
||||
@@ -894,8 +894,8 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* Execute query ignoring second level cache.
|
||||
*
|
||||
* @psalm-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
* @phpstan-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
*/
|
||||
private function executeIgnoreQueryCache(
|
||||
ArrayCollection|array|null $parameters = null,
|
||||
@@ -965,8 +965,8 @@ abstract class AbstractQuery
|
||||
/**
|
||||
* Load from second level cache or executes the query and put into cache.
|
||||
*
|
||||
* @psalm-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
* @phpstan-param ArrayCollection<int, Parameter>|mixed[]|null $parameters
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_*|null $hydrationMode
|
||||
*/
|
||||
private function executeUsingQueryCache(
|
||||
ArrayCollection|array|null $parameters = null,
|
||||
@@ -1029,7 +1029,7 @@ abstract class AbstractQuery
|
||||
* automatically generated for you.
|
||||
*
|
||||
* @return string[] ($key, $hash)
|
||||
* @psalm-return array{string, string} ($key, $hash)
|
||||
* @phpstan-return array{string, string} ($key, $hash)
|
||||
*/
|
||||
protected function getHydrationCacheId(): array
|
||||
{
|
||||
|
||||
@@ -29,11 +29,14 @@ class CollectionCacheKey extends CacheKey
|
||||
public readonly string $entityClass,
|
||||
public readonly string $association,
|
||||
array $ownerIdentifier,
|
||||
string $filterHash = '',
|
||||
) {
|
||||
ksort($ownerIdentifier);
|
||||
|
||||
$this->ownerIdentifier = $ownerIdentifier;
|
||||
|
||||
parent::__construct(str_replace('\\', '.', strtolower($entityClass)) . '_' . implode(' ', $ownerIdentifier) . '__' . $association);
|
||||
$filterHash = $filterHash === '' ? '' : '_' . $filterHash;
|
||||
|
||||
parent::__construct(str_replace('\\', '.', strtolower($entityClass)) . '_' . implode(' ', $ownerIdentifier) . '__' . $association . $filterHash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class DefaultCache implements Cache
|
||||
|
||||
/**
|
||||
* @var QueryCache[]
|
||||
* @psalm-var array<string, QueryCache>
|
||||
* @phpstan-var array<string, QueryCache>
|
||||
*/
|
||||
private array $queryCaches = [];
|
||||
|
||||
|
||||
@@ -231,7 +231,6 @@ class DefaultQueryCache implements QueryCache
|
||||
$region = $persister->getCacheRegion();
|
||||
|
||||
$cm = $this->em->getClassMetadata($entityName);
|
||||
assert($cm instanceof ClassMetadata);
|
||||
|
||||
foreach ($result as $index => $entity) {
|
||||
$identifier = $this->uow->getEntityIdentifier($entity);
|
||||
@@ -297,7 +296,7 @@ class DefaultQueryCache implements QueryCache
|
||||
|
||||
/**
|
||||
* @return mixed[]|null
|
||||
* @psalm-return array{targetEntity: class-string, type: mixed, list?: array[], identifier?: array}|null
|
||||
* @phpstan-return array{targetEntity: class-string, type: mixed, list?: array[], identifier?: array}|null
|
||||
*/
|
||||
private function storeAssociationCache(QueryCacheKey $key, AssociationMapping $assoc, mixed $assocValue): array|null
|
||||
{
|
||||
@@ -348,7 +347,7 @@ class DefaultQueryCache implements QueryCache
|
||||
];
|
||||
}
|
||||
|
||||
/** @psalm-return list<mixed>|object|null */
|
||||
/** @phpstan-return list<mixed>|object|null */
|
||||
private function getAssociationValue(
|
||||
ResultSetMapping $rsm,
|
||||
string $assocAlias,
|
||||
@@ -374,9 +373,9 @@ class DefaultQueryCache implements QueryCache
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param array<array-key, array{field: string, class: string}> $path
|
||||
* @phpstan-param array<array-key, array{field: string, class: string}> $path
|
||||
*
|
||||
* @psalm-return list<mixed>|object|null
|
||||
* @phpstan-return list<mixed>|object|null
|
||||
*/
|
||||
private function getAssociationPathValue(mixed $value, array $path): array|object|null
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@ use Doctrine\ORM\Mapping\ClassMetadataFactory;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\Persisters\Collection\CollectionPersister;
|
||||
use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
|
||||
use Doctrine\ORM\Query\FilterCollection;
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
|
||||
use function array_values;
|
||||
@@ -35,6 +36,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
|
||||
protected array $queuedCache = [];
|
||||
|
||||
protected string $regionName;
|
||||
protected FilterCollection $filters;
|
||||
protected CollectionHydrator $hydrator;
|
||||
protected CacheLogger|null $cacheLogger;
|
||||
|
||||
@@ -48,6 +50,10 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
|
||||
$cacheConfig = $configuration->getSecondLevelCacheConfiguration();
|
||||
$cacheFactory = $cacheConfig->getCacheFactory();
|
||||
|
||||
$this->region = $region;
|
||||
$this->persister = $persister;
|
||||
$this->association = $association;
|
||||
$this->filters = $em->getFilters();
|
||||
$this->regionName = $region->getName();
|
||||
$this->uow = $em->getUnitOfWork();
|
||||
$this->metadataFactory = $em->getMetadataFactory();
|
||||
@@ -135,7 +141,7 @@ abstract class AbstractCollectionPersister implements CachedCollectionPersister
|
||||
public function count(PersistentCollection $collection): int
|
||||
{
|
||||
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
|
||||
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId);
|
||||
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId, $this->filters->getHash());
|
||||
$entry = $this->region->get($key);
|
||||
|
||||
if ($entry !== null) {
|
||||
|
||||
@@ -36,7 +36,7 @@ class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPers
|
||||
public function delete(PersistentCollection $collection): void
|
||||
{
|
||||
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
|
||||
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId);
|
||||
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId, $this->filters->getHash());
|
||||
|
||||
$this->persister->delete($collection);
|
||||
|
||||
@@ -53,7 +53,7 @@ class NonStrictReadWriteCachedCollectionPersister extends AbstractCollectionPers
|
||||
}
|
||||
|
||||
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
|
||||
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId);
|
||||
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId, $this->filters->getHash());
|
||||
|
||||
// Invalidate non initialized collections OR ordered collection
|
||||
if ($isDirty && ! $isInitialized || $this->association->isOrdered()) {
|
||||
|
||||
@@ -61,7 +61,7 @@ class ReadWriteCachedCollectionPersister extends AbstractCollectionPersister
|
||||
public function delete(PersistentCollection $collection): void
|
||||
{
|
||||
$ownerId = $this->uow->getEntityIdentifier($collection->getOwner());
|
||||
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId);
|
||||
$key = new CollectionCacheKey($this->sourceEntity->rootEntityName, $this->association->fieldName, $ownerId, $this->filters->getHash());
|
||||
$lock = $this->region->lock($key);
|
||||
|
||||
$this->persister->delete($collection);
|
||||
@@ -88,7 +88,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) {
|
||||
|
||||
@@ -24,11 +24,12 @@ 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\Query\ResultSetMapping;
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
|
||||
use function array_merge;
|
||||
use function assert;
|
||||
use function func_get_args;
|
||||
use function serialize;
|
||||
use function sha1;
|
||||
|
||||
@@ -44,6 +45,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
protected TimestampCacheKey $timestampKey;
|
||||
protected EntityHydrator $hydrator;
|
||||
protected Cache $cache;
|
||||
protected FilterCollection $filters;
|
||||
protected CacheLogger|null $cacheLogger = null;
|
||||
protected string $regionName;
|
||||
|
||||
@@ -65,6 +67,7 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
$cacheFactory = $cacheConfig->getCacheFactory();
|
||||
|
||||
$this->cache = $em->getCache();
|
||||
$this->filters = $em->getFilters();
|
||||
$this->regionName = $region->getName();
|
||||
$this->uow = $em->getUnitOfWork();
|
||||
$this->metadataFactory = $em->getMetadataFactory();
|
||||
@@ -216,7 +219,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());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,7 +476,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) {
|
||||
@@ -504,7 +507,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) {
|
||||
@@ -547,11 +550,15 @@ abstract class AbstractEntityPersister implements CachedEntityPersister
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $ownerId */
|
||||
protected function buildCollectionCacheKey(AssociationMapping $association, array $ownerId): CollectionCacheKey
|
||||
protected function buildCollectionCacheKey(AssociationMapping $association, array $ownerId, /* string $filterHash */): CollectionCacheKey
|
||||
{
|
||||
$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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,16 +41,16 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
/** @var mixed[] */
|
||||
protected array $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;
|
||||
@@ -122,7 +122,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
/**
|
||||
* Sets the entity alias map.
|
||||
*
|
||||
* @psalm-param array<string, string> $entityNamespaces
|
||||
* @phpstan-param array<string, string> $entityNamespaces
|
||||
*/
|
||||
public function setEntityNamespaces(array $entityNamespaces): void
|
||||
{
|
||||
@@ -132,7 +132,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(): array
|
||||
{
|
||||
@@ -191,7 +191,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* DQL function names are case-insensitive.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function addCustomStringFunction(string $name, string|callable $className): void
|
||||
{
|
||||
@@ -201,7 +201,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
/**
|
||||
* Gets the implementation class name of a registered custom string DQL function.
|
||||
*
|
||||
* @psalm-return class-string<FunctionNode>|callable(string):FunctionNode|null
|
||||
* @phpstan-return class-string<FunctionNode>|callable(string):FunctionNode|null
|
||||
*/
|
||||
public function getCustomStringFunction(string $name): string|callable|null
|
||||
{
|
||||
@@ -218,7 +218,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.
|
||||
*/
|
||||
public function setCustomStringFunctions(array $functions): void
|
||||
@@ -236,7 +236,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* DQL function names are case-insensitive.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function addCustomNumericFunction(string $name, string|callable $className): void
|
||||
{
|
||||
@@ -246,7 +246,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
/**
|
||||
* Gets the implementation class name of a registered custom numeric DQL function.
|
||||
*
|
||||
* @psalm-return ?class-string<FunctionNode>|callable(string):FunctionNode
|
||||
* @phpstan-return class-string<FunctionNode>|callable(string):FunctionNode|null
|
||||
*/
|
||||
public function getCustomNumericFunction(string $name): string|callable|null
|
||||
{
|
||||
@@ -281,7 +281,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
* DQL function names are case-insensitive.
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
public function addCustomDatetimeFunction(string $name, string|callable $className): void
|
||||
{
|
||||
@@ -309,7 +309,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
|
||||
*/
|
||||
public function setCustomDatetimeFunctions(array $functions): void
|
||||
{
|
||||
@@ -538,7 +538,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(): array
|
||||
{
|
||||
@@ -548,7 +548,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
|
||||
*/
|
||||
public function setDefaultQueryHints(array $defaultQueryHints): void
|
||||
{
|
||||
|
||||
@@ -565,9 +565,9 @@ class EntityManager implements EntityManagerInterface
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function isUninitializedObject($obj): bool
|
||||
public function isUninitializedObject($value): bool
|
||||
{
|
||||
return $this->unitOfWork->isUninitializedObject($obj);
|
||||
return $this->unitOfWork->isUninitializedObject($value);
|
||||
}
|
||||
|
||||
public function getFilters(): FilterCollection
|
||||
@@ -586,7 +586,7 @@ class EntityManager implements EntityManagerInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param LockMode::* $lockMode
|
||||
* @phpstan-param LockMode::* $lockMode
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
* @throws TransactionRequiredException
|
||||
|
||||
@@ -71,10 +71,10 @@ interface EntityManagerInterface extends ObjectManager
|
||||
* If an exception occurs during execution of the function or flushing or transaction commit,
|
||||
* the transaction is rolled back, the EntityManager closed and the exception re-thrown.
|
||||
*
|
||||
* @psalm-param callable(self): T $func The function to execute transactionally.
|
||||
* @phpstan-param callable(self): T $func The function to execute transactionally.
|
||||
*
|
||||
* @return mixed The value returned from the closure.
|
||||
* @psalm-return T
|
||||
* @phpstan-return T
|
||||
*
|
||||
* @template T
|
||||
*/
|
||||
@@ -117,11 +117,11 @@ interface EntityManagerInterface extends ObjectManager
|
||||
* during the search.
|
||||
* @param int|null $lockVersion The version of the entity to find when using
|
||||
* optimistic locking.
|
||||
* @psalm-param class-string<T> $className
|
||||
* @psalm-param LockMode::*|null $lockMode
|
||||
* @phpstan-param class-string<T> $className
|
||||
* @phpstan-param LockMode::*|null $lockMode
|
||||
*
|
||||
* @return object|null The entity instance or NULL if the entity can not be found.
|
||||
* @psalm-return T|null
|
||||
* @phpstan-return T|null
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
* @throws ORMInvalidArgumentException
|
||||
@@ -139,7 +139,7 @@ interface EntityManagerInterface extends ObjectManager
|
||||
* @param LockMode|int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants
|
||||
* or NULL if no specific lock mode should be used
|
||||
* during the search.
|
||||
* @psalm-param LockMode::*|null $lockMode
|
||||
* @phpstan-param LockMode::*|null $lockMode
|
||||
*
|
||||
* @throws ORMInvalidArgumentException
|
||||
* @throws ORMException
|
||||
@@ -172,7 +172,7 @@ interface EntityManagerInterface extends ObjectManager
|
||||
/**
|
||||
* Acquire a lock on the given entity.
|
||||
*
|
||||
* @psalm-param LockMode::* $lockMode
|
||||
* @phpstan-param LockMode::* $lockMode
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
* @throws PessimisticLockException
|
||||
@@ -202,7 +202,7 @@ interface EntityManagerInterface extends ObjectManager
|
||||
/**
|
||||
* Create a new instance for the given hydration mode.
|
||||
*
|
||||
* @psalm-param string|AbstractQuery::HYDRATE_* $hydrationMode
|
||||
* @phpstan-param string|AbstractQuery::HYDRATE_* $hydrationMode
|
||||
*
|
||||
* @throws ORMException
|
||||
*/
|
||||
@@ -233,9 +233,9 @@ interface EntityManagerInterface extends ObjectManager
|
||||
*
|
||||
* @param string|class-string<T> $className
|
||||
*
|
||||
* @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(string $className): Mapping\ClassMetadata;
|
||||
}
|
||||
|
||||
@@ -76,10 +76,10 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
* @param LockMode|int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants
|
||||
* or NULL if no specific lock mode should be used
|
||||
* during the search.
|
||||
* @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(mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null
|
||||
{
|
||||
@@ -89,7 +89,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(): array
|
||||
{
|
||||
@@ -101,7 +101,7 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
*
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-return list<T>
|
||||
* @phpstan-return list<T>
|
||||
*/
|
||||
public function findBy(array $criteria, array|null $orderBy = null, int|null $limit = null, int|null $offset = null): array
|
||||
{
|
||||
@@ -113,10 +113,10 @@ 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
|
||||
*
|
||||
* @psalm-return T|null
|
||||
* @phpstan-return T|null
|
||||
*/
|
||||
public function findOneBy(array $criteria, array|null $orderBy = null): object|null
|
||||
{
|
||||
@@ -128,10 +128,10 @@ 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.
|
||||
* @psalm-return 0|positive-int
|
||||
* @phpstan-return 0|positive-int
|
||||
*
|
||||
* @todo Add this method to `ObjectRepository` interface in the next major release
|
||||
*/
|
||||
@@ -144,7 +144,7 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
* Adds support for magic method calls.
|
||||
*
|
||||
* @param mixed[] $arguments
|
||||
* @psalm-param list<mixed> $arguments
|
||||
* @phpstan-param list<mixed> $arguments
|
||||
*
|
||||
* @throws BadMethodCallException If the method called is invalid.
|
||||
*/
|
||||
@@ -185,7 +185,7 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
return $this->em;
|
||||
}
|
||||
|
||||
/** @psalm-return ClassMetadata<T> */
|
||||
/** @phpstan-return ClassMetadata<T> */
|
||||
protected function getClassMetadata(): ClassMetadata
|
||||
{
|
||||
return $this->class;
|
||||
@@ -195,7 +195,7 @@ class EntityRepository implements ObjectRepository, Selectable
|
||||
* Select all elements from a selectable that match the expression and
|
||||
* return a new collection containing these elements.
|
||||
*
|
||||
* @psalm-return AbstractLazyCollection<int, T>&Selectable<int, T>
|
||||
* @phpstan-return AbstractLazyCollection<int, T>&Selectable<int, T>
|
||||
*/
|
||||
public function matching(Criteria $criteria): AbstractLazyCollection&Selectable
|
||||
{
|
||||
@@ -209,7 +209,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
|
||||
*
|
||||
* @throws InvalidMagicMethodCall If the method called is invalid or the
|
||||
* requested field/association does not exist.
|
||||
|
||||
@@ -38,7 +38,7 @@ class ListenersInvoker
|
||||
* @param ClassMetadata $metadata The entity metadata.
|
||||
* @param string $eventName The entity lifecycle event.
|
||||
*
|
||||
* @psalm-return int-mask-of<self::INVOKE_*> Bitmask of subscribed event systems.
|
||||
* @phpstan-return int-mask-of<self::INVOKE_*> Bitmask of subscribed event systems.
|
||||
*/
|
||||
public function getSubscribedSystems(ClassMetadata $metadata, string $eventName): int
|
||||
{
|
||||
@@ -66,7 +66,7 @@ class ListenersInvoker
|
||||
* @param string $eventName The entity lifecycle event.
|
||||
* @param object $entity The Entity on which the event occurred.
|
||||
* @param EventArgs $event The Event args.
|
||||
* @psalm-param int-mask-of<self::INVOKE_*> $invoke Bitmask to invoke listeners.
|
||||
* @phpstan-param int-mask-of<self::INVOKE_*> $invoke Bitmask to invoke listeners.
|
||||
*/
|
||||
public function invoke(
|
||||
ClassMetadata $metadata,
|
||||
|
||||
@@ -24,7 +24,7 @@ class PreUpdateEventArgs extends LifecycleEventArgs
|
||||
|
||||
/**
|
||||
* @param mixed[][] $changeSet
|
||||
* @psalm-param array<string, array{mixed, mixed}|PersistentCollection> $changeSet
|
||||
* @phpstan-param array<string, array{mixed, mixed}|PersistentCollection> $changeSet
|
||||
*/
|
||||
public function __construct(object $entity, EntityManagerInterface $em, array &$changeSet)
|
||||
{
|
||||
@@ -37,7 +37,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(): array
|
||||
{
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -29,7 +29,7 @@ use function is_array;
|
||||
* Base class for all hydrators. A hydrator is a class that provides some form
|
||||
* of transformation of an SQL result set into another structure.
|
||||
*
|
||||
* @psalm-consistent-constructor
|
||||
* @phpstan-consistent-constructor
|
||||
*/
|
||||
abstract class AbstractHydrator
|
||||
{
|
||||
@@ -86,7 +86,7 @@ abstract class AbstractHydrator
|
||||
/**
|
||||
* Initiates a row-by-row hydration.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $hints
|
||||
* @phpstan-param array<string, mixed> $hints
|
||||
*
|
||||
* @return Generator<array-key, mixed>
|
||||
*
|
||||
@@ -153,7 +153,7 @@ abstract class AbstractHydrator
|
||||
/**
|
||||
* Hydrates all rows returned by the passed statement instance at once.
|
||||
*
|
||||
* @psalm-param array<string, string> $hints
|
||||
* @phpstan-param array<string, string> $hints
|
||||
*/
|
||||
public function hydrateAll(Result $stmt, ResultSetMapping $resultSetMapping, array $hints = []): mixed
|
||||
{
|
||||
@@ -242,14 +242,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: ReflectionClass,
|
||||
@@ -367,10 +367,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(array &$data): array
|
||||
{
|
||||
@@ -405,7 +405,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(string $key): array|null
|
||||
{
|
||||
@@ -502,7 +502,7 @@ abstract class AbstractHydrator
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @psalm-return non-empty-list<string>
|
||||
* @phpstan-return non-empty-list<string>
|
||||
*/
|
||||
private function getDiscriminatorValues(ClassMetadata $classMetadata): array
|
||||
{
|
||||
|
||||
@@ -213,7 +213,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.
|
||||
*
|
||||
* @throws HydrationException
|
||||
*/
|
||||
@@ -266,7 +266,7 @@ class ObjectHydrator extends AbstractHydrator
|
||||
|
||||
/**
|
||||
* @param class-string $className
|
||||
* @psalm-param array<string, mixed> $data
|
||||
* @phpstan-param array<string, mixed> $data
|
||||
*/
|
||||
private function getEntityFromIdentityMap(string $className, array $data): object|bool
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ use function array_search;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function in_array;
|
||||
use function is_array;
|
||||
use function key;
|
||||
use function reset;
|
||||
use function sprintf;
|
||||
@@ -138,14 +139,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,
|
||||
);
|
||||
|
||||
@@ -29,7 +29,7 @@ trait NoUnknownNamedArguments
|
||||
* @param TItem[] $parameter
|
||||
*
|
||||
* @template TItem
|
||||
* @psalm-assert list<TItem> $parameter
|
||||
* @phpstan-assert list<TItem> $parameter
|
||||
*/
|
||||
private static function validateVariadicParameter(array $parameter): void
|
||||
{
|
||||
|
||||
@@ -97,7 +97,7 @@ abstract class AssociationMapping implements ArrayAccess
|
||||
|
||||
/**
|
||||
* @param mixed[] $mappingArray
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName: string,
|
||||
* sourceEntity: class-string,
|
||||
* targetEntity: class-string,
|
||||
@@ -153,75 +153,75 @@ abstract class AssociationMapping implements ArrayAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-assert-if-true OwningSideMapping $this
|
||||
* @psalm-assert-if-false InverseSideMapping $this
|
||||
* @phpstan-assert-if-true OwningSideMapping $this
|
||||
* @phpstan-assert-if-false InverseSideMapping $this
|
||||
*/
|
||||
final public function isOwningSide(): bool
|
||||
{
|
||||
return $this instanceof OwningSideMapping;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true ToOneAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true ToOneAssociationMapping $this */
|
||||
final public function isToOne(): bool
|
||||
{
|
||||
return $this instanceof ToOneAssociationMapping;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true ToManyAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true ToManyAssociationMapping $this */
|
||||
final public function isToMany(): bool
|
||||
{
|
||||
return $this instanceof ToManyAssociationMapping;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true OneToOneOwningSideMapping $this */
|
||||
/** @phpstan-assert-if-true OneToOneOwningSideMapping $this */
|
||||
final public function isOneToOneOwningSide(): bool
|
||||
{
|
||||
return $this->isOneToOne() && $this->isOwningSide();
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true OneToOneOwningSideMapping|ManyToOneAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true OneToOneOwningSideMapping|ManyToOneAssociationMapping $this */
|
||||
final public function isToOneOwningSide(): bool
|
||||
{
|
||||
return $this->isToOne() && $this->isOwningSide();
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true ManyToManyOwningSideMapping $this */
|
||||
/** @phpstan-assert-if-true ManyToManyOwningSideMapping $this */
|
||||
final public function isManyToManyOwningSide(): bool
|
||||
{
|
||||
return $this instanceof ManyToManyOwningSideMapping;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true OneToOneAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true OneToOneAssociationMapping $this */
|
||||
final public function isOneToOne(): bool
|
||||
{
|
||||
return $this instanceof OneToOneAssociationMapping;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true OneToManyAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true OneToManyAssociationMapping $this */
|
||||
final public function isOneToMany(): bool
|
||||
{
|
||||
return $this instanceof OneToManyAssociationMapping;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true ManyToOneAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true ManyToOneAssociationMapping $this */
|
||||
final public function isManyToOne(): bool
|
||||
{
|
||||
return $this instanceof ManyToOneAssociationMapping;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true ManyToManyAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true ManyToManyAssociationMapping $this */
|
||||
final public function isManyToMany(): bool
|
||||
{
|
||||
return $this instanceof ManyToManyAssociationMapping;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true ToManyAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true ToManyAssociationMapping $this */
|
||||
final public function isOrdered(): bool
|
||||
{
|
||||
return $this->isToMany() && $this->orderBy() !== [];
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true ToManyAssociationMapping $this */
|
||||
/** @phpstan-assert-if-true ToManyAssociationMapping $this */
|
||||
public function isIndexed(): bool
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -27,7 +27,7 @@ final class AssociationOverride implements MappingAttribute
|
||||
* @param JoinColumn|array<JoinColumn> $inverseJoinColumns
|
||||
* @param JoinTable|null $joinTable The join table that maps the relationship.
|
||||
* @param string|null $inversedBy The name of the association-field on the inverse-side.
|
||||
* @psalm-param 'LAZY'|'EAGER'|'EXTRA_LAZY'|null $fetch
|
||||
* @phpstan-param 'LAZY'|'EAGER'|'EXTRA_LAZY'|null $fetch
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly string $name,
|
||||
|
||||
@@ -109,7 +109,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Adds Index.
|
||||
*
|
||||
* @psalm-param list<string> $columns
|
||||
* @phpstan-param list<string> $columns
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -127,7 +127,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Adds Unique Constraint.
|
||||
*
|
||||
* @psalm-param list<string> $columns
|
||||
* @phpstan-param list<string> $columns
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
@@ -235,7 +235,7 @@ class ClassMetadataBuilder
|
||||
/**
|
||||
* Adds Field.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $mapping
|
||||
* @phpstan-param array<string, mixed> $mapping
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@ use Attribute;
|
||||
#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_PROPERTY)]
|
||||
final class Cache implements MappingAttribute
|
||||
{
|
||||
/** @psalm-param 'READ_ONLY'|'NONSTRICT_READ_WRITE'|'READ_WRITE' $usage */
|
||||
/** @phpstan-param 'READ_ONLY'|'NONSTRICT_READ_WRITE'|'READ_WRITE' $usage */
|
||||
public function __construct(
|
||||
public readonly string $usage = 'READ_ONLY',
|
||||
public readonly string|null $region = null,
|
||||
|
||||
@@ -9,7 +9,7 @@ use Attribute;
|
||||
#[Attribute(Attribute::TARGET_CLASS)]
|
||||
final class ChangeTrackingPolicy implements MappingAttribute
|
||||
{
|
||||
/** @psalm-param 'DEFERRED_IMPLICIT'|'DEFERRED_EXPLICIT' $value */
|
||||
/** @phpstan-param 'DEFERRED_IMPLICIT'|'DEFERRED_EXPLICIT' $value */
|
||||
public function __construct(
|
||||
public readonly string $value,
|
||||
) {
|
||||
|
||||
@@ -25,7 +25,10 @@ use ReflectionProperty;
|
||||
use Stringable;
|
||||
|
||||
use function array_column;
|
||||
use function array_count_values;
|
||||
use function array_diff;
|
||||
use function array_filter;
|
||||
use function array_flip;
|
||||
use function array_intersect;
|
||||
use function array_key_exists;
|
||||
use function array_keys;
|
||||
@@ -39,6 +42,7 @@ use function count;
|
||||
use function defined;
|
||||
use function enum_exists;
|
||||
use function explode;
|
||||
use function implode;
|
||||
use function in_array;
|
||||
use function interface_exists;
|
||||
use function is_string;
|
||||
@@ -67,12 +71,14 @@ use function trim;
|
||||
* get the whole class name, namespace inclusive, prepended to every property in
|
||||
* the serialized representation).
|
||||
*
|
||||
* @psalm-type ConcreteAssociationMapping = OneToOneOwningSideMapping|OneToOneInverseSideMapping|ManyToOneAssociationMapping|OneToManyAssociationMapping|ManyToManyOwningSideMapping|ManyToManyInverseSideMapping
|
||||
* @phpstan-type ConcreteAssociationMapping = OneToOneOwningSideMapping|OneToOneInverseSideMapping|ManyToOneAssociationMapping|OneToManyAssociationMapping|ManyToManyOwningSideMapping|ManyToManyInverseSideMapping
|
||||
* @template-covariant T of object
|
||||
* @template-implements PersistenceClassMetadata<T>
|
||||
*/
|
||||
class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
{
|
||||
use GetReflectionClassImplementation;
|
||||
|
||||
/* The inheritance mapping types */
|
||||
/**
|
||||
* NONE means the class does not participate in an inheritance hierarchy
|
||||
@@ -231,7 +237,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* hierarchy. If the entity is not part of a mapped inheritance hierarchy this is the same
|
||||
* as {@link $name}.
|
||||
*
|
||||
* @psalm-var class-string
|
||||
* @phpstan-var class-string
|
||||
*/
|
||||
public string $rootEntityName;
|
||||
|
||||
@@ -255,7 +261,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* The name of the custom repository class used for the entity class.
|
||||
* (Optional).
|
||||
*
|
||||
* @psalm-var ?class-string<EntityRepository>
|
||||
* @phpstan-var ?class-string<EntityRepository>
|
||||
*/
|
||||
public string|null $customRepositoryClassName = null;
|
||||
|
||||
@@ -273,7 +279,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* READ-ONLY: The names of the parent <em>entity</em> classes (ancestors), starting with the
|
||||
* nearest one and ending with the root entity class.
|
||||
*
|
||||
* @psalm-var list<class-string>
|
||||
* @phpstan-var list<class-string>
|
||||
*/
|
||||
public array $parentClasses = [];
|
||||
|
||||
@@ -300,14 +306,14 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* For subclasses of such root entities, the list can be reused/passed downwards, it only needs to
|
||||
* be filtered accordingly (only keep remaining subclasses)
|
||||
*
|
||||
* @psalm-var list<class-string>
|
||||
* @phpstan-var list<class-string>
|
||||
*/
|
||||
public array $subClasses = [];
|
||||
|
||||
/**
|
||||
* READ-ONLY: The names of all embedded classes based on properties.
|
||||
*
|
||||
* @psalm-var array<string, EmbeddedClassMapping>
|
||||
* @phpstan-var array<string, EmbeddedClassMapping>
|
||||
*/
|
||||
public array $embeddedClasses = [];
|
||||
|
||||
@@ -315,21 +321,21 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* 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 array $identifier = [];
|
||||
|
||||
/**
|
||||
* READ-ONLY: The inheritance mapping type used by the class.
|
||||
*
|
||||
* @psalm-var self::INHERITANCE_TYPE_*
|
||||
* @phpstan-var self::INHERITANCE_TYPE_*
|
||||
*/
|
||||
public int $inheritanceType = self::INHERITANCE_TYPE_NONE;
|
||||
|
||||
/**
|
||||
* READ-ONLY: The Id generator type used by the class.
|
||||
*
|
||||
* @psalm-var self::GENERATOR_TYPE_*
|
||||
* @phpstan-var self::GENERATOR_TYPE_*
|
||||
*/
|
||||
public int $generatorType = self::GENERATOR_TYPE_NONE;
|
||||
|
||||
@@ -345,7 +351,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* 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 array $fieldNames = [];
|
||||
|
||||
@@ -380,7 +386,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
*
|
||||
* @var array<int|string, string>
|
||||
*
|
||||
* @psalm-var array<int|string, class-string>
|
||||
* @phpstan-var array<int|string, class-string>
|
||||
*/
|
||||
public array $discriminatorMap = [];
|
||||
|
||||
@@ -400,7 +406,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* uniqueConstraints => array
|
||||
*
|
||||
* @var mixed[]
|
||||
* @psalm-var array{
|
||||
* @phpstan-var array{
|
||||
* name: string,
|
||||
* schema?: string,
|
||||
* indexes?: array,
|
||||
@@ -414,14 +420,14 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* READ-ONLY: The registered lifecycle callbacks for entities of this class.
|
||||
*
|
||||
* @psalm-var array<string, list<string>>
|
||||
* @phpstan-var array<string, list<string>>
|
||||
*/
|
||||
public array $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 array $entityListeners = [];
|
||||
|
||||
@@ -437,7 +443,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* )
|
||||
* </pre>
|
||||
*
|
||||
* @psalm-var array<string, ConcreteAssociationMapping>
|
||||
* @phpstan-var array<string, ConcreteAssociationMapping>
|
||||
*/
|
||||
public array $associationMappings = [];
|
||||
|
||||
@@ -481,7 +487,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* </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 array|null $sequenceGeneratorDefinition = null;
|
||||
@@ -548,7 +554,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* metadata of the class with the given name.
|
||||
*
|
||||
* @param string $name The name of the entity class the new instance is used for.
|
||||
* @psalm-param class-string<T> $name
|
||||
* @phpstan-param class-string<T> $name
|
||||
*/
|
||||
public function __construct(public string $name, NamingStrategy|null $namingStrategy = null, TypedFieldMapper|null $typedFieldMapper = null)
|
||||
{
|
||||
@@ -562,7 +568,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* 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(): array
|
||||
{
|
||||
@@ -628,7 +634,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Populates the entity identifier of an entity.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $id
|
||||
* @phpstan-param array<string, mixed> $id
|
||||
*
|
||||
* @todo Rename to assignIdentifier()
|
||||
*/
|
||||
@@ -932,17 +938,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Can return null when using static reflection, in violation of the LSP
|
||||
*/
|
||||
public function getReflectionClass(): ReflectionClass|null
|
||||
{
|
||||
return $this->reflClass;
|
||||
}
|
||||
|
||||
/** @psalm-param array{usage?: mixed, region?: mixed} $cache */
|
||||
/** @phpstan-param array{usage?: mixed, region?: mixed} $cache */
|
||||
public function enableCache(array $cache): void
|
||||
{
|
||||
if (! isset($cache['usage'])) {
|
||||
@@ -956,17 +952,17 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
/** @psalm-param array{usage?: int, region?: string} $cache */
|
||||
/** @phpstan-param array{usage?: int, region?: string} $cache */
|
||||
public function enableAssociationCache(string $fieldName, array $cache): void
|
||||
{
|
||||
$this->associationMappings[$fieldName]->cache = $this->getAssociationCacheDefaults($fieldName, $cache);
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param array{usage?: int, region?: string|null} $cache
|
||||
* @phpstan-param array{usage?: int, 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(string $fieldName, array $cache): array
|
||||
{
|
||||
@@ -1083,7 +1079,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Gets all association mappings of the class.
|
||||
*
|
||||
* @psalm-return array<string, AssociationMapping>
|
||||
* @phpstan-return array<string, AssociationMapping>
|
||||
*/
|
||||
public function getAssociationMappings(): array
|
||||
{
|
||||
@@ -1150,7 +1146,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Validates & completes the given field mapping.
|
||||
*
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName?: string,
|
||||
* columnName?: string,
|
||||
* id?: bool,
|
||||
@@ -1250,7 +1246,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* 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 ConcreteAssociationMapping
|
||||
*
|
||||
@@ -1465,7 +1461,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* 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
|
||||
*/
|
||||
public function setIdentifier(array $identifier): void
|
||||
{
|
||||
@@ -1489,10 +1485,10 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* 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|null $fieldNames = null): array
|
||||
{
|
||||
@@ -1506,7 +1502,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Returns an array with all the identifier column names.
|
||||
*
|
||||
* @psalm-return list<string>
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
public function getIdentifierColumnNames(): array
|
||||
{
|
||||
@@ -1533,7 +1529,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Sets the type of Id generator to use for the mapped class.
|
||||
*
|
||||
* @psalm-param self::GENERATOR_TYPE_* $generatorType
|
||||
* @phpstan-param self::GENERATOR_TYPE_* $generatorType
|
||||
*/
|
||||
public function setIdGeneratorType(int $generatorType): void
|
||||
{
|
||||
@@ -1586,7 +1582,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Checks whether the class uses a sequence for id generation.
|
||||
*
|
||||
* @psalm-assert-if-true !null $this->sequenceGeneratorDefinition
|
||||
* @phpstan-assert-if-true !null $this->sequenceGeneratorDefinition
|
||||
*/
|
||||
public function isIdGeneratorSequence(): bool
|
||||
{
|
||||
@@ -1642,7 +1638,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public function setSubclasses(array $subclasses): void
|
||||
{
|
||||
@@ -1657,7 +1653,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* Assumes that the class names in the passed array are in the order:
|
||||
* directParent -> directParentParent -> directParentParentParent ... -> root.
|
||||
*
|
||||
* @psalm-param list<class-string> $classNames
|
||||
* @phpstan-param list<class-string> $classNames
|
||||
*/
|
||||
public function setParentClasses(array $classNames): void
|
||||
{
|
||||
@@ -1671,7 +1667,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Sets the inheritance type used by the class and its subclasses.
|
||||
*
|
||||
* @psalm-param self::INHERITANCE_TYPE_* $type
|
||||
* @phpstan-param self::INHERITANCE_TYPE_* $type
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
@@ -1687,7 +1683,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Sets the association to override association mapping of property for an entity relationship.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $overrideMapping
|
||||
* @phpstan-param array{joinColumns?: array, inversedBy?: ?string, joinTable?: array, fetch?: ?string, cascade?: string[]} $overrideMapping
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
@@ -1723,6 +1719,10 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
$mapping['fetch'] = $overrideMapping['fetch'];
|
||||
}
|
||||
|
||||
if (isset($overrideMapping['cascade'])) {
|
||||
$mapping['cascade'] = $overrideMapping['cascade'];
|
||||
}
|
||||
|
||||
switch ($mapping['type']) {
|
||||
case self::ONE_TO_ONE:
|
||||
case self::MANY_TO_ONE:
|
||||
@@ -1741,7 +1741,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Sets the override for a mapped field.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $overrideMapping
|
||||
* @phpstan-param array<string, mixed> $overrideMapping
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
@@ -1836,7 +1836,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
public function setPrimaryTable(array $table): void
|
||||
{
|
||||
@@ -1888,7 +1888,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
@@ -1956,7 +1956,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Adds a one-to-many mapping.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $mapping The mapping.
|
||||
* @phpstan-param array<string, mixed> $mapping The mapping.
|
||||
*/
|
||||
public function mapOneToMany(array $mapping): void
|
||||
{
|
||||
@@ -1970,7 +1970,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Adds a many-to-one mapping.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $mapping The mapping.
|
||||
* @phpstan-param array<string, mixed> $mapping The mapping.
|
||||
*/
|
||||
public function mapManyToOne(array $mapping): void
|
||||
{
|
||||
@@ -1984,7 +1984,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Adds a many-to-many mapping.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $mapping The mapping.
|
||||
* @phpstan-param array<string, mixed> $mapping The mapping.
|
||||
*/
|
||||
public function mapManyToMany(array $mapping): void
|
||||
{
|
||||
@@ -2015,7 +2015,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* Registers a custom repository class for the entity class.
|
||||
*
|
||||
* @param string|null $repositoryClassName The class name of the custom mapper.
|
||||
* @psalm-param class-string<EntityRepository>|null $repositoryClassName
|
||||
* @phpstan-param class-string<EntityRepository>|null $repositoryClassName
|
||||
*/
|
||||
public function setCustomRepositoryClass(string|null $repositoryClassName): void
|
||||
{
|
||||
@@ -2055,7 +2055,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* Gets the registered lifecycle callbacks for an event.
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
public function getLifecycleCallbacks(string $event): array
|
||||
{
|
||||
@@ -2082,7 +2082,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* 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
|
||||
*/
|
||||
public function setLifecycleCallbacks(array $callbacks): void
|
||||
{
|
||||
@@ -2128,7 +2128,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* @see getDiscriminatorColumn()
|
||||
*
|
||||
* @param DiscriminatorColumnMapping|mixed[]|null $columnDef
|
||||
* @psalm-param DiscriminatorColumnMapping|array{
|
||||
* @phpstan-param DiscriminatorColumnMapping|array{
|
||||
* name: string|null,
|
||||
* fieldName?: string|null,
|
||||
* type?: string|null,
|
||||
@@ -2186,6 +2186,22 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
*/
|
||||
public function setDiscriminatorMap(array $map): void
|
||||
{
|
||||
if (count(array_flip($map)) !== count($map)) {
|
||||
Deprecation::trigger(
|
||||
'doctrine/orm',
|
||||
'https://github.com/doctrine/orm/issues/3519',
|
||||
<<<'DEPRECATION'
|
||||
Mapping a class to multiple discriminator values is deprecated,
|
||||
and the discriminator mapping of %s contains duplicate values
|
||||
for the following discriminator values: %s.
|
||||
DEPRECATION,
|
||||
$this->name,
|
||||
implode(', ', array_keys(array_filter(array_count_values($map), static function (int $value): bool {
|
||||
return $value > 1;
|
||||
}))),
|
||||
);
|
||||
}
|
||||
|
||||
foreach ($map as $value => $className) {
|
||||
$this->addDiscriminatorMapClass($value, $className);
|
||||
}
|
||||
@@ -2334,7 +2350,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Sets definition.
|
||||
*
|
||||
* @psalm-param array<string, string|null> $definition
|
||||
* @phpstan-param array<string, string|null> $definition
|
||||
*/
|
||||
public function setCustomGeneratorDefinition(array $definition): void
|
||||
{
|
||||
@@ -2354,7 +2370,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* )
|
||||
* </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
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
@@ -2387,7 +2403,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* 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.
|
||||
*
|
||||
* @throws MappingException
|
||||
*/
|
||||
@@ -2456,7 +2472,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @psalm-return class-string
|
||||
* @phpstan-return class-string
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
@@ -2501,7 +2517,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
* @param C $className
|
||||
*
|
||||
* @return string|null null if and only if the input value is null
|
||||
* @psalm-return (C is class-string ? class-string : (C is string ? string : null))
|
||||
* @phpstan-return (C is class-string ? class-string : (C is string ? string : null))
|
||||
*
|
||||
* @template C of string|null
|
||||
*/
|
||||
@@ -2533,7 +2549,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
/**
|
||||
* Map Embedded Class
|
||||
*
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName: string,
|
||||
* class?: class-string,
|
||||
* declaredField?: string,
|
||||
@@ -2642,7 +2658,7 @@ class ClassMetadata implements PersistenceClassMetadata, Stringable
|
||||
return $sequencePrefix;
|
||||
}
|
||||
|
||||
/** @psalm-param class-string $class */
|
||||
/** @phpstan-param class-string $class */
|
||||
private function getAccessibleProperty(ReflectionService $reflService, string $class, string $field): ReflectionProperty|null
|
||||
{
|
||||
$reflectionProperty = $reflService->getAccessibleProperty($class, $field);
|
||||
|
||||
@@ -612,7 +612,7 @@ class ClassMetadataFactory extends AbstractClassMetadataFactory
|
||||
}
|
||||
}
|
||||
|
||||
/** @psalm-return ClassMetadata::GENERATOR_TYPE_* */
|
||||
/** @phpstan-return ClassMetadata::GENERATOR_TYPE_* */
|
||||
private function determineIdGeneratorStrategy(AbstractPlatform $platform): int
|
||||
{
|
||||
assert($this->em !== null);
|
||||
|
||||
@@ -15,7 +15,7 @@ final class Column implements MappingAttribute
|
||||
* @param int|null $scale The scale for a decimal (exact numeric) column (Applies only for decimal column).
|
||||
* @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(
|
||||
public readonly string|null $name = null,
|
||||
|
||||
@@ -24,7 +24,7 @@ class DefaultQuoteStrategy implements QuoteStrategy
|
||||
public function getColumnName(string $fieldName, ClassMetadata $class, AbstractPlatform $platform): string
|
||||
{
|
||||
return isset($class->fieldMappings[$fieldName]->quoted)
|
||||
? $platform->quoteIdentifier($class->fieldMappings[$fieldName]->columnName)
|
||||
? $platform->quoteSingleIdentifier($class->fieldMappings[$fieldName]->columnName)
|
||||
: $class->fieldMappings[$fieldName]->columnName;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class DefaultQuoteStrategy implements QuoteStrategy
|
||||
}
|
||||
|
||||
return isset($class->table['quoted'])
|
||||
? $platform->quoteIdentifier($tableName)
|
||||
? $platform->quoteSingleIdentifier($tableName)
|
||||
: $tableName;
|
||||
}
|
||||
|
||||
@@ -52,14 +52,14 @@ class DefaultQuoteStrategy implements QuoteStrategy
|
||||
public function getSequenceName(array $definition, ClassMetadata $class, AbstractPlatform $platform): string
|
||||
{
|
||||
return isset($definition['quoted'])
|
||||
? $platform->quoteIdentifier($definition['sequenceName'])
|
||||
? $platform->quoteSingleIdentifier($definition['sequenceName'])
|
||||
: $definition['sequenceName'];
|
||||
}
|
||||
|
||||
public function getJoinColumnName(JoinColumnMapping $joinColumn, ClassMetadata $class, AbstractPlatform $platform): string
|
||||
{
|
||||
return isset($joinColumn->quoted)
|
||||
? $platform->quoteIdentifier($joinColumn->name)
|
||||
? $platform->quoteSingleIdentifier($joinColumn->name)
|
||||
: $joinColumn->name;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class DefaultQuoteStrategy implements QuoteStrategy
|
||||
AbstractPlatform $platform,
|
||||
): string {
|
||||
return isset($joinColumn->quoted)
|
||||
? $platform->quoteIdentifier($joinColumn->referencedColumnName)
|
||||
? $platform->quoteSingleIdentifier($joinColumn->referencedColumnName)
|
||||
: $joinColumn->referencedColumnName;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class DefaultQuoteStrategy implements QuoteStrategy
|
||||
$tableName = $association->joinTable->name;
|
||||
|
||||
if (isset($association->joinTable->quoted)) {
|
||||
$tableName = $platform->quoteIdentifier($tableName);
|
||||
$tableName = $platform->quoteSingleIdentifier($tableName);
|
||||
}
|
||||
|
||||
return $schema . $tableName;
|
||||
@@ -113,7 +113,7 @@ class DefaultQuoteStrategy implements QuoteStrategy
|
||||
$joinColumns = $assoc->joinColumns;
|
||||
$assocQuotedColumnNames = array_map(
|
||||
static fn (JoinColumnMapping $joinColumn) => isset($joinColumn->quoted)
|
||||
? $platform->quoteIdentifier($joinColumn->name)
|
||||
? $platform->quoteSingleIdentifier($joinColumn->name)
|
||||
: $joinColumn->name,
|
||||
$joinColumns,
|
||||
);
|
||||
|
||||
@@ -20,7 +20,7 @@ use function defined;
|
||||
use function enum_exists;
|
||||
use function is_a;
|
||||
|
||||
/** @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 */
|
||||
@@ -74,8 +74,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($mapping['type'])) {
|
||||
|
||||
@@ -35,7 +35,7 @@ final class DiscriminatorColumnMapping implements ArrayAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* type: string,
|
||||
* fieldName: string,
|
||||
* name: string,
|
||||
|
||||
@@ -15,7 +15,6 @@ use Doctrine\Persistence\Mapping\Driver\MappingDriver;
|
||||
use InvalidArgumentException;
|
||||
use ReflectionClass;
|
||||
use ReflectionMethod;
|
||||
use ReflectionProperty;
|
||||
|
||||
use function assert;
|
||||
use function class_exists;
|
||||
@@ -273,8 +272,6 @@ class AttributeDriver implements MappingDriver
|
||||
}
|
||||
|
||||
foreach ($reflectionClass->getProperties() as $property) {
|
||||
assert($property instanceof ReflectionProperty);
|
||||
|
||||
if ($this->isRepeatedPropertyDeclaration($property, $metadata)) {
|
||||
continue;
|
||||
}
|
||||
@@ -285,8 +282,6 @@ class AttributeDriver implements MappingDriver
|
||||
// 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'],
|
||||
[
|
||||
@@ -560,7 +555,6 @@ class AttributeDriver implements MappingDriver
|
||||
$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);
|
||||
@@ -584,7 +578,6 @@ class AttributeDriver implements MappingDriver
|
||||
}
|
||||
|
||||
foreach ($reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
|
||||
assert($method instanceof ReflectionMethod);
|
||||
foreach ($this->getMethodCallbacks($method) as $value) {
|
||||
$metadata->addLifecycleCallback($value[0], $value[1]);
|
||||
}
|
||||
@@ -629,7 +622,7 @@ class AttributeDriver implements MappingDriver
|
||||
* 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
|
||||
{
|
||||
@@ -677,7 +670,7 @@ class AttributeDriver implements MappingDriver
|
||||
* Parse the given JoinColumn as array
|
||||
*
|
||||
* @return mixed[]
|
||||
* @psalm-return array{
|
||||
* @phpstan-return array{
|
||||
* name: string|null,
|
||||
* unique: bool,
|
||||
* nullable: bool,
|
||||
@@ -709,7 +702,7 @@ class AttributeDriver implements MappingDriver
|
||||
* Parse the given Column as array
|
||||
*
|
||||
* @return mixed[]
|
||||
* @psalm-return array{
|
||||
* @phpstan-return array{
|
||||
* fieldName: string,
|
||||
* type: mixed,
|
||||
* scale: int,
|
||||
|
||||
@@ -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 MappingAttribute
|
||||
*/
|
||||
|
||||
@@ -61,7 +61,7 @@ class DatabaseDriver implements MappingDriver
|
||||
/** @var array<class-string, string> */
|
||||
private array $classToTableNames = [];
|
||||
|
||||
/** @psalm-var array<string, Table> */
|
||||
/** @phpstan-var array<string, Table> */
|
||||
private array $manyToManyTables = [];
|
||||
|
||||
/** @var mixed[] */
|
||||
@@ -126,8 +126,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
|
||||
*/
|
||||
public function setTables(array $entityTables, array $manyToManyTables): void
|
||||
{
|
||||
@@ -366,7 +366,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,
|
||||
|
||||
35
src/Mapping/Driver/LoadMappingFileImplementation.php
Normal file
35
src/Mapping/Driver/LoadMappingFileImplementation.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Mapping\Driver;
|
||||
|
||||
use Doctrine\Persistence\Mapping\StaticReflectionService;
|
||||
|
||||
use function class_exists;
|
||||
|
||||
if (! class_exists(StaticReflectionService::class)) {
|
||||
/** @internal */
|
||||
trait LoadMappingFileImplementation
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function loadMappingFile($file): array
|
||||
{
|
||||
return $this->doLoadMappingFile($file);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/** @internal */
|
||||
trait LoadMappingFileImplementation
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function loadMappingFile($file)
|
||||
{
|
||||
return $this->doLoadMappingFile($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,13 @@ trait ReflectionBasedDriver
|
||||
*/
|
||||
private function isRepeatedPropertyDeclaration(ReflectionProperty $property, ClassMetadata $metadata): bool
|
||||
{
|
||||
/** @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
|
||||
|
||||
@@ -43,6 +43,8 @@ use function strtoupper;
|
||||
*/
|
||||
class XmlDriver extends FileDriver
|
||||
{
|
||||
use LoadMappingFileImplementation;
|
||||
|
||||
public const DEFAULT_FILE_EXTENSION = '.dcm.xml';
|
||||
|
||||
/**
|
||||
@@ -408,7 +410,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
|
||||
@@ -538,7 +539,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
|
||||
@@ -666,7 +666,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|null $options): array
|
||||
{
|
||||
@@ -701,7 +701,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,
|
||||
@@ -745,7 +745,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,
|
||||
@@ -831,7 +831,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
|
||||
{
|
||||
@@ -858,7 +858,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
|
||||
{
|
||||
@@ -878,10 +878,8 @@ class XmlDriver extends FileDriver
|
||||
return $cascades;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function loadMappingFile($file)
|
||||
/** @return array<class-string, SimpleXMLElement> */
|
||||
private function doLoadMappingFile(string $file): array
|
||||
{
|
||||
$this->validateMapping($file);
|
||||
$result = [];
|
||||
|
||||
@@ -48,7 +48,7 @@ final class EmbeddedClassMapping implements ArrayAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* class: class-string,
|
||||
* columnPrefix?: false|string|null,
|
||||
* declaredField?: string|null,
|
||||
|
||||
@@ -11,7 +11,7 @@ use Doctrine\ORM\EntityRepository;
|
||||
#[Attribute(Attribute::TARGET_CLASS)]
|
||||
final class Entity implements MappingAttribute
|
||||
{
|
||||
/** @psalm-param class-string<EntityRepository<T>>|null $repositoryClass */
|
||||
/** @phpstan-param class-string<EntityRepository<T>>|null $repositoryClass */
|
||||
public function __construct(
|
||||
public readonly string|null $repositoryClass = null,
|
||||
public readonly bool $readOnly = false,
|
||||
|
||||
@@ -26,7 +26,7 @@ final class FieldMapping implements ArrayAccess
|
||||
public bool|null $notInsertable = null;
|
||||
public bool|null $notUpdatable = null;
|
||||
public string|null $columnDefinition = null;
|
||||
/** @psalm-var ClassMetadata::GENERATED_*|null */
|
||||
/** @phpstan-var ClassMetadata::GENERATED_*|null */
|
||||
public int|null $generated = null;
|
||||
/** @var class-string<BackedEnum>|null */
|
||||
public string|null $enumType = null;
|
||||
@@ -85,7 +85,7 @@ final class FieldMapping implements ArrayAccess
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $mappingArray
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* type: string,
|
||||
* fieldName: string,
|
||||
* columnName: string,
|
||||
|
||||
@@ -9,7 +9,7 @@ use Attribute;
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final class GeneratedValue implements MappingAttribute
|
||||
{
|
||||
/** @psalm-param 'AUTO'|'SEQUENCE'|'IDENTITY'|'NONE'|'CUSTOM' $strategy */
|
||||
/** @phpstan-param 'AUTO'|'SEQUENCE'|'IDENTITY'|'NONE'|'CUSTOM' $strategy */
|
||||
public function __construct(
|
||||
public readonly string $strategy = 'AUTO',
|
||||
) {
|
||||
|
||||
33
src/Mapping/GetReflectionClassImplementation.php
Normal file
33
src/Mapping/GetReflectionClassImplementation.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\ORM\Mapping;
|
||||
|
||||
use Doctrine\Persistence\Mapping\StaticReflectionService;
|
||||
use ReflectionClass;
|
||||
|
||||
use function class_exists;
|
||||
|
||||
if (! class_exists(StaticReflectionService::class)) {
|
||||
trait GetReflectionClassImplementation
|
||||
{
|
||||
public function getReflectionClass(): ReflectionClass
|
||||
{
|
||||
return $this->reflClass;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
trait GetReflectionClassImplementation
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* Can return null when using static reflection, in violation of the LSP
|
||||
*/
|
||||
public function getReflectionClass(): ReflectionClass|null
|
||||
{
|
||||
return $this->reflClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ use Attribute;
|
||||
#[Attribute(Attribute::TARGET_CLASS)]
|
||||
final class InheritanceType implements MappingAttribute
|
||||
{
|
||||
/** @psalm-param 'NONE'|'JOINED'|'SINGLE_TABLE' $value */
|
||||
/** @phpstan-param 'NONE'|'JOINED'|'SINGLE_TABLE' $value */
|
||||
public function __construct(
|
||||
public readonly string $value,
|
||||
) {
|
||||
|
||||
@@ -31,7 +31,7 @@ final class JoinColumnMapping implements ArrayAccess
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $mappingArray
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* name: string,
|
||||
* referencedColumnName: string,
|
||||
* unique?: bool|null,
|
||||
|
||||
@@ -33,7 +33,7 @@ final class JoinTableMapping implements ArrayAccess
|
||||
|
||||
/**
|
||||
* @param mixed[] $mappingArray
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* name: string,
|
||||
* quoted?: bool|null,
|
||||
* joinColumns?: mixed[],
|
||||
|
||||
@@ -12,7 +12,7 @@ final class ManyToMany implements MappingAttribute
|
||||
/**
|
||||
* @param class-string $targetEntity
|
||||
* @param string[]|null $cascade
|
||||
* @psalm-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
|
||||
* @phpstan-param 'LAZY'|'EAGER'|'EXTRA_LAZY' $fetch
|
||||
*/
|
||||
public function __construct(
|
||||
public readonly string $targetEntity,
|
||||
|
||||
@@ -37,7 +37,7 @@ final class ManyToManyOwningSideMapping extends ToManyOwningSideMapping implemen
|
||||
|
||||
/**
|
||||
* @param mixed[] $mappingArray
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName: string,
|
||||
* sourceEntity: class-string,
|
||||
* targetEntity: class-string,
|
||||
|
||||
@@ -12,7 +12,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(
|
||||
public readonly string|null $targetEntity = null,
|
||||
|
||||
@@ -12,7 +12,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(
|
||||
public readonly string|null $targetEntity = null,
|
||||
|
||||
@@ -8,7 +8,7 @@ final class OneToManyAssociationMapping extends ToManyInverseSideMapping
|
||||
{
|
||||
/**
|
||||
* @param mixed[] $mappingArray
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName: string,
|
||||
* sourceEntity: class-string,
|
||||
* targetEntity: class-string,
|
||||
@@ -41,7 +41,7 @@ final class OneToManyAssociationMapping extends ToManyInverseSideMapping
|
||||
|
||||
/**
|
||||
* @param mixed[] $mappingArray
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName: string,
|
||||
* sourceEntity: class-string,
|
||||
* targetEntity: class-string,
|
||||
|
||||
@@ -12,7 +12,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(
|
||||
public readonly string|null $targetEntity = null,
|
||||
|
||||
@@ -52,7 +52,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): array;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ final class ReflectionEmbeddedProperty extends ReflectionProperty
|
||||
/**
|
||||
* @param ReflectionProperty $parentProperty reflection property of the class where the embedded object has to be put
|
||||
* @param ReflectionProperty $childProperty reflection property of the embedded object
|
||||
* @psalm-param class-string $embeddedClass
|
||||
* @phpstan-param class-string $embeddedClass
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly ReflectionProperty $parentProperty,
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace Doctrine\ORM\Mapping;
|
||||
|
||||
interface ToManyAssociationMapping
|
||||
{
|
||||
/** @psalm-assert-if-true string $this->indexBy() */
|
||||
/** @phpstan-assert-if-true string $this->indexBy() */
|
||||
public function isIndexed(): bool;
|
||||
|
||||
public function indexBy(): string;
|
||||
|
||||
@@ -32,7 +32,7 @@ trait ToManyAssociationMappingImplementation
|
||||
return $this->orderBy;
|
||||
}
|
||||
|
||||
/** @psalm-assert-if-true !null $this->indexBy */
|
||||
/** @phpstan-assert-if-true !null $this->indexBy */
|
||||
final public function isIndexed(): bool
|
||||
{
|
||||
return $this->indexBy !== null;
|
||||
|
||||
@@ -9,7 +9,7 @@ abstract class ToOneInverseSideMapping extends InverseSideMapping
|
||||
/**
|
||||
* @param mixed[] $mappingArray
|
||||
* @param class-string $name
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName: string,
|
||||
* sourceEntity: class-string,
|
||||
* targetEntity: class-string,
|
||||
|
||||
@@ -27,7 +27,7 @@ abstract class ToOneOwningSideMapping extends OwningSideMapping implements ToOne
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $mappingArray
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName: string,
|
||||
* sourceEntity: class-string,
|
||||
* targetEntity: class-string,
|
||||
@@ -74,7 +74,7 @@ abstract class ToOneOwningSideMapping extends OwningSideMapping implements ToOne
|
||||
/**
|
||||
* @param mixed[] $mappingArray
|
||||
* @param class-string $name
|
||||
* @psalm-param array{
|
||||
* @phpstan-param array{
|
||||
* fieldName: string,
|
||||
* sourceEntity: class-string,
|
||||
* targetEntity: class-string,
|
||||
|
||||
@@ -35,8 +35,8 @@ use function strtoupper;
|
||||
* Similarly, if you remove entities from a collection that is part of a one-many
|
||||
* mapping this will only result in the nulling out of the foreign keys on flush.
|
||||
*
|
||||
* @psalm-template TKey of array-key
|
||||
* @psalm-template T
|
||||
* @phpstan-template TKey of array-key
|
||||
* @phpstan-template T
|
||||
* @template-extends AbstractLazyCollection<TKey,T>
|
||||
* @template-implements Selectable<TKey,T>
|
||||
*/
|
||||
@@ -46,7 +46,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
* A snapshot of the collection at the moment it was fetched from the database.
|
||||
* This is used to create a diff of the collection at commit time.
|
||||
*
|
||||
* @psalm-var array<string|int, mixed>
|
||||
* @phpstan-var array<string|int, mixed>
|
||||
*/
|
||||
private array $snapshot = [];
|
||||
|
||||
@@ -80,7 +80,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
*
|
||||
* @param EntityManagerInterface $em The EntityManager the collection will be associated with.
|
||||
* @param ClassMetadata $typeClass The class descriptor of the entity type of this collection.
|
||||
* @psalm-param Collection<TKey, T>&Selectable<TKey, T> $collection The collection elements.
|
||||
* @phpstan-param Collection<TKey, T>&Selectable<TKey, T> $collection The collection elements.
|
||||
*/
|
||||
public function __construct(
|
||||
private EntityManagerInterface|null $em,
|
||||
@@ -202,7 +202,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
* INTERNAL:
|
||||
* Returns the last snapshot of the elements in the collection.
|
||||
*
|
||||
* @psalm-return array<string|int, mixed> The last snapshot of the elements.
|
||||
* @phpstan-return array<string|int, mixed> The last snapshot of the elements.
|
||||
*/
|
||||
public function getSnapshot(): array
|
||||
{
|
||||
@@ -492,7 +492,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
* with circular references. This solution seems simpler and works well.
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return array{0: string, 1: string}
|
||||
* @phpstan-return array{0: string, 1: string}
|
||||
*/
|
||||
public function __sleep(): array
|
||||
{
|
||||
@@ -504,6 +504,20 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
$this->em = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function first()
|
||||
{
|
||||
if (! $this->initialized && ! $this->isDirty && $this->getMapping()->fetch === ClassMetadata::FETCH_EXTRA_LAZY) {
|
||||
$persister = $this->getUnitOfWork()->getCollectionPersister($this->getMapping());
|
||||
|
||||
return array_values($persister->slice($this, 0, 1))[0] ?? false;
|
||||
}
|
||||
|
||||
return parent::first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a slice of $length elements starting at position $offset from the Collection.
|
||||
*
|
||||
@@ -512,7 +526,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
* selected slice and NOT change the elements contained in the collection slice is called on.
|
||||
*
|
||||
* @return mixed[]
|
||||
* @psalm-return array<TKey,T>
|
||||
* @phpstan-return array<TKey,T>
|
||||
*/
|
||||
public function slice(int $offset, int|null $length = null): array
|
||||
{
|
||||
@@ -554,7 +568,7 @@ final class PersistentCollection extends AbstractLazyCollection implements Selec
|
||||
* Selects all elements from a selectable that match the expression and
|
||||
* return a new collection containing these elements.
|
||||
*
|
||||
* @psalm-return Collection<TKey, T>
|
||||
* @phpstan-return Collection<TKey, T>
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
|
||||
@@ -292,7 +292,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* @return string[] ordered tuple:
|
||||
* - JOIN condition to add to the SQL
|
||||
* - WHERE condition to add to the SQL
|
||||
* @psalm-return array{0: string, 1: string}
|
||||
* @phpstan-return array{0: string, 1: string}
|
||||
*/
|
||||
public function getFilterSql(AssociationMapping $mapping): array
|
||||
{
|
||||
@@ -340,7 +340,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* Generate ON condition
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
protected function getOnConditionSQL(AssociationMapping $mapping): array
|
||||
{
|
||||
@@ -412,7 +412,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
*
|
||||
* @return string[]|string[][] ordered tuple containing the SQL to be executed and an array
|
||||
* of types for bound parameters
|
||||
* @psalm-return array{0: string, 1: list<string>}
|
||||
* @phpstan-return array{0: string, 1: list<string>}
|
||||
*/
|
||||
protected function getDeleteRowSQL(PersistentCollection $collection): array
|
||||
{
|
||||
@@ -447,7 +447,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* Internal note: Order of the parameters must be the same as the order of the columns in getDeleteRowSql.
|
||||
*
|
||||
* @return mixed[]
|
||||
* @psalm-return list<mixed>
|
||||
* @phpstan-return list<mixed>
|
||||
*/
|
||||
protected function getDeleteRowSQLParameters(PersistentCollection $collection, object $element): array
|
||||
{
|
||||
@@ -459,7 +459,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
*
|
||||
* @return string[]|string[][] ordered tuple containing the SQL to be executed and an array
|
||||
* of types for bound parameters
|
||||
* @psalm-return array{0: string, 1: list<string>}
|
||||
* @phpstan-return array{0: string, 1: list<string>}
|
||||
*/
|
||||
protected function getInsertRowSQL(PersistentCollection $collection): array
|
||||
{
|
||||
@@ -496,7 +496,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* Internal note: Order of the parameters must be the same as the order of the columns in getInsertRowSql.
|
||||
*
|
||||
* @return mixed[]
|
||||
* @psalm-return list<mixed>
|
||||
* @phpstan-return list<mixed>
|
||||
*/
|
||||
protected function getInsertRowSQLParameters(PersistentCollection $collection, object $element): array
|
||||
{
|
||||
@@ -508,7 +508,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* of the join table columns as specified in ManyToManyMapping#joinTableColumns.
|
||||
*
|
||||
* @return mixed[]
|
||||
* @psalm-return list<mixed>
|
||||
* @phpstan-return list<mixed>
|
||||
*/
|
||||
private function collectJoinTableColumnParameters(
|
||||
PersistentCollection $collection,
|
||||
@@ -557,7 +557,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* - where clauses to be added for filtering
|
||||
* - parameters to be bound for filtering
|
||||
* - types of the parameters to be bound for filtering
|
||||
* @psalm-return array{0: string, 1: list<string>, 2: list<mixed>, 3: list<string>}
|
||||
* @phpstan-return array{0: string, 1: list<string>, 2: list<mixed>, 3: list<string>}
|
||||
*/
|
||||
private function getJoinTableRestrictionsWithKey(
|
||||
PersistentCollection $collection,
|
||||
@@ -647,7 +647,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
* - where clauses to be added for filtering
|
||||
* - parameters to be bound for filtering
|
||||
* - types of the parameters to be bound for filtering
|
||||
* @psalm-return array{0: string, 1: list<string>, 2: list<mixed>, 3: list<string>}
|
||||
* @phpstan-return array{0: string, 1: list<string>, 2: list<mixed>, 3: list<string>}
|
||||
*/
|
||||
private function getJoinTableRestrictions(
|
||||
PersistentCollection $collection,
|
||||
|
||||
@@ -128,7 +128,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* Queued inserts.
|
||||
*
|
||||
* @psalm-var array<int, object>
|
||||
* @phpstan-var array<int, object>
|
||||
*/
|
||||
protected array $queuedInserts = [];
|
||||
|
||||
@@ -173,6 +173,8 @@ class BasicEntityPersister implements EntityPersister
|
||||
private readonly CachedPersisterContext $limitsHandlingContext;
|
||||
private readonly CachedPersisterContext $noLimitsContext;
|
||||
|
||||
private string|null $filterHash = null;
|
||||
|
||||
/**
|
||||
* Initializes a new <tt>BasicEntityPersister</tt> that uses the given EntityManager
|
||||
* and persists instances of the class described by the given ClassMetadata descriptor.
|
||||
@@ -340,7 +342,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
* @param mixed[] $id
|
||||
*
|
||||
* @return list<ParameterType|int|string>
|
||||
* @psalm-return list<ParameterType::*|ArrayParameterType::*|string>
|
||||
* @phpstan-return list<ParameterType::*|ArrayParameterType::*|string>
|
||||
*/
|
||||
final protected function extractIdentifierTypes(array $id, ClassMetadata $versionedClass): array
|
||||
{
|
||||
@@ -584,7 +586,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
* @param bool $isInsert Whether the data to be prepared refers to an insert statement.
|
||||
*
|
||||
* @return mixed[][] The prepared data.
|
||||
* @psalm-return array<string, array<array-key, mixed|null>>
|
||||
* @phpstan-return array<string, array<array-key, mixed|null>>
|
||||
*/
|
||||
protected function prepareUpdateData(object $entity, bool $isInsert = false): array
|
||||
{
|
||||
@@ -703,7 +705,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
* @param object $entity The entity for which to prepare the data.
|
||||
*
|
||||
* @return mixed[][] The prepared data for the tables to update.
|
||||
* @psalm-return array<string, mixed[]>
|
||||
* @phpstan-return array<string, mixed[]>
|
||||
*/
|
||||
protected function prepareInsertData(object $entity): array
|
||||
{
|
||||
@@ -1164,7 +1166,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* Gets the ORDER BY SQL snippet for ordered collections.
|
||||
*
|
||||
* @psalm-param array<string, string> $orderBy
|
||||
* @phpstan-param array<string, string> $orderBy
|
||||
*
|
||||
* @throws InvalidOrientation
|
||||
* @throws InvalidFindByCall
|
||||
@@ -1229,7 +1231,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
*/
|
||||
protected function getSelectColumnsSQL(): string
|
||||
{
|
||||
if ($this->currentPersisterContext->selectColumnListSql !== null) {
|
||||
if ($this->currentPersisterContext->selectColumnListSql !== null && $this->filterHash === $this->em->getFilters()->getHash()) {
|
||||
return $this->currentPersisterContext->selectColumnListSql;
|
||||
}
|
||||
|
||||
@@ -1339,6 +1341,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
}
|
||||
|
||||
$this->currentPersisterContext->selectColumnListSql = implode(', ', $columnList);
|
||||
$this->filterHash = $this->em->getFilters()->getHash();
|
||||
|
||||
return $this->currentPersisterContext->selectColumnListSql;
|
||||
}
|
||||
@@ -1445,7 +1448,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
* Subclasses should override this method to alter or change the list of
|
||||
* columns placed in the INSERT statements used by the persister.
|
||||
*
|
||||
* @psalm-return list<string>
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
protected function getInsertColumnList(): array
|
||||
{
|
||||
@@ -1497,7 +1500,15 @@ class BasicEntityPersister implements EntityPersister
|
||||
$tableAlias = $this->getSQLTableAlias($class->name, $root);
|
||||
$fieldMapping = $class->fieldMappings[$field];
|
||||
$sql = sprintf('%s.%s', $tableAlias, $this->quoteStrategy->getColumnName($field, $class, $this->platform));
|
||||
$columnAlias = $this->getSQLColumnAlias($fieldMapping->columnName);
|
||||
|
||||
$columnAlias = null;
|
||||
if ($this->currentPersisterContext->rsm->hasColumnAliasByField($alias, $field)) {
|
||||
$columnAlias = $this->currentPersisterContext->rsm->getColumnAliasByField($alias, $field);
|
||||
}
|
||||
|
||||
if ($columnAlias === null) {
|
||||
$columnAlias = $this->getSQLColumnAlias($fieldMapping->columnName);
|
||||
}
|
||||
|
||||
$this->currentPersisterContext->rsm->addFieldResult($alias, $columnAlias, $field);
|
||||
if (! empty($fieldMapping->enumType)) {
|
||||
@@ -1560,7 +1571,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* Gets the FROM and optionally JOIN conditions to lock the entity managed by this persister.
|
||||
*
|
||||
* @psalm-param LockMode::* $lockMode
|
||||
* @phpstan-param LockMode::* $lockMode
|
||||
*/
|
||||
protected function getLockTablesSql(LockMode|int $lockMode): string
|
||||
{
|
||||
@@ -1662,7 +1673,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
* Builds the left-hand-side of a where condition statement.
|
||||
*
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
* @phpstan-return list<string>
|
||||
*
|
||||
* @throws InvalidFindByCall
|
||||
* @throws UnrecognizedField
|
||||
@@ -1737,7 +1748,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
* Subclasses are supposed to override this method if they intend to change
|
||||
* or alter the criteria by which entities are selected.
|
||||
*
|
||||
* @psalm-param array<string, mixed> $criteria
|
||||
* @phpstan-param array<string, mixed> $criteria
|
||||
*/
|
||||
protected function getSelectConditionSQL(array $criteria, AssociationMapping|null $assoc = null): string
|
||||
{
|
||||
@@ -1861,7 +1872,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
* - class to which the field belongs to
|
||||
*
|
||||
* @return mixed[][]
|
||||
* @psalm-return array{0: array, 1: list<ParameterType::*|ArrayParameterType::*|string>}
|
||||
* @phpstan-return array{0: array, 1: list<ParameterType::*|ArrayParameterType::*|string>}
|
||||
*/
|
||||
private function expandToManyParameters(array $criteria): array
|
||||
{
|
||||
@@ -1884,7 +1895,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
* Infers field types to be used by parameter type casting.
|
||||
*
|
||||
* @return list<ParameterType|ArrayParameterType|int|string>
|
||||
* @psalm-return list<ParameterType::*|ArrayParameterType::*|string>
|
||||
* @phpstan-return list<ParameterType::*|ArrayParameterType::*|string>
|
||||
*
|
||||
* @throws QueryException
|
||||
*/
|
||||
@@ -1926,7 +1937,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
return $types;
|
||||
}
|
||||
|
||||
/** @psalm-return ArrayParameterType::* */
|
||||
/** @phpstan-return ArrayParameterType::* */
|
||||
private function getArrayBindingType(ParameterType|int|string $type): ArrayParameterType|int
|
||||
{
|
||||
if (! $type instanceof ParameterType) {
|
||||
@@ -1963,7 +1974,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* Retrieves an individual parameter value.
|
||||
*
|
||||
* @psalm-return list<mixed>
|
||||
* @phpstan-return list<mixed>
|
||||
*/
|
||||
private function getIndividualValue(mixed $value): array
|
||||
{
|
||||
@@ -2094,7 +2105,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
* @psalm-return list<string>
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
protected function getClassIdentifiersTypes(ClassMetadata $class): array
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user