Skip to content

Commit 16f1be7

Browse files
authored
Merge pull request #12004 from doctrine/3.4.x
Merge 3.4.x up into 3.5.x
2 parents 1334162 + c74df3f commit 16f1be7

File tree

12 files changed

+89
-32
lines changed

12 files changed

+89
-32
lines changed

.doctrine-project.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,23 @@
1111
"slug": "latest",
1212
"upcoming": true
1313
},
14+
{
15+
"name": "3.5",
16+
"branchName": "3.5.x",
17+
"slug": "3.5",
18+
"upcoming": true
19+
},
1420
{
1521
"name": "3.4",
1622
"branchName": "3.4.x",
1723
"slug": "3.4",
18-
"upcoming": true
24+
"current": true
1925
},
2026
{
2127
"name": "3.3",
2228
"branchName": "3.3.x",
2329
"slug": "3.3",
24-
"current": true
30+
"maintained": false
2531
},
2632
{
2733
"name": "3.2",

.github/workflows/continuous-integration.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,27 @@ jobs:
4343
- "pdo_sqlite"
4444
deps:
4545
- "highest"
46-
lazy_proxy:
46+
native_lazy:
4747
- "0"
4848
include:
4949
- php-version: "8.2"
5050
dbal-version: "4@dev"
5151
extension: "pdo_sqlite"
52-
lazy_proxy: "0"
52+
native_lazy: "0"
5353
- php-version: "8.2"
5454
dbal-version: "4@dev"
5555
extension: "sqlite3"
56-
lazy_proxy: "0"
56+
native_lazy: "0"
5757
- php-version: "8.1"
5858
dbal-version: "default"
5959
deps: "lowest"
6060
extension: "pdo_sqlite"
61-
lazy_proxy: "0"
61+
native_lazy: "0"
6262
- php-version: "8.4"
6363
dbal-version: "default"
6464
deps: "highest"
6565
extension: "pdo_sqlite"
66-
lazy_proxy: "1"
66+
native_lazy: "1"
6767

6868
steps:
6969
- name: "Checkout"
@@ -93,18 +93,18 @@ jobs:
9393
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --coverage-clover=coverage-no-cache.xml"
9494
env:
9595
ENABLE_SECOND_LEVEL_CACHE: 0
96-
ENABLE_LAZY_PROXY: ${{ matrix.lazy_proxy }}
96+
ENABLE_NATIVE_LAZY_OBJECTS: ${{ matrix.native_lazy }}
9797

9898
- name: "Run PHPUnit with Second Level Cache"
9999
run: "vendor/bin/phpunit -c ci/github/phpunit/${{ matrix.extension }}.xml --exclude-group performance,non-cacheable,locking_functional --coverage-clover=coverage-cache.xml"
100100
env:
101101
ENABLE_SECOND_LEVEL_CACHE: 1
102-
ENABLE_LAZY_PROXY: ${{ matrix.lazy_proxy }}
102+
ENABLE_NATIVE_LAZY_OBJECTS: ${{ matrix.native_lazy }}
103103

104104
- name: "Upload coverage file"
105105
uses: "actions/upload-artifact@v4"
106106
with:
107-
name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.deps }}-${{ matrix.lazy_proxy }}-coverage"
107+
name: "phpunit-${{ matrix.extension }}-${{ matrix.php-version }}-${{ matrix.dbal-version }}-${{ matrix.deps }}-${{ matrix.native_lazy }}-coverage"
108108
path: "coverage*.xml"
109109

