mirror of
https://github.com/doctrine/orm.git
synced 2026-03-25 23:42:19 +01:00
Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78dd074266 | ||
|
|
ff22a00fcf | ||
|
|
02e8ff9663 | ||
|
|
2e75a7f1c1 | ||
|
|
152b0e3d65 | ||
|
|
9d11fdd3da | ||
|
|
87f1ba74e0 | ||
|
|
ee70178314 | ||
|
|
ab148d3d9d | ||
|
|
3924c38fab | ||
|
|
9814078a2c | ||
|
|
6de5684fd9 | ||
|
|
c142503a52 | ||
|
|
01c178b297 | ||
|
|
ffa50a777f | ||
|
|
649048f745 | ||
|
|
15537bc218 | ||
|
|
bc95c7c08d | ||
|
|
3df11d518c | ||
|
|
c1becd54e6 | ||
|
|
e4d7df29c2 | ||
|
|
608705427e | ||
|
|
9f19310f27 | ||
|
|
e38278bfca | ||
|
|
f18de9d569 | ||
|
|
37f76a8381 | ||
|
|
b62292256a | ||
|
|
b138395194 | ||
|
|
dede2d775a | ||
|
|
c502190712 | ||
|
|
5bff0919a7 | ||
|
|
9ef0f5301b | ||
|
|
4989ca6f15 | ||
|
|
32d1e97ce7 | ||
|
|
ca8147b148 | ||
|
|
c8ebea77f0 | ||
|
|
23f22860f1 | ||
|
|
b24586b1b5 | ||
|
|
7d8e51c934 | ||
|
|
2f8f1cfcb8 | ||
|
|
fe5ee705db | ||
|
|
0511a9f790 | ||
|
|
0e3d5e8c82 | ||
|
|
72ffb3bfbf | ||
|
|
2e9a1adc23 | ||
|
|
ffd3f50ad7 | ||
|
|
483b45d449 | ||
|
|
dd4e8fe78f | ||
|
|
7cc210424c | ||
|
|
4fd9e94819 | ||
|
|
587caf88a7 | ||
|
|
1e33b775d3 | ||
|
|
28d9472a38 | ||
|
|
c6955ec056 | ||
|
|
6863272943 | ||
|
|
c472a1535d | ||
|
|
f1a8ee175c | ||
|
|
28dd32790f | ||
|
|
ac19b21a71 | ||
|
|
a7a14cffaf | ||
|
|
ceb04bf3f6 | ||
|
|
ed9ba16ff4 | ||
|
|
fc1bf3b815 | ||
|
|
b6b342cada | ||
|
|
bea4814d55 | ||
|
|
238c15952c | ||
|
|
fdc88ba236 | ||
|
|
c49bf58682 | ||
|
|
ce844d94a0 | ||
|
|
c1f7a60c5b | ||
|
|
d1d13d5956 | ||
|
|
4f8dde2d1e | ||
|
|
e3c320c705 | ||
|
|
831232e05e | ||
|
|
a774cedb24 | ||
|
|
6b8207bb11 | ||
|
|
3d3b5b51cd | ||
|
|
760616291b | ||
|
|
8584da8fdc | ||
|
|
07bb0def60 | ||
|
|
8cf161d8bc | ||
|
|
a2990e1a0a | ||
|
|
d355c4a990 | ||
|
|
88c395c488 | ||
|
|
256d6cb0d7 | ||
|
|
a1fdc6eb6e | ||
|
|
d583460d63 | ||
|
|
79d4cfdce8 | ||
|
|
5301b99533 | ||
|
|
00c7b70211 |
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@12.1.0"
|
||||
uses: "doctrine/.github/.github/workflows/coding-standards.yml@13.0.0"
|
||||
|
||||
20
.github/workflows/composer-lint.yml
vendored
Normal file
20
.github/workflows/composer-lint.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
name: "Composer Lint"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- "*.x"
|
||||
paths:
|
||||
- ".github/workflows/composer-lint.yml"
|
||||
- "composer.json"
|
||||
push:
|
||||
branches:
|
||||
- "*.x"
|
||||
paths:
|
||||
- ".github/workflows/composer-lint.yml"
|
||||
- "composer.json"
|
||||
|
||||
jobs:
|
||||
composer-lint:
|
||||
name: "Composer Lint"
|
||||
uses: "doctrine/.github/.github/workflows/composer-lint.yml@13.0.0"
|
||||
14
.github/workflows/continuous-integration.yml
vendored
14
.github/workflows/continuous-integration.yml
vendored
@@ -68,7 +68,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v6"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
@@ -84,6 +84,10 @@ jobs:
|
||||
run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update"
|
||||
if: "${{ matrix.dbal-version != 'default' }}"
|
||||
|
||||
- name: "Downgrade VarExporter"
|
||||
run: 'composer require --no-update "symfony/var-exporter:^6.4 || ^7.4"'
|
||||
if: "${{ matrix.native_lazy == '0' }}"
|
||||
|
||||
- name: "Install dependencies with Composer"
|
||||
uses: "ramsey/composer-install@v3"
|
||||
with:
|
||||
@@ -203,7 +207,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v6"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
@@ -271,7 +275,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v6"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
@@ -347,7 +351,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v6"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
@@ -411,7 +415,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v6"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
|
||||
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@12.1.0"
|
||||
uses: "doctrine/.github/.github/workflows/documentation.yml@13.0.0"
|
||||
|
||||
2
.github/workflows/phpbench.yml
vendored
2
.github/workflows/phpbench.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v6"
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ on:
|
||||
|
||||
jobs:
|
||||
release:
|
||||
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@12.1.0"
|
||||
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@13.0.0"
|
||||
secrets:
|
||||
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
|
||||
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
|
||||
|
||||
2
.github/workflows/static-analysis.yml
vendored
2
.github/workflows/static-analysis.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: "actions/checkout@v5"
|
||||
uses: "actions/checkout@v6"
|
||||
|
||||
- name: Install PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
{
|
||||
"name": "doctrine/orm",
|
||||
"type": "library",
|
||||
"description": "Object-Relational-Mapper for PHP",
|
||||
"keywords": ["orm", "database"],
|
||||
"homepage": "https://www.doctrine-project.org/projects/orm.html",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
|
||||
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
|
||||
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
|
||||
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
|
||||
{"name": "Marco Pivetta", "email": "ocramius@gmail.com"}
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"orm",
|
||||
"database"
|
||||
],
|
||||
"scripts": {
|
||||
"docs": "composer --working-dir docs update && ./docs/vendor/bin/build-docs.sh @additional_args"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true,
|
||||
"phpstan/extension-installer": true
|
||||
"authors": [
|
||||
{
|
||||
"name": "Guilherme Blanco",
|
||||
"email": "guilhermeblanco@gmail.com"
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
{
|
||||
"name": "Roman Borschel",
|
||||
"email": "roman@code-factory.org"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin Eberlei",
|
||||
"email": "kontakt@beberlei.de"
|
||||
},
|
||||
{
|
||||
"name": "Jonathan Wage",
|
||||
"email": "jonwage@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Marco Pivetta",
|
||||
"email": "ocramius@gmail.com"
|
||||
}
|
||||
],
|
||||
"homepage": "https://www.doctrine-project.org/projects/orm.html",
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"composer-runtime-api": "^2",
|
||||
"ext-ctype": "*",
|
||||
"composer-runtime-api": "^2",
|
||||
"doctrine/collections": "^2.2",
|
||||
"doctrine/dbal": "^3.8.2 || ^4",
|
||||
"doctrine/deprecations": "^0.5.3 || ^1",
|
||||
@@ -36,35 +43,44 @@
|
||||
"doctrine/lexer": "^3",
|
||||
"doctrine/persistence": "^3.3.1 || ^4",
|
||||
"psr/cache": "^1 || ^2 || ^3",
|
||||
"symfony/console": "^5.4 || ^6.0 || ^7.0",
|
||||
"symfony/var-exporter": "^6.3.9 || ^7.0"
|
||||
"symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0",
|
||||
"symfony/var-exporter": "^6.3.9 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^14.0",
|
||||
"phpbench/phpbench": "^1.0",
|
||||
"phpdocumentor/guides-cli": "^1.4",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan": "2.1.22",
|
||||
"phpstan/phpstan": "2.1.23",
|
||||
"phpstan/phpstan-deprecation-rules": "^2",
|
||||
"phpunit/phpunit": "^10.5.0 || ^11.5",
|
||||
"psr/log": "^1 || ^2 || ^3",
|
||||
"symfony/cache": "^5.4 || ^6.2 || ^7.0"
|
||||
"symfony/cache": "^5.4 || ^6.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "Provides support for XSD validation for XML mapping files",
|
||||
"symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "Doctrine\\ORM\\": "src" }
|
||||
"psr-4": {
|
||||
"Doctrine\\ORM\\": "src"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Tests\\": "tests/Tests",
|
||||
"Doctrine\\Performance\\": "tests/Performance",
|
||||
"Doctrine\\StaticAnalysis\\": "tests/StaticAnalysis",
|
||||
"Doctrine\\Performance\\": "tests/Performance"
|
||||
"Doctrine\\Tests\\": "tests/Tests"
|
||||
}
|
||||
},
|
||||
"archive": {
|
||||
"exclude": ["!vendor", "tests", "*phpunit.xml", "build.xml", "build.properties", "composer.phar", "vendor/satooshi", "lib/vendor", "*.swp"]
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"composer/package-versions-deprecated": true,
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true,
|
||||
"phpstan/extension-installer": true
|
||||
},
|
||||
"sort-packages": true
|
||||
},
|
||||
"scripts": {
|
||||
"docs": "composer --working-dir docs update && ./docs/vendor/bin/build-docs.sh @additional_args"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ If this documentation is not helping to answer questions you have about
|
||||
Doctrine ORM don't panic. You can get help from different sources:
|
||||
|
||||
- There is a :doc:`FAQ <reference/faq>` with answers to frequent questions.
|
||||
- The `Doctrine Mailing List <https://groups.google.com/group/doctrine-user>`_
|
||||
- Slack chat room `#orm <https://www.doctrine-project.org/slack>`_
|
||||
- Report a bug on `GitHub <https://github.com/doctrine/orm/issues>`_.
|
||||
- On `StackOverflow <https://stackoverflow.com/questions/tagged/doctrine-orm>`_
|
||||
|
||||
@@ -182,6 +182,21 @@ Here is a complete list of ``Column``s attributes (all optional):
|
||||
- ``options``: Key-value pairs of options that get passed
|
||||
to the underlying database platform when generating DDL statements.
|
||||
|
||||
Specifying default values
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
While it is possible to specify default values for properties in your
|
||||
PHP class, Doctrine also allows you to specify default values for
|
||||
database columns using the ``default`` key in the ``options`` array of
|
||||
the ``Column`` attribute.
|
||||
|
||||
.. configuration-block::
|
||||
.. literalinclude:: basic-mapping/DefaultValues.php
|
||||
:language: attribute
|
||||
|
||||
.. literalinclude:: basic-mapping/default-values.xml
|
||||
:language: xml
|
||||
|
||||
.. _reference-php-mapping-types:
|
||||
|
||||
PHP Types Mapping
|
||||
|
||||
15
docs/en/reference/basic-mapping/DefaultValues.php
Normal file
15
docs/en/reference/basic-mapping/DefaultValues.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use Doctrine\ORM\Mapping\Column;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
|
||||
#[Entity]
|
||||
class Message
|
||||
{
|
||||
#[Column(options: ['default' => 'Hello World!'])]
|
||||
private string $text;
|
||||
}
|
||||
9
docs/en/reference/basic-mapping/default-values.xml
Normal file
9
docs/en/reference/basic-mapping/default-values.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<doctrine-mapping>
|
||||
<entity name="Message">
|
||||
<field name="text">
|
||||
<options>
|
||||
<option name="default">Hello World!</option>
|
||||
</options>
|
||||
</field>
|
||||
</entity>
|
||||
</doctrine-mapping>
|
||||
@@ -18,30 +18,6 @@ In your mapping configuration, the column definition (for example, the
|
||||
the ``charset`` and ``collation``. The default values are ``utf8`` and
|
||||
``utf8_unicode_ci``, respectively.
|
||||
|
||||
Entity Classes
|
||||
--------------
|
||||
|
||||
How can I add default values to a column?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Doctrine does not support to set the default values in columns through the "DEFAULT" keyword in SQL.
|
||||
This is not necessary however, you can just use your class properties as default values. These are then used
|
||||
upon insert:
|
||||
|
||||
.. code-block:: php
|
||||
|
||||
class User
|
||||
{
|
||||
private const STATUS_DISABLED = 0;
|
||||
private const STATUS_ENABLED = 1;
|
||||
|
||||
private string $algorithm = "sha1";
|
||||
/** @var self::STATUS_* */
|
||||
private int $status = self::STATUS_DISABLED;
|
||||
}
|
||||
|
||||
.
|
||||
|
||||
Mapping
|
||||
-------
|
||||
|
||||
|
||||
@@ -696,12 +696,6 @@ parameters:
|
||||
count: 1
|
||||
path: src/Internal/Hydration/AbstractHydrator.php
|
||||
|
||||
-
|
||||
message: '#^Method Doctrine\\ORM\\Internal\\Hydration\\AbstractHydrator\:\:gatherRowData\(\) should return array\{data\: array\<array\>, newObjects\?\: array\<array\{class\: ReflectionClass, args\: array, obj\: object\}\>, scalars\?\: array\} but returns array\{data\: array, newObjects\: array\<array\{class\: ReflectionClass\<object\>, args\: array, obj\?\: object\}\>, scalars\?\: non\-empty\-array\}\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: src/Internal/Hydration/AbstractHydrator.php
|
||||
|
||||
-
|
||||
message: '#^Method Doctrine\\ORM\\Internal\\Hydration\\AbstractHydrator\:\:getClassMetadata\(\) return type with generic class Doctrine\\ORM\\Mapping\\ClassMetadata does not specify its types\: T$#'
|
||||
identifier: missingType.generics
|
||||
@@ -822,6 +816,12 @@ parameters:
|
||||
count: 1
|
||||
path: src/Internal/HydrationCompleteHandler.php
|
||||
|
||||
-
|
||||
message: '#^Offset int\|null might not exist on array\<int, object\>\.$#'
|
||||
identifier: offsetAccess.notFound
|
||||
count: 1
|
||||
path: src/Internal/StronglyConnectedComponents.php
|
||||
|
||||
-
|
||||
message: '#^Property Doctrine\\ORM\\Internal\\StronglyConnectedComponents\:\:\$representingNodes \(array\<int, object\>\) does not accept array\<int\|string, object\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
@@ -1410,12 +1410,6 @@ parameters:
|
||||
count: 2
|
||||
path: src/Mapping/Driver/DatabaseDriver.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$asset of static method Doctrine\\ORM\\Mapping\\Driver\\DatabaseDriver\:\:getAssetName\(\) expects Doctrine\\DBAL\\Schema\\AbstractAsset, Doctrine\\DBAL\\Schema\\Column\|false given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: src/Mapping/Driver/DatabaseDriver.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#2 \$columnName of method Doctrine\\ORM\\Mapping\\Driver\\DatabaseDriver\:\:getFieldNameForColumn\(\) expects string, string\|false given\.$#'
|
||||
identifier: argument.type
|
||||
@@ -1536,6 +1530,12 @@ parameters:
|
||||
count: 1
|
||||
path: src/Mapping/LegacyReflectionFields.php
|
||||
|
||||
-
|
||||
message: '#^Strict comparison using \!\=\= between array\<string, string\> and null will always evaluate to true\.$#'
|
||||
identifier: notIdentical.alwaysTrue
|
||||
count: 1
|
||||
path: src/Mapping/ManyToManyOwningSideMapping.php
|
||||
|
||||
-
|
||||
message: '#^Method Doctrine\\ORM\\Mapping\\MappedSuperclass\:\:__construct\(\) has parameter \$repositoryClass with generic class Doctrine\\ORM\\EntityRepository but does not specify its types\: T$#'
|
||||
identifier: missingType.generics
|
||||
@@ -2607,7 +2607,7 @@ parameters:
|
||||
-
|
||||
message: '#^Property Doctrine\\ORM\\Query\\Filter\\SQLFilter\:\:\$parameters \(array\<string, array\{type\: string, value\: mixed, is_list\: bool\}\>\) does not accept non\-empty\-array\<string, array\{value\: mixed, type\: Doctrine\\DBAL\\ArrayParameterType\|Doctrine\\DBAL\\ParameterType\|int\|string, is_list\: bool\}\>\.$#'
|
||||
identifier: assign.propertyType
|
||||
count: 1
|
||||
count: 2
|
||||
path: src/Query/Filter/SQLFilter.php
|
||||
|
||||
-
|
||||
@@ -2880,12 +2880,6 @@ parameters:
|
||||
count: 1
|
||||
path: src/Tools/Console/Command/GenerateProxiesCommand.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#2 \$proxyDir of method Doctrine\\ORM\\Proxy\\ProxyFactory\:\:generateProxyClasses\(\) expects string\|null, string\|false given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: src/Tools/Console/Command/GenerateProxiesCommand.php
|
||||
|
||||
-
|
||||
message: '#^Method Doctrine\\ORM\\Tools\\Console\\Command\\MappingDescribeCommand\:\:getClassMetadata\(\) return type with generic class Doctrine\\ORM\\Mapping\\ClassMetadata does not specify its types\: T$#'
|
||||
identifier: missingType.generics
|
||||
@@ -3351,6 +3345,12 @@ parameters:
|
||||
count: 1
|
||||
path: src/UnitOfWork.php
|
||||
|
||||
-
|
||||
message: '#^Access to an undefined property Doctrine\\ORM\\Mapping\\AssociationMapping\:\:\$joinColumns\.$#'
|
||||
identifier: property.notFound
|
||||
count: 1
|
||||
path: src/UnitOfWork.php
|
||||
|
||||
-
|
||||
message: '#^Access to an undefined property Doctrine\\ORM\\Mapping\\ManyToManyInverseSideMapping\|Doctrine\\ORM\\Mapping\\ManyToManyOwningSideMapping\|Doctrine\\ORM\\Mapping\\ManyToOneAssociationMapping\|Doctrine\\ORM\\Mapping\\OneToManyAssociationMapping\|Doctrine\\ORM\\Mapping\\OneToOneInverseSideMapping\|Doctrine\\ORM\\Mapping\\OneToOneOwningSideMapping\:\:\$inversedBy\.$#'
|
||||
identifier: property.notFound
|
||||
@@ -3366,7 +3366,7 @@ parameters:
|
||||
-
|
||||
message: '#^Access to an undefined property Doctrine\\ORM\\Mapping\\ManyToManyInverseSideMapping\|Doctrine\\ORM\\Mapping\\ManyToManyOwningSideMapping\|Doctrine\\ORM\\Mapping\\ManyToOneAssociationMapping\|Doctrine\\ORM\\Mapping\\OneToManyAssociationMapping\|Doctrine\\ORM\\Mapping\\OneToOneInverseSideMapping\|Doctrine\\ORM\\Mapping\\OneToOneOwningSideMapping\:\:\$mappedBy\.$#'
|
||||
identifier: property.notFound
|
||||
count: 1
|
||||
count: 3
|
||||
path: src/UnitOfWork.php
|
||||
|
||||
-
|
||||
|
||||
@@ -98,6 +98,17 @@ parameters:
|
||||
identifier: argument.unresolvableType
|
||||
path: src/Mapping/Driver/DatabaseDriver.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$asset of static method Doctrine\\ORM\\Mapping\\Driver\\DatabaseDriver\:\:getAssetName\(\) expects Doctrine\\DBAL\\Schema\\AbstractAsset, Doctrine\\DBAL\\Schema\\Column\|false given\.$#'
|
||||
identifier: argument.type
|
||||
path: src/Mapping/Driver/DatabaseDriver.php
|
||||
|
||||
-
|
||||
message: '#^Instantiated class Doctrine\\DBAL\\Schema\\DefaultExpression\\\w+ not found\.$#'
|
||||
identifier: class.notFound
|
||||
path: src/Tools/SchemaTool.php
|
||||
|
||||
|
||||
# To be removed in 4.0
|
||||
-
|
||||
message: '#Negated boolean expression is always false\.#'
|
||||
|
||||
@@ -160,6 +160,11 @@ EXCEPTION
|
||||
return new self('You must configure a proxy directory. See docs for details');
|
||||
}
|
||||
|
||||
public static function lazyGhostUnavailable(): self
|
||||
{
|
||||
return new self('Symfony LazyGhost is not available. Please install the "symfony/var-exporter" package version 6.4 or 7 to use this feature or enable PHP 8.4 native lazy objects.');
|
||||
}
|
||||
|
||||
public static function proxyNamespaceRequired(): self
|
||||
{
|
||||
return new self('You must configure a proxy namespace');
|
||||
|
||||
@@ -1668,6 +1668,11 @@ class BasicEntityPersister implements EntityPersister
|
||||
$value = [$value];
|
||||
}
|
||||
|
||||
if ($value === []) {
|
||||
$selectedColumns[] = '1=0';
|
||||
continue;
|
||||
}
|
||||
|
||||
$nullKeys = array_keys($value, null, true);
|
||||
$nonNullValues = array_diff_key($value, array_flip($nullKeys));
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ use function is_dir;
|
||||
use function is_int;
|
||||
use function is_writable;
|
||||
use function ltrim;
|
||||
use function method_exists;
|
||||
use function mkdir;
|
||||
use function preg_match_all;
|
||||
use function random_bytes;
|
||||
@@ -161,6 +162,11 @@ EOPHP;
|
||||
);
|
||||
}
|
||||
|
||||
// @phpstan-ignore function.impossibleType (This method has been removed in Symfony 8)
|
||||
if (! method_exists(ProxyHelper::class, 'generateLazyGhost')) {
|
||||
throw ORMInvalidArgumentException::lazyGhostUnavailable();
|
||||
}
|
||||
|
||||
if (! $proxyDir) {
|
||||
throw ORMInvalidArgumentException::proxyDirectoryRequired();
|
||||
}
|
||||
@@ -464,7 +470,7 @@ EOPHP;
|
||||
|
||||
private function generateUseLazyGhostTrait(ClassMetadata $class): string
|
||||
{
|
||||
// @phpstan-ignore staticMethod.deprecated (Because we support Symfony < 7.3)
|
||||
// @phpstan-ignore staticMethod.notFound (This method has been removed in Symfony 8)
|
||||
$code = ProxyHelper::generateLazyGhost($class->getReflectionClass());
|
||||
$code = substr($code, 7 + (int) strpos($code, "\n{"));
|
||||
$code = substr($code, 0, (int) strpos($code, "\n}"));
|
||||
|
||||
@@ -18,11 +18,12 @@ trait ApplicationCompatibility
|
||||
{
|
||||
private static function addCommandToApplication(Application $application, Command $command): Command|null
|
||||
{
|
||||
// @phpstan-ignore function.alreadyNarrowedType (This method did not exist before Symfony 7.4)
|
||||
if (method_exists(Application::class, 'addCommand')) {
|
||||
// @phpstan-ignore method.notFound (This method will be added in Symfony 7.4)
|
||||
return $application->addCommand($command);
|
||||
}
|
||||
|
||||
// @phpstan-ignore method.notFound
|
||||
return $application->add($command);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Schema\AbstractAsset;
|
||||
use Doctrine\DBAL\Schema\AbstractSchemaManager;
|
||||
use Doctrine\DBAL\Schema\ComparatorConfig;
|
||||
use Doctrine\DBAL\Schema\DefaultExpression;
|
||||
use Doctrine\DBAL\Schema\DefaultExpression\CurrentDate;
|
||||
use Doctrine\DBAL\Schema\DefaultExpression\CurrentTime;
|
||||
use Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp;
|
||||
use Doctrine\DBAL\Schema\ForeignKeyConstraintEditor;
|
||||
use Doctrine\DBAL\Schema\Index;
|
||||
use Doctrine\DBAL\Schema\Index\IndexedColumn;
|
||||
@@ -18,6 +22,7 @@ use Doctrine\DBAL\Schema\NamedObject;
|
||||
use Doctrine\DBAL\Schema\PrimaryKeyConstraint;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Schema\Table;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use Doctrine\ORM\Mapping\AssociationMapping;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
@@ -46,6 +51,7 @@ use function count;
|
||||
use function current;
|
||||
use function implode;
|
||||
use function in_array;
|
||||
use function interface_exists;
|
||||
use function is_numeric;
|
||||
use function method_exists;
|
||||
use function preg_match;
|
||||
@@ -489,6 +495,34 @@ class SchemaTool
|
||||
// the 'default' option can be overwritten here
|
||||
$options = $this->gatherColumnOptions($mapping) + $options;
|
||||
|
||||
if (isset($options['default']) && interface_exists(DefaultExpression::class)) {
|
||||
if (
|
||||
in_array($mapping->type, [
|
||||
Types::DATETIME_MUTABLE,
|
||||
Types::DATETIME_IMMUTABLE,
|
||||
Types::DATETIMETZ_MUTABLE,
|
||||
Types::DATETIMETZ_IMMUTABLE,
|
||||
], true)
|
||||
&& $options['default'] === $this->platform->getCurrentTimestampSQL()
|
||||
) {
|
||||
$options['default'] = new CurrentTimestamp();
|
||||
}
|
||||
|
||||
if (
|
||||
in_array($mapping->type, [Types::TIME_MUTABLE, Types::TIME_IMMUTABLE], true)
|
||||
&& $options['default'] === $this->platform->getCurrentTimeSQL()
|
||||
) {
|
||||
$options['default'] = new CurrentTime();
|
||||
}
|
||||
|
||||
if (
|
||||
in_array($mapping->type, [Types::DATE_MUTABLE, Types::DATE_IMMUTABLE], true)
|
||||
&& $options['default'] === $this->platform->getCurrentDateSQL()
|
||||
) {
|
||||
$options['default'] = new CurrentDate();
|
||||
}
|
||||
}
|
||||
|
||||
if ($class->isIdGeneratorIdentity() && $class->getIdentifierFieldNames() === [$mapping->fieldName]) {
|
||||
$options['autoincrement'] = true;
|
||||
}
|
||||
@@ -1009,7 +1043,7 @@ class SchemaTool
|
||||
{
|
||||
return $asset instanceof NamedObject
|
||||
? $asset->getObjectName()->toString()
|
||||
// DBAL < 4.4
|
||||
// @phpstan-ignore method.deprecated (DBAL < 4.4)
|
||||
: $asset->getName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ use function array_map;
|
||||
use function array_sum;
|
||||
use function array_values;
|
||||
use function assert;
|
||||
use function count;
|
||||
use function current;
|
||||
use function get_debug_type;
|
||||
use function implode;
|
||||
@@ -2594,8 +2595,14 @@ class UnitOfWork implements PropertyChangedListener
|
||||
$reflField->setValue($entity, $pColl);
|
||||
|
||||
if ($hints['fetchMode'][$class->name][$field] === ClassMetadata::FETCH_EAGER) {
|
||||
$isIteration = isset($hints[Query::HINT_INTERNAL_ITERATION]) && $hints[Query::HINT_INTERNAL_ITERATION];
|
||||
if (! $isIteration && $assoc->isOneToMany() && ! $targetClass->isIdentifierComposite && ! $assoc->isIndexed()) {
|
||||
if (
|
||||
$assoc->isOneToMany()
|
||||
// is iteration
|
||||
&& ! (isset($hints[Query::HINT_INTERNAL_ITERATION]) && $hints[Query::HINT_INTERNAL_ITERATION])
|
||||
// is foreign key composite
|
||||
&& ! ($targetClass->hasAssociation($assoc->mappedBy) && count($targetClass->getAssociationMapping($assoc->mappedBy)->joinColumns) > 1)
|
||||
&& ! $assoc->isIndexed()
|
||||
) {
|
||||
$this->scheduleCollectionForBatchLoading($pColl, $class);
|
||||
} else {
|
||||
$this->loadCollection($pColl);
|
||||
|
||||
@@ -24,11 +24,16 @@ class RootEntity
|
||||
#[ORM\OneToMany(mappedBy: 'root', targetEntity: SecondLevel::class, fetch: 'EAGER')]
|
||||
private Collection $secondLevel;
|
||||
|
||||
/** @var Collection<int, SecondLevelWithoutCompositePrimaryKey> */
|
||||
#[ORM\OneToMany(mappedBy: 'root', targetEntity: SecondLevelWithoutCompositePrimaryKey::class, fetch: 'EAGER')]
|
||||
private Collection $anotherSecondLevel;
|
||||
|
||||
public function __construct(int $id, string $other)
|
||||
{
|
||||
$this->otherKey = $other;
|
||||
$this->secondLevel = new ArrayCollection();
|
||||
$this->id = $id;
|
||||
$this->otherKey = $other;
|
||||
$this->secondLevel = new ArrayCollection();
|
||||
$this->anotherSecondLevel = new ArrayCollection();
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getId(): int|null
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Tests\Models\EagerFetchedCompositeOneToMany;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
#[ORM\Entity]
|
||||
class SecondLevelWithoutCompositePrimaryKey
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\GeneratedValue]
|
||||
#[ORM\Column(type: 'integer', nullable: false)]
|
||||
private int|null $id;
|
||||
|
||||
#[ORM\ManyToOne(targetEntity: RootEntity::class, inversedBy: 'anotherSecondLevel')]
|
||||
#[ORM\JoinColumn(name: 'root_id', referencedColumnName: 'id')]
|
||||
#[ORM\JoinColumn(name: 'root_other_key', referencedColumnName: 'other_key')]
|
||||
private RootEntity $root;
|
||||
|
||||
public function __construct(RootEntity $upper)
|
||||
{
|
||||
$this->root = $upper;
|
||||
}
|
||||
|
||||
public function getId(): int|null
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
43
tests/Tests/ORM/Functional/DefaultTimeExpressionTest.php
Normal file
43
tests/Tests/ORM/Functional/DefaultTimeExpressionTest.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class DefaultTimeExpressionTest extends OrmFunctionalTestCase
|
||||
{
|
||||
use VerifyDeprecations;
|
||||
|
||||
public function testUsingTimeRelatedDefaultExpressionCausesNoDbalDeprecation(): void
|
||||
{
|
||||
$this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/dbal/pull/7195');
|
||||
|
||||
$this->createSchemaForModels(TimeEntity::class);
|
||||
}
|
||||
}
|
||||
|
||||
#[ORM\Entity]
|
||||
class TimeEntity
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column]
|
||||
public int $id;
|
||||
|
||||
#[ORM\Column(options: ['default' => 'CURRENT_TIMESTAMP'])]
|
||||
public DateTime $createdAt;
|
||||
|
||||
#[ORM\Column(options: ['default' => 'CURRENT_TIMESTAMP'])]
|
||||
public DateTimeImmutable $createdAtImmutable;
|
||||
|
||||
#[ORM\Column(options: ['default' => 'CURRENT_TIME'])]
|
||||
public DateTime $createdTime;
|
||||
|
||||
#[ORM\Column(options: ['default' => 'CURRENT_DATE'])]
|
||||
public DateTime $createdDate;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ namespace Doctrine\Tests\ORM\Functional;
|
||||
|
||||
use Doctrine\Tests\Models\EagerFetchedCompositeOneToMany\RootEntity;
|
||||
use Doctrine\Tests\Models\EagerFetchedCompositeOneToMany\SecondLevel;
|
||||
use Doctrine\Tests\Models\EagerFetchedCompositeOneToMany\SecondLevelWithoutCompositePrimaryKey;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
|
||||
@@ -14,7 +15,7 @@ final class EagerFetchOneToManyWithCompositeKeyTest extends OrmFunctionalTestCas
|
||||
#[Group('GH11154')]
|
||||
public function testItDoesNotThrowAnExceptionWhenTriggeringALoad(): void
|
||||
{
|
||||
$this->setUpEntitySchema([RootEntity::class, SecondLevel::class]);
|
||||
$this->setUpEntitySchema([RootEntity::class, SecondLevel::class, SecondLevelWithoutCompositePrimaryKey::class]);
|
||||
|
||||
$a1 = new RootEntity(1, 'A');
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ use Generator;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
|
||||
use ReflectionMethod;
|
||||
use Symfony\Component\VarExporter\Instantiator;
|
||||
use Symfony\Component\VarExporter\VarExporter;
|
||||
|
||||
use function file_get_contents;
|
||||
@@ -78,11 +77,6 @@ class ParserResultSerializationTest extends OrmFunctionalTestCase
|
||||
},
|
||||
];
|
||||
|
||||
$instantiatorMethod = new ReflectionMethod(Instantiator::class, 'instantiate');
|
||||
if ($instantiatorMethod->getReturnType() === null) {
|
||||
self::markTestSkipped('symfony/var-exporter 5.4+ is required.');
|
||||
}
|
||||
|
||||
yield 'symfony/var-exporter' => [
|
||||
static function (ParserResult $parserResult): ParserResult {
|
||||
return eval('return ' . VarExporter::export($parserResult) . ';');
|
||||
|
||||
@@ -474,7 +474,9 @@ class QueryTest extends OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery('select a, u, a.topic, a.text from ' . CmsArticle::class . ' a, ' . CmsUser::class . ' u WHERE a.user = u ');
|
||||
$query = $this->_em->createQuery(
|
||||
'select a, u, a.topic, a.text from ' . CmsArticle::class . ' a, ' . CmsUser::class . ' u WHERE a.user = u order by a.id asc',
|
||||
);
|
||||
$result = $query->toIterable();
|
||||
|
||||
$it = iterator_to_array($result);
|
||||
@@ -517,7 +519,9 @@ class QueryTest extends OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery('select a.topic, a.text from ' . CmsArticle::class . ' a ');
|
||||
$query = $this->_em->createQuery(
|
||||
'select a.topic, a.text from ' . CmsArticle::class . ' a order by a.id asc',
|
||||
);
|
||||
$result = $query->toIterable();
|
||||
|
||||
$it = iterator_to_array($result);
|
||||
@@ -545,7 +549,9 @@ class QueryTest extends OrmFunctionalTestCase
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
|
||||
$query = $this->_em->createQuery('select a from Doctrine\Tests\Models\CMS\CmsArticle a');
|
||||
$query = $this->_em->createQuery(
|
||||
'select a from Doctrine\Tests\Models\CMS\CmsArticle a order by a.id asc',
|
||||
);
|
||||
|
||||
$articles = $query->toIterable();
|
||||
$iteratedCount = 0;
|
||||
|
||||
@@ -142,6 +142,8 @@ class MySqlSchemaToolTest extends OrmFunctionalTestCase
|
||||
self::equalTo('CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'),
|
||||
// DBAL 4.3 (see https://github.com/doctrine/dbal/pull/6864)
|
||||
self::equalTo('CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY (id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'),
|
||||
// DBAL 4.4 (see https://github.com/doctrine/dbal/pull/7221)
|
||||
self::equalTo('CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT NOT NULL, PRIMARY KEY (id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'),
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
54
tests/Tests/ORM/Functional/Ticket/GH12254Test.php
Normal file
54
tests/Tests/ORM/Functional/Ticket/GH12254Test.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Tests\ORM\Functional\Ticket;
|
||||
|
||||
use Doctrine\ORM\Mapping\Column;
|
||||
use Doctrine\ORM\Mapping\Entity;
|
||||
use Doctrine\ORM\Mapping\GeneratedValue;
|
||||
use Doctrine\ORM\Mapping\Id;
|
||||
use Doctrine\Tests\OrmFunctionalTestCase;
|
||||
|
||||
class GH12254Test extends OrmFunctionalTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->setUpEntitySchema([
|
||||
GH12254EntityA::class,
|
||||
]);
|
||||
|
||||
$this->_em->persist(new GH12254EntityA());
|
||||
$this->_em->flush();
|
||||
$this->_em->clear();
|
||||
}
|
||||
|
||||
public function testFindByEmptyArrayShouldReturnEmptyArray(): void
|
||||
{
|
||||
// pretend we are starting afresh
|
||||
$this->_em = $this->getEntityManager();
|
||||
$result = $this->_em->getRepository(GH12254EntityA::class)->findBy(['id' => []]);
|
||||
$this->assertEmpty($result);
|
||||
}
|
||||
|
||||
public function testFindByInNullableField(): void
|
||||
{
|
||||
$this->_em = $this->getEntityManager();
|
||||
$result = $this->_em->getRepository(GH12254EntityA::class)->findBy(['name' => []]);
|
||||
$this->assertEmpty($result);
|
||||
}
|
||||
}
|
||||
|
||||
#[Entity]
|
||||
class GH12254EntityA
|
||||
{
|
||||
#[Column(type: 'integer')]
|
||||
#[Id]
|
||||
#[GeneratedValue(strategy: 'AUTO')]
|
||||
public int $id;
|
||||
|
||||
#[Column(type: 'string', nullable: true)]
|
||||
public string|null $name = null;
|
||||
}
|
||||
@@ -19,6 +19,7 @@ use ReflectionProperty;
|
||||
use Symfony\Component\Cache\Adapter\AbstractAdapter;
|
||||
use Symfony\Component\Cache\Adapter\ApcuAdapter;
|
||||
use Symfony\Component\Cache\Adapter\ArrayAdapter;
|
||||
use Symfony\Component\Cache\Adapter\NullAdapter;
|
||||
|
||||
use function sys_get_temp_dir;
|
||||
|
||||
@@ -68,7 +69,7 @@ class ORMSetupTest extends TestCase
|
||||
{
|
||||
$this->expectNotToPerformAssertions();
|
||||
|
||||
ORMSetup::createXMLMetadataConfig(paths: [], isXsdValidationEnabled: false);
|
||||
ORMSetup::createXMLMetadataConfig(paths: [], cache: new NullAdapter(), isXsdValidationEnabled: false);
|
||||
}
|
||||
|
||||
#[RequiresPhpExtension('apcu')]
|
||||
|
||||
@@ -147,6 +147,7 @@ class BasicEntityPersisterTypeValueSqlTest extends OrmTestCase
|
||||
}
|
||||
|
||||
#[Group('DDC-3056')]
|
||||
#[Group('GH12254')]
|
||||
public function testSelectConditionStatementWithMultipleValuesContainingNull(): void
|
||||
{
|
||||
self::assertEquals(
|
||||
@@ -168,6 +169,11 @@ class BasicEntityPersisterTypeValueSqlTest extends OrmTestCase
|
||||
'(t0.id IN (?, ?) OR t0.id IS NULL)',
|
||||
$this->persister->getSelectConditionStatementSQL('id', [123, null, 234]),
|
||||
);
|
||||
|
||||
self::assertEquals(
|
||||
'1=0',
|
||||
$this->persister->getSelectConditionStatementSQL('id', []),
|
||||
);
|
||||
}
|
||||
|
||||
public function testCountCondition(): void
|
||||
|
||||
@@ -16,6 +16,8 @@ use Doctrine\Tests\Models\BinaryPrimaryKey\BinaryIdType;
|
||||
use Doctrine\Tests\Models\BinaryPrimaryKey\Category;
|
||||
use Doctrine\Tests\OrmTestCase;
|
||||
|
||||
use const PHP_VERSION_ID;
|
||||
|
||||
final class BinaryIdPersisterTest extends OrmTestCase
|
||||
{
|
||||
private EntityManager|null $entityManager = null;
|
||||
@@ -64,6 +66,7 @@ final class BinaryIdPersisterTest extends OrmTestCase
|
||||
}
|
||||
|
||||
$config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/../../Models/BinaryPrimaryKey'], isDevMode: true);
|
||||
$config->enableNativeLazyObjects(PHP_VERSION_ID >= 80400);
|
||||
|
||||
if (! DbalType::hasType(BinaryIdType::NAME)) {
|
||||
DbalType::addType(BinaryIdType::NAME, BinaryIdType::class);
|
||||
|
||||
@@ -10,6 +10,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
|
||||
use Doctrine\ORM\EntityNotFoundException;
|
||||
use Doctrine\ORM\Mapping\ClassMetadata;
|
||||
use Doctrine\ORM\ORMInvalidArgumentException;
|
||||
use Doctrine\ORM\Persisters\Entity\BasicEntityPersister;
|
||||
use Doctrine\ORM\Proxy\ProxyFactory;
|
||||
use Doctrine\Persistence\Mapping\RuntimeReflectionService;
|
||||
@@ -22,10 +23,12 @@ use Doctrine\Tests\Models\ECommerce\ECommerceFeature;
|
||||
use Doctrine\Tests\OrmTestCase;
|
||||
use PHPUnit\Framework\Attributes\Group;
|
||||
use PHPUnit\Framework\Attributes\IgnoreDeprecations;
|
||||
use PHPUnit\Framework\Attributes\RequiresMethod;
|
||||
use PHPUnit\Framework\Attributes\RequiresPhp;
|
||||
use ReflectionClass;
|
||||
use ReflectionProperty;
|
||||
use stdClass;
|
||||
use Symfony\Component\VarExporter\ProxyHelper;
|
||||
|
||||
use function assert;
|
||||
use function method_exists;
|
||||
@@ -247,6 +250,7 @@ class ProxyFactoryTest extends OrmTestCase
|
||||
}
|
||||
|
||||
#[RequiresPhp('8.4')]
|
||||
#[RequiresMethod(ProxyHelper::class, 'generateLazyGhost')]
|
||||
#[IgnoreDeprecations]
|
||||
public function testProxyFactoryTriggersDeprecationWhenNativeLazyObjectsAreDisabled(): void
|
||||
{
|
||||
@@ -276,6 +280,25 @@ class ProxyFactoryTest extends OrmTestCase
|
||||
ProxyFactory::AUTOGENERATE_ALWAYS,
|
||||
);
|
||||
}
|
||||
|
||||
public function testProxyFactoryThrowsIfLazyGhostsAreUnavailable(): void
|
||||
{
|
||||
if (method_exists(ProxyHelper::class, 'generateLazyGhost')) {
|
||||
self::markTestSkipped('This test is not relevant when lazy ghosts are available');
|
||||
}
|
||||
|
||||
$this->emMock->getConfiguration()->enableNativeLazyObjects(false);
|
||||
|
||||
$this->expectException(ORMInvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Symfony LazyGhost is not available. Please install the "symfony/var-exporter" package version 6.4 or 7 to use this feature or enable PHP 8.4 native lazy objects.');
|
||||
|
||||
new ProxyFactory(
|
||||
$this->emMock,
|
||||
sys_get_temp_dir(),
|
||||
'Proxies',
|
||||
ProxyFactory::AUTOGENERATE_ALWAYS,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractClass
|
||||
|
||||
Reference in New Issue
Block a user