Merge remote-tracking branch 'origin/1.8.x' into 2.1.x

This commit is contained in:
Grégoire Paris
2025-10-17 22:01:23 +02:00
11 changed files with 105 additions and 20 deletions

View File

@@ -11,4 +11,4 @@ on:
jobs: jobs:
coding-standards: coding-standards:
name: "Coding Standards" name: "Coding Standards"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@8.0.0" uses: "doctrine/.github/.github/workflows/coding-standards.yml@10.1.0"

View File

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

View File

@@ -8,7 +8,7 @@ on:
jobs: jobs:
release: release:
name: "Git tag, release & create merge-up PR" name: "Git tag, release & create merge-up PR"
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@8.0.0" uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@10.1.0"
secrets: secrets:
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }} GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }} GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}

View File

@@ -11,4 +11,4 @@ on:
jobs: jobs:
static-analysis: static-analysis:
name: "Static Analysis" name: "Static Analysis"
uses: "doctrine/.github/.github/workflows/phpstan.yml@8.0.0" uses: "doctrine/.github/.github/workflows/phpstan.yml@10.1.0"

View File

@@ -30,7 +30,7 @@
"doctrine/mongodb-odm": "^1.3.0 || ^2.0.0", "doctrine/mongodb-odm": "^1.3.0 || ^2.0.0",
"doctrine/orm": "^2.14 || ^3", "doctrine/orm": "^2.14 || ^3",
"fig/log-test": "^1", "fig/log-test": "^1",
"phpstan/phpstan": "2.1.30", "phpstan/phpstan": "2.1.31",
"phpunit/phpunit": "10.5.45 || 12.4.0", "phpunit/phpunit": "10.5.45 || 12.4.0",
"symfony/cache": "^6.4 || ^7", "symfony/cache": "^6.4 || ^7",
"symfony/var-exporter": "^6.4 || ^7" "symfony/var-exporter": "^6.4 || ^7"

View File

@@ -270,6 +270,12 @@ parameters:
count: 1 count: 1
path: src/Sorter/Vertex.php path: src/Sorter/Vertex.php
-
message: '#^Call to function method_exists\(\) with ''Doctrine\\\\ORM\\\\ORMSetup'' and ''createAttributeMeta…'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 1
path: tests/Common/DataFixtures/BaseTestCase.php
- -
message: '#^Method Doctrine\\Tests\\Common\\DataFixtures\\FixtureWithUnexistentDependency\:\:getDependencies\(\) should return array\<class\-string\<Doctrine\\Common\\DataFixtures\\FixtureInterface\>\> but returns array\<int, string\>\.$#' message: '#^Method Doctrine\\Tests\\Common\\DataFixtures\\FixtureWithUnexistentDependency\:\:getDependencies\(\) should return array\<class\-string\<Doctrine\\Common\\DataFixtures\\FixtureInterface\>\> but returns array\<int, string\>\.$#'
identifier: return.type identifier: return.type
@@ -288,6 +294,12 @@ parameters:
count: 3 count: 3
path: tests/Common/DataFixtures/Executor/PHPCRExecutorTest.php path: tests/Common/DataFixtures/Executor/PHPCRExecutorTest.php
-
message: '#^Call to function method_exists\(\) with ''Doctrine\\\\ORM\\\\ORMSetup'' and ''createAttributeMeta…'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 2
path: tests/Common/DataFixtures/ProxyReferenceRepositoryTest.php
- -
message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getConnection\(\)\.$#' message: '#^Call to an undefined method Doctrine\\ODM\\MongoDB\\DocumentManager\:\:getConnection\(\)\.$#'
identifier: method.notFound identifier: method.notFound
@@ -300,6 +312,12 @@ parameters:
count: 1 count: 1
path: tests/Common/DataFixtures/Purger/MongoDBPurgerTest.php path: tests/Common/DataFixtures/Purger/MongoDBPurgerTest.php
-
message: '#^Call to function method_exists\(\) with ''Doctrine\\\\ORM\\\\ORMSetup'' and ''createAttributeMeta…'' will always evaluate to true\.$#'
identifier: function.alreadyNarrowedType
count: 2
path: tests/Common/DataFixtures/ReferenceRepositoryTest.php
- -
message: '#^Parameter \#1 \$name of class Doctrine\\ORM\\Mapping\\ClassMetadata constructor expects class\-string\<1\>, string given\.$#' message: '#^Parameter \#1 \$name of class Doctrine\\ORM\\Mapping\\ClassMetadata constructor expects class\-string\<1\>, string given\.$#'
identifier: argument.type identifier: argument.type

View File

@@ -1,5 +1,5 @@
parameters: parameters:
phpVersion: 80200 phpVersion: 80400
level: 7 level: 7
paths: paths:
- src - src

View File

@@ -18,7 +18,7 @@
<source ignoreSuppressionOfDeprecations="true"> <source ignoreSuppressionOfDeprecations="true">
<include> <include>
<directory>./src</directory> <directory>./src/</directory>
</include> </include>
</source> </source>
</phpunit> </phpunit>

View File