110110

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
| [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] |
1+
| [4.0.x][4.0] | [3.5.x][3.5] | [3.4.x][3.4] | [2.21.x][2.21] | [2.20.x][2.20] |
22
|:------------------------------------------------------:|:------------------------------------------------------:|:------------------------------------------------------:|:--------------------------------------------------------:|:--------------------------------------------------------:|
3-
| [![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] |
4-
| [![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] |
3+
| [![Build status][4.0 image]][4.0] | [![Build status][3.5 image]][3.5] | [![Build status][3.4 image]][3.4] | [![Build status][2.21 image]][2.21] | [![Build status][2.20 image]][2.20] |
4+
| [![Coverage Status][4.0 coverage image]][4.0 coverage] | [![Coverage Status][3.5 coverage image]][3.5 coverage] | [![Coverage Status][3.4 coverage image]][3.4 coverage] | [![Coverage Status][2.21 coverage image]][2.21 coverage] | [![Coverage Status][2.20 coverage image]][2.20 coverage] |
55

66
Doctrine ORM is an object-relational mapper for PHP 8.1+ that provides transparent persistence
77
for PHP objects. It sits on top of a powerful database abstraction layer (DBAL). One of its key features
@@ -20,14 +20,14 @@ without requiring unnecessary code duplication.
2020
[4.0]: https://github.com/doctrine/orm/tree/4.0.x
2121
[4.0 coverage image]: https://codecov.io/gh/doctrine/orm/branch/4.0.x/graph/badge.svg
2222
[4.0 coverage]: https://codecov.io/gh/doctrine/orm/branch/4.0.x
23+
[3.5 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.5.x
24+
[3.5]: https://github.com/doctrine/orm/tree/3.5.x
25+
[3.5 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.5.x/graph/badge.svg
26+
[3.5 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.5.x
2327
[3.4 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.4.x
2428
[3.4]: https://github.com/doctrine/orm/tree/3.4.x
2529
[3.4 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.4.x/graph/badge.svg
2630
[3.4 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.4.x
27-
[3.3 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=3.3.x
28-
[3.3]: https://github.com/doctrine/orm/tree/3.3.x
29-
[3.3 coverage image]: https://codecov.io/gh/doctrine/orm/branch/3.3.x/graph/badge.svg
30-
[3.3 coverage]: https://codecov.io/gh/doctrine/orm/branch/3.3.x
3131
[2.21 image]: https://github.com/doctrine/orm/actions/workflows/continuous-integration.yml/badge.svg?branch=2.21.x
3232
[2.21]: https://github.com/doctrine/orm/tree/2.21.x
3333
[2.21 coverage image]: https://codecov.io/gh/doctrine/orm/branch/2.21.x/graph/badge.svg

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ You can hydrate an entity nested in a DTO :
685685
// CustomerDTO => {name : 'DOE', email: null, address : {city: 'New York', zip: '10011', address: 'Abbey Road'}
686686
687687
In a Dto, if you want add all fields of an entity, you can use ``.*`` :
688+
688689
.. code-block:: php
689690
690691
<?php

src/UnitOfWork.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3057,7 +3057,7 @@ public function initializeObject(object $obj): void
30573057
*/
30583058
public function isUninitializedObject(mixed $obj): bool
30593059
{
3060-
if ($this->em->getConfiguration()->isNativeLazyObjectsEnabled() && ! ($obj instanceof Collection)) {
3060+
if ($this->em->getConfiguration()->isNativeLazyObjectsEnabled() && ! ($obj instanceof Collection) && is_object($obj)) {
30613061
return $this->em->getClassMetadata($obj::class)->reflClass->isUninitializedLazyObject($obj);
30623062
}
30633063

tests/Tests/ORM/EntityManagerTest.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@
2525
use PHPUnit\Framework\Assert;
2626
use PHPUnit\Framework\Attributes\DataProvider;
2727
use PHPUnit\Framework\Attributes\Group;
28+
use PHPUnit\Framework\Attributes\RequiresPhp;
29+
use ReflectionClass;
2830
use ReflectionProperty;
2931
use stdClass;
30-
use Symfony\Component\VarExporter\LazyGhostTrait;
3132
use TypeError;
3233

3334
class EntityManagerTest extends OrmTestCase
@@ -180,17 +181,12 @@ public function testWrapInTransactionReThrowsThrowables(): void
180181
}
181182

182183
/** Resetting the EntityManager relies on lazy objects until https://github.com/doctrine/orm/issues/5933 is resolved */
184+
#[RequiresPhp('8.4')]
183185
public function testLazyGhostEntityManager(): void
184186
{
185-
$em = new class () extends EntityManager {
186-
use LazyGhostTrait;
187+
$reflector = new ReflectionClass(EntityManager::class);
187188

188-
public function __construct()
189-
{
190-
}
191-
};
192-
193-
$em = $em::createLazyGhost(static function ($em): void {
189+
$em = $reflector->newLazyGhost($initializer = static function (EntityManager $em): void {
194190
$r = new ReflectionProperty(EntityManager::class, 'unitOfWork');
195191
$r->setValue($em, new class () extends UnitOfWork {
196192
public function __construct()
@@ -207,7 +203,7 @@ public function clear(): void
207203
$em->close();
208204
$this->assertFalse($em->isOpen());
209205

210-
$em->resetLazyObject();
206+
$reflector->resetAsLazyGhost($em, $initializer);
211207
$this->assertTrue($em->isOpen());
212208
}
213209

tests/Tests/ORM/Functional/PropertyHooksTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Doctrine\Tests\ORM\Functional;
66

7+
use Doctrine\DBAL\Platforms\AbstractMySQLPlatform;
78
use Doctrine\ORM\Mapping\MappingException;
89
use Doctrine\Tests\Models\PropertyHooks\MappingVirtualProperty;
910
use Doctrine\Tests\Models\PropertyHooks\User;
@@ -17,6 +18,10 @@ protected function setUp(): void
1718
{
1819
parent::setUp();
1920

21+
if ($this->_em->getConnection()->getDatabasePlatform() instanceof AbstractMySQLPlatform) {
22+
self::markTestSkipped('MySQL/MariaDB is case-insensitive by default, and the logic of this test relies on case sensitivity.');
23+
}
24+
2025
if (! $this->_em->getConfiguration()->isNativeLazyObjectsEnabled()) {
2126
$this->markTestSkipped('Property hooks require native lazy objects to be enabled.');
2227
}

tests/Tests/ORM/Hydration/ObjectHydratorTest.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use Doctrine\ORM\Internal\Hydration\ObjectHydrator;
1010
use Doctrine\ORM\Mapping\ClassMetadata;
1111
use Doctrine\ORM\PersistentCollection;
12-
use Doctrine\ORM\Proxy\InternalProxy;
1312
use Doctrine\ORM\Proxy\ProxyFactory;
1413
use Doctrine\ORM\Query\ResultSetMapping;
1514
use Doctrine\Tests\Mocks\ArrayResultFactory;
@@ -1030,7 +1029,7 @@ public function testCreatesProxyForLazyLoadingWithForeignKeys(): void
10301029
'Proxies',
10311030
ProxyFactory::AUTOGENERATE_ALWAYS,
10321031
) extends ProxyFactory {
1033-
public function getProxy(string $className, array $identifier): InternalProxy
1032+
public function getProxy(string $className, array $identifier): object
10341033
{
10351034
TestCase::assertSame(ECommerceShipping::class, $className);
10361035
TestCase::assertSame(['id' => 42], $identifier);
@@ -1084,7 +1083,7 @@ public function testCreatesProxyForLazyLoadingWithForeignKeysWithAliasedProductE
10841083
'Proxies',
10851084
ProxyFactory::AUTOGENERATE_ALWAYS,
10861085
) extends ProxyFactory {
1087-
public function getProxy(string $className, array $identifier): InternalProxy
1086+
public function getProxy(string $className, array $identifier): object
10881087
{
10891088
TestCase::assertSame(ECommerceShipping::class, $className);
10901089
TestCase::assertSame(['id' => 42], $identifier);

tests/Tests/ORM/Proxy/ProxyFactoryTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ public function testSkipAbstractClassesOnGeneration(): void
120120
#[Group('DDC-2432')]
121121
public function testFailedProxyLoadingDoesNotMarkTheProxyAsInitialized(): void
122122
{
123+
if ($this->emMock->getConfiguration()->isNativeLazyObjectsEnabled()) {
124+
self::markTestSkipped('This test is not relevant when native lazy objects are enabled');
125+
}
126+
123127
$persister = $this->getMockBuilder(BasicEntityPersister::class)
124128
->onlyMethods(['load'])
125129
->disableOriginalConstructor()
@@ -146,6 +150,10 @@ public function testFailedProxyLoadingDoesNotMarkTheProxyAsInitialized(): void
146150
#[Group('DDC-2432')]
147151
public function testFailedProxyCloningDoesNotMarkTheProxyAsInitialized(): void
148152
{
153+
if ($this->emMock->getConfiguration()->isNativeLazyObjectsEnabled()) {
154+
self::markTestSkipped('This test is not relevant when native lazy objects are enabled');
155+
}
156+
149157
$persister = $this->getMockBuilder(BasicEntityPersister::class)
150158
->onlyMethods(['load', 'getClassMetadata'])
151159
->disableOriginalConstructor()
@@ -172,6 +180,10 @@ public function testFailedProxyCloningDoesNotMarkTheProxyAsInitialized(): void
172180

173181
public function testProxyClonesParentFields(): void
174182
{
183+
if ($this->emMock->getConfiguration()->isNativeLazyObjectsEnabled()) {
184+
self::markTestSkipped('This test is not relevant when native lazy objects are enabled');
185+
}
186+
175187
$companyEmployee = new CompanyEmployee();
176188
$companyEmployee->setSalary(1000); // A property on the CompanyEmployee
177189
$companyEmployee->setName('Bob'); // A property on the parent class, CompanyPerson

tests/Tests/ORM/UnitOfWorkTest.php

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Doctrine\ORM\Mapping\GeneratedValue;
2121
use Doctrine\ORM\Mapping\Id;
2222
use Doctrine\ORM\Mapping\ManyToOne;
23+
use Doctrine\ORM\Mapping\MappingException;
2324
use Doctrine\ORM\Mapping\Version;
2425
use Doctrine\ORM\OptimisticLockException;
2526
use Doctrine\ORM\ORMInvalidArgumentException;
@@ -40,6 +41,7 @@
4041
use stdClass;
4142

4243
use function enum_exists;
44+
use function is_object;
4345
use function random_int;
4446
use function uniqid;
4547

@@ -278,7 +280,19 @@ public function testRejectsChangeSetComputationForObjectsWithInvalidAssociationV
278280
$user->username = 'John';
279281
$user->avatar = $invalidValue;
280282

281-
$this->expectException(ORMInvalidArgumentException::class);
283+
if (
284+
is_object($invalidValue) &&
285+
! $invalidValue instanceof ArrayCollection &&
286+
$this->_emMock->getConfiguration()->isNativeLazyObjectsEnabled()
287+
) {
288+
// in the case of stdClass, the changeset is rejected because
289+
// stdClass is not a valid entity
290+
// when using native lazy objects, this happens because UnitOfWork::isUninitializedObject()
291+
// needs to load the class metadata to do its job
292+
$this->expectException(MappingException::class);
293+
} else {
294+
$this->expectException(ORMInvalidArgumentException::class);
295+
}
282296

283297
$this->_unitOfWork->computeChangeSet($metadata, $user);
284298
}

0 commit comments

Comments
 (0)