@@ -11,6 +11,8 @@ use PHPUnit\Framework\TestCase;
use function method_exists; use function method_exists;
use const PHP_VERSION_ID;
abstract class BaseTestCase extends TestCase abstract class BaseTestCase extends TestCase
{ {
/** /**
@@ -21,8 +23,13 @@ abstract class BaseTestCase extends TestCase
protected function getMockSqliteEntityManager(string $fixtureSet = 'TestEntity'): EntityManager protected function getMockSqliteEntityManager(string $fixtureSet = 'TestEntity'): EntityManager
{ {
$dbParams = ['driver' => 'sqlite3', 'memory' => true]; $dbParams = ['driver' => 'sqlite3', 'memory' => true];
$config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/' . $fixtureSet], true); if (PHP_VERSION_ID >= 80400 && method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$config->setLazyGhostObjectEnabled(true); $config = ORMSetup::createAttributeMetadataConfig([__DIR__ . '/' . $fixtureSet], true);
$config->enableNativeLazyObjects(true);
} else {
$config = ORMSetup::createAttributeMetadataConfiguration([__DIR__ . '/' . $fixtureSet], true);
$config->setLazyGhostObjectEnabled(true);
}
$connection = DriverManager::getConnection($dbParams, $config); $connection = DriverManager::getConnection($dbParams, $config);
$platform = $connection->getDatabasePlatform(); $platform = $connection->getDatabasePlatform();

View File

@@ -7,6 +7,7 @@ namespace Doctrine\Tests\Common\DataFixtures;
use Doctrine\Common\DataFixtures\Event\Listener\ORMReferenceListener; use Doctrine\Common\DataFixtures\Event\Listener\ORMReferenceListener;
use Doctrine\Common\DataFixtures\ProxyReferenceRepository; use Doctrine\Common\DataFixtures\ProxyReferenceRepository;
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\ORMSetup;
use Doctrine\ORM\Tools\SchemaTool; use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\Persistence\Proxy; use Doctrine\Persistence\Proxy;
use Doctrine\Tests\Common\DataFixtures\TestEntity\Link; use Doctrine\Tests\Common\DataFixtures\TestEntity\Link;
@@ -14,6 +15,11 @@ use Doctrine\Tests\Common\DataFixtures\TestEntity\Role;
use Doctrine\Tests\Common\DataFixtures\TestTypes\UuidType; use Doctrine\Tests\Common\DataFixtures\TestTypes\UuidType;
use Doctrine\Tests\Common\DataFixtures\TestValueObjects\Uuid; use Doctrine\Tests\Common\DataFixtures\TestValueObjects\Uuid;
use PHPUnit\Framework\Attributes\IgnoreDeprecations; use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use ReflectionClass;
use function method_exists;
use const PHP_VERSION_ID;
class ProxyReferenceRepositoryTest extends BaseTestCase class ProxyReferenceRepositoryTest extends BaseTestCase
{ {
@@ -39,7 +45,7 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$role->setName('admin'); $role->setName('admin');
$meta = $em->getClassMetadata(self::TEST_ENTITY_ROLE); $meta = $em->getClassMetadata(self::TEST_ENTITY_ROLE);
// getPropertyAccessor() is not available with Doctrine < 3.4 // getPropertyAccessor() is not available with ORM < 3.4
$meta->getReflectionProperty('id')->setValue($role, 1); $meta->getReflectionProperty('id')->setValue($role, 1);
$referenceRepo = new ProxyReferenceRepository($em); $referenceRepo = new ProxyReferenceRepository($em);
@@ -101,7 +107,7 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
// first test against managed state // first test against managed state
$ref = $referenceRepository->getReference('admin-role', Role::class); $ref = $referenceRepository->getReference('admin-role', Role::class);
$this->assertNotInstanceOf(Proxy::class, $ref); $this->assertNotProxy($ref);
// test reference reconstruction from serialized data (was managed) // test reference reconstruction from serialized data (was managed)
$serializedData = $referenceRepository->serialize(); $serializedData = $referenceRepository->serialize();
@@ -112,14 +118,14 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$ref = $proxyReferenceRepository->getReference('admin-role', Role::class); $ref = $proxyReferenceRepository->getReference('admin-role', Role::class);
// before clearing, the reference is not yet a proxy // before clearing, the reference is not yet a proxy
$this->assertNotInstanceOf(Proxy::class, $ref); $this->assertNotProxy($ref);
$this->assertInstanceOf(self::TEST_ENTITY_ROLE, $ref); $this->assertInstanceOf(self::TEST_ENTITY_ROLE, $ref);
// now test reference reconstruction from identity // now test reference reconstruction from identity
$em->clear(); $em->clear();
$ref = $referenceRepository->getReference('admin-role', Role::class); $ref = $referenceRepository->getReference('admin-role', Role::class);
$this->assertInstanceOf(Proxy::class, $ref); $this->assertProxy($ref);
// test reference reconstruction from serialized data (was identity) // test reference reconstruction from serialized data (was identity)
$serializedData = $referenceRepository->serialize(); $serializedData = $referenceRepository->serialize();
@@ -129,7 +135,7 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$ref = $proxyReferenceRepository->getReference('admin-role', Role::class); $ref = $proxyReferenceRepository->getReference('admin-role', Role::class);
$this->assertInstanceOf(Proxy::class, $ref); $this->assertProxy($ref);
} }
#[IgnoreDeprecations] #[IgnoreDeprecations]
@@ -179,7 +185,31 @@ class ProxyReferenceRepositoryTest extends BaseTestCase
$em->flush(); $em->flush();
$em->clear(); $em->clear();
$this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('admin', Role::class)); $this->assertProxy($referenceRepository->getReference('admin', Role::class));
$this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('duplicate', Role::class)); $this->assertProxy($referenceRepository->getReference('duplicate', Role::class));
}
private function assertProxy(object $object): void
{
if (PHP_VERSION_ID < 80400 || ! method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$this->assertInstanceOf(Proxy::class, $object);
return;
}
$reflector = new ReflectionClass($object);
$this->assertTrue($reflector->isUninitializedLazyObject($object));
}
private function assertNotProxy(object $object): void
{
if (PHP_VERSION_ID < 80400 || ! method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$this->assertNotInstanceOf(Proxy::class, $object);
return;
}
$reflector = new ReflectionClass($object);
$this->assertFalse($reflector->isUninitializedLazyObject($object));
} }
} }

View File

@@ -8,6 +8,7 @@ use BadMethodCallException;
use Doctrine\Common\DataFixtures\Event\Listener\ORMReferenceListener; use Doctrine\Common\DataFixtures\Event\Listener\ORMReferenceListener;
use Doctrine\Common\DataFixtures\ReferenceRepository; use Doctrine\Common\DataFixtures\ReferenceRepository;
use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\ORMSetup;
use Doctrine\ORM\Tools\SchemaTool; use Doctrine\ORM\Tools\SchemaTool;
use Doctrine\ORM\UnitOfWork; use Doctrine\ORM\UnitOfWork;
use Doctrine\Persistence\Proxy; use Doctrine\Persistence\Proxy;
@@ -16,11 +17,16 @@ use Doctrine\Tests\Common\DataFixtures\TestEntity\User;
use Doctrine\Tests\Mock\ForwardCompatibleEntityManager; use Doctrine\Tests\Mock\ForwardCompatibleEntityManager;
use OutOfBoundsException; use OutOfBoundsException;
use PHPUnit\Framework\Attributes\IgnoreDeprecations; use PHPUnit\Framework\Attributes\IgnoreDeprecations;
use ReflectionClass;
use function method_exists;
use function sprintf; use function sprintf;
use const PHP_VERSION_ID;
class ReferenceRepositoryTest extends BaseTestCase class ReferenceRepositoryTest extends BaseTestCase
{ {
#[IgnoreDeprecations]
public function testReferenceEntry(): void public function testReferenceEntry(): void
{ {
$em = $this->getMockSqliteEntityManager(); $em = $this->getMockSqliteEntityManager();
@@ -92,13 +98,13 @@ class ReferenceRepositoryTest extends BaseTestCase
// first test against managed state // first test against managed state
$ref = $referenceRepository->getReference('admin-role', Role::class); $ref = $referenceRepository->getReference('admin-role', Role::class);
$this->assertNotInstanceOf(Proxy::class, $ref); $this->assertNotProxy($ref);
// now test reference reconstruction from identity // now test reference reconstruction from identity
$em->clear(); $em->clear();
$ref = $referenceRepository->getReference('admin-role', Role::class); $ref = $referenceRepository->getReference('admin-role', Role::class);
$this->assertInstanceOf(Proxy::class, $ref); $this->assertProxy($ref);
} }
public function testReferenceMultipleEntries(): void public function testReferenceMultipleEntries(): void
@@ -118,8 +124,8 @@ class ReferenceRepositoryTest extends BaseTestCase
$em->flush(); $em->flush();
$em->clear(); $em->clear();
$this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('admin', Role::class)); $this->assertProxy($referenceRepository->getReference('admin', Role::class));
$this->assertInstanceOf(Proxy::class, $referenceRepository->getReference('duplicate', Role::class)); $this->assertProxy($referenceRepository->getReference('duplicate', Role::class));
} }
public function testUndefinedReference(): void public function testUndefinedReference(): void
@@ -264,4 +270,28 @@ class ReferenceRepositoryTest extends BaseTestCase
$this->assertCount(1, $names); $this->assertCount(1, $names);
$this->assertSame('1', $names[0]); $this->assertSame('1', $names[0]);
} }
private function assertProxy(object $object): void
{
if (PHP_VERSION_ID < 80400 || ! method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$this->assertInstanceOf(Proxy::class, $object);
return;
}
$reflector = new ReflectionClass($object);
$this->assertTrue($reflector->isUninitializedLazyObject($object));
}
private function assertNotProxy(object $object): void
{
if (PHP_VERSION_ID < 80400 || ! method_exists(ORMSetup::class, 'createAttributeMetadataConfig')) {
$this->assertNotInstanceOf(Proxy::class, $object);
return;
}
$reflector = new ReflectionClass($object);
$this->assertFalse($reflector->isUninitializedLazyObject($object));
}
} }