Skip to content

Commit 8794b18

Browse files
committed
Feature: add support for $sourceFilePathNames
In the scope of doctrine/persistence#429 (available from `doctrine/persistence` >= 4.1) there was added `ColocatedMappingDriver::$sourceFilePathNames`, which allows passing the iterable of file paths for the mapping driver to use. This commit integrates those changes into `AttributeDriver`. Since `doctrine/orm` maintains the support for `doctrine/persistence` of older versions, `AttributeDriver` ensures that `$sourceFilePathNames` is actually defined. Tests use `InstalledVersions` to opt into new behaviour if `doctrine/persistence` is at least version 4.1. The new behaviour is adapted by using `glob()` on paths.
1 parent 7606162 commit 8794b18

File tree

15 files changed

+124
-55
lines changed

15 files changed

+124
-55
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"symfony/var-exporter": "^6.3.9 || ^7.0"
3838
},
3939
"require-dev": {
40+
"doctrine/persistence": "^3.3.1 || ^4.0 || 4.1.x-dev",
4041
"doctrine/coding-standard": "^13.0",
4142
"phpbench/phpbench": "^1.0",
4243
"phpdocumentor/guides-cli": "^1.4",

docs/en/reference/advanced-configuration.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ steps of configuration.
2929
3030
$config = new Configuration;
3131
$config->setMetadataCache($metadataCache);
32-
$driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities'], true);
32+
$driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities']);
3333
$config->setMetadataDriverImpl($driverImpl);
3434
$config->setQueryCache($queryCache);
3535
@@ -154,7 +154,7 @@ The attribute driver can be injected in the ``Doctrine\ORM\Configuration``:
154154
<?php
155155
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
156156
157-
$driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities'], true);
157+
$driverImpl = new AttributeDriver(['/path/to/lib/MyProject/Entities']);
158158
$config->setMetadataDriverImpl($driverImpl);
159159
160160
The path information to the entities is required for the attribute

src/Mapping/Driver/AttributeDriver.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@
1313
use Doctrine\Persistence\Mapping\Driver\ColocatedMappingDriver;
1414
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
1515
use InvalidArgumentException;
16+
use LogicException;
1617
use ReflectionClass;
1718
use ReflectionMethod;
1819

1920
use function assert;
2021
use function class_exists;
2122
use function constant;
2223
use function defined;
24+
use function is_array;
25+
use function property_exists;
2326
use function sprintf;
2427

2528
class AttributeDriver implements MappingDriver
@@ -35,10 +38,11 @@ class AttributeDriver implements MappingDriver
3538
private readonly AttributeReader $reader;
3639

3740
/**
38-
* @param array<string> $paths
39-
* @param true $reportFieldsWhereDeclared no-op, to be removed in 4.0
41+
* @param iterable<string> $paths iterable of source file path names {@see $pathsAsFilePaths}, or an array of directories.
42+
* @param true $reportFieldsWhereDeclared no-op, to be removed in 4.0
43+
* @param bool $pathsAsFilePaths whether {@see $paths} are paths to files or directories
4044
*/
41-
public function __construct(array $paths, bool $reportFieldsWhereDeclared = true)
45+
public function __construct(iterable $paths, bool $reportFieldsWhereDeclared = true, bool $pathsAsFilePaths = false)
4246
{
4347
if (! $reportFieldsWhereDeclared) {
4448
throw new InvalidArgumentException(sprintf(
@@ -47,8 +51,19 @@ public function __construct(array $paths, bool $reportFieldsWhereDeclared = true
4751
));
4852
}
4953

54+
if ($pathsAsFilePaths) {
55+
if (! property_exists(self::class, 'sourceFilePathNames')) {
56+
throw new LogicException('Source file path names support for AttributeDriver is available since doctrine/persistence 4.1.');
57+
}
58+
59+
$this->sourceFilePathNames = $paths;
60+
} elseif (is_array($paths)) {
61+
$this->addPaths($paths);
62+
} else {
63+
throw new LogicException('The $paths argument must be an array of directories.');
64+
}
65+
5066
$this->reader = new AttributeReader();
51-
$this->addPaths($paths);
5267
}
5368

5469
public function isTransient(string $className): bool

src/ORMSetup.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ public static function createAttributeMetadataConfiguration(
3535
bool $isDevMode = false,
3636
string|null $proxyDir = null,
3737
CacheItemPoolInterface|null $cache = null,
38+
bool $pathsAsFilePaths = false,
3839
): Configuration {
3940
if (PHP_VERSION_ID >= 80400) {
4041
Deprecation::trigger(
@@ -47,7 +48,7 @@ public static function createAttributeMetadataConfiguration(
4748
}
4849

4950
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
50-
$config->setMetadataDriverImpl(new AttributeDriver($paths));
51+
$config->setMetadataDriverImpl(new AttributeDriver($paths, true, $pathsAsFilePaths));
5152

5253
return $config;
5354
}
@@ -62,9 +63,10 @@ public static function createAttributeMetadataConfig(
6263
bool $isDevMode = false,
6364
string|null $cacheNamespaceSeed = null,
6465
CacheItemPoolInterface|null $cache = null,
66+
bool $pathsAsFilePaths = false,
6567
): Configuration {
6668
$config = self::createConfig($isDevMode, $cacheNamespaceSeed, $cache);
67-
$config->setMetadataDriverImpl(new AttributeDriver($paths));
69+
$config->setMetadataDriverImpl(new AttributeDriver($paths, true, $pathsAsFilePaths));
6870

6971
return $config;
7072
}

tests/Performance/EntityManagerFactory.php

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,13 @@
1313
use Doctrine\ORM\Configuration;
1414
use Doctrine\ORM\EntityManager;
1515
use Doctrine\ORM\EntityManagerInterface;
16-
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
1716
use Doctrine\ORM\Proxy\ProxyFactory;
1817
use Doctrine\ORM\Tools\SchemaTool;
1918
use Doctrine\Tests\Mocks\ArrayResultFactory;
19+
use Doctrine\Tests\Mocks\AttributeDriverFactory;
2020
use Doctrine\Tests\TestUtil;
2121

2222
use function array_map;
23-
use function realpath;
2423

2524
final class EntityManagerFactory
2625
{
@@ -30,10 +29,7 @@ public static function getEntityManager(array $schemaClassNames): EntityManagerI
3029

3130
TestUtil::configureProxies($config);
3231
$config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_EVAL);
33-
$config->setMetadataDriverImpl(new AttributeDriver([
34-
realpath(__DIR__ . '/Models/Cache'),
35-
realpath(__DIR__ . '/Models/GeoNames'),
36-
]));
32+
$config->setMetadataDriverImpl(AttributeDriverFactory::createAttributeDriver([__DIR__ . '/../Tests/Models/Cache', __DIR__ . '/../Tests/Models/GeoNames']));
3733

3834
$entityManager = new EntityManager(
3935
DriverManager::getConnection([
@@ -55,11 +51,7 @@ public static function makeEntityManagerWithNoResultsConnection(): EntityManager
5551

5652
TestUtil::configureProxies($config);
5753
$config->setAutoGenerateProxyClasses(ProxyFactory::AUTOGENERATE_EVAL);
58-
$config->setMetadataDriverImpl(new AttributeDriver([
59-
realpath(__DIR__ . '/Models/Cache'),
60-
realpath(__DIR__ . '/Models/Generic'),
61-
realpath(__DIR__ . '/Models/GeoNames'),
62-
]));
54+
$config->setMetadataDriverImpl(AttributeDriverFactory::createAttributeDriver([__DIR__ . '/../Tests/Models/Cache', __DIR__ . '/../Tests/Models/Generic', __DIR__ . '/../Tests/Models/GeoNames']));
6355

6456
// A connection that doesn't really do anything
6557
$connection = new class ([], new Driver(), null, new EventManager()) extends Connection
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Tests\Mocks;
6+
7+
use Composer\InstalledVersions;
8+
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
9+
use LogicException;
10+
11+
use function array_map;
12+
use function array_merge;
13+
use function assert;
14+
use function glob;
15+
use function realpath;
16+
use function version_compare;
17+
18+
use const GLOB_BRACE;
19+
20+
final class AttributeDriverFactory
21+
{
22+
/** @param list<string> $paths */
23+
public static function createAttributeDriver(array $paths = []): AttributeDriver
24+
{
25+
if (! self::isPathsFilePathsSupported()) {
26+
return new AttributeDriver($paths, true, false);
27+
}
28+
29+
$filePaths = array_merge(...array_map(self::pathFiles(...), $paths));
30+
31+
return new AttributeDriver($filePaths, true, true);
32+
}
33+
34+
public static function isPathsFilePathsSupported(): bool
35+
{
36+
return version_compare(InstalledVersions::getVersion('doctrine/persistence'), '4.1', '>=');
37+
}
38+
39+
/** @return list<string> */
40+
public static function pathFiles(string $path): array
41+
{
42+
$realpath = realpath($path);
43+
44+
assert($realpath !== false);
45+
46+
return glob($realpath . '/{,*/}*.php', GLOB_BRACE)
47+
?: throw new LogicException('Could not load driver files');
48+
}
49+
}

tests/Tests/Mocks/EntityManagerMock.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use Doctrine\DBAL\Connection;
99
use Doctrine\ORM\Configuration;
1010
use Doctrine\ORM\EntityManager;
11-
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
1211
use Doctrine\ORM\Proxy\ProxyFactory;
1312
use Doctrine\ORM\UnitOfWork;
1413
use Doctrine\Tests\TestUtil;
@@ -26,7 +25,8 @@ public function __construct(Connection $conn, Configuration|null $config = null,
2625
if ($config === null) {
2726
$config = new Configuration();
2827
TestUtil::configureProxies($config);
29-
$config->setMetadataDriverImpl(new AttributeDriver([]));
28+
$attributeDriver = AttributeDriverFactory::createAttributeDriver();
29+
$config->setMetadataDriverImpl($attributeDriver);
3030
}
3131

3232
parent::__construct($conn, $config, $eventManager);

tests/Tests/ORM/Functional/EnumTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
use Doctrine\DBAL\Types\EnumType;
88
use Doctrine\ORM\AbstractQuery;
99
use Doctrine\ORM\Mapping\Column;
10-
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
1110
use Doctrine\ORM\Mapping\MappingException;
1211
use Doctrine\ORM\Query\Expr\Func;
1312
use Doctrine\ORM\Tools\SchemaTool;
13+
use Doctrine\Tests\Mocks\AttributeDriverFactory;
1414
use Doctrine\Tests\Models\DataTransferObjects\DtoWithArrayOfEnums;
1515
use Doctrine\Tests\Models\DataTransferObjects\DtoWithEnum;
1616
use Doctrine\Tests\Models\Enums\Card;
@@ -28,7 +28,6 @@
2828
use PHPUnit\Framework\Attributes\DataProvider;
2929

3030
use function class_exists;
31-
use function dirname;
3231
use function sprintf;
3332
use function uniqid;
3433

@@ -38,7 +37,9 @@ public function setUp(): void
3837
{
3938
parent::setUp();
4039

41-
$this->_em = $this->getEntityManager(null, new AttributeDriver([dirname(__DIR__, 2) . '/Models/Enums'], true));
40+
$mappingDriver = AttributeDriverFactory::createAttributeDriver([__DIR__ . '/../../Models/Enums']);
41+
42+
$this->_em = $this->getEntityManager(null, $mappingDriver);
4243
$this->_schemaTool = new SchemaTool($this->_em);
4344

4445
if ($this->isSecondLevelCacheEnabled) {

tests/Tests/ORM/Functional/Locking/LockAgentWorker.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Doctrine\ORM\Configuration;
1010
use Doctrine\ORM\EntityManager;
1111
use Doctrine\ORM\EntityManagerInterface;
12+
use Doctrine\Tests\Mocks\AttributeDriverFactory;
1213
use Doctrine\Tests\ORM\Functional\Locking\Doctrine\ORM\Query;
1314
use Doctrine\Tests\TestUtil;
1415
use GearmanWorker;
@@ -116,8 +117,8 @@ protected function createEntityManager(Connection $conn): EntityManagerInterface
116117
TestUtil::configureProxies($config);
117118
$config->setAutoGenerateProxyClasses(true);
118119

119-
$annotDriver = new AttributeDriver([__DIR__ . '/../../../Models/']);
120-
$config->setMetadataDriverImpl($annotDriver);
120+
$attributeDriver = AttributeDriverFactory::createAttributeDriver([__DIR__ . '/../../../Models']);
121+
$config->setMetadataDriverImpl($attributeDriver);
121122
$config->setMetadataCache(new ArrayAdapter());
122123

123124
$config->setQueryCache(new ArrayAdapter());

tests/Tests/ORM/Functional/ReadonlyPropertiesTest.php

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44

55
namespace Doctrine\Tests\ORM\Functional;
66

7-
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
87
use Doctrine\ORM\Tools\SchemaTool;
8+
use Doctrine\Tests\Mocks\AttributeDriverFactory;
99
use Doctrine\Tests\Models\ReadonlyProperties\Author;
1010
use Doctrine\Tests\Models\ReadonlyProperties\Book;
1111
use Doctrine\Tests\Models\ReadonlyProperties\SimpleBook;
1212
use Doctrine\Tests\OrmFunctionalTestCase;
1313
use Doctrine\Tests\TestUtil;
1414

15-
use function dirname;
16-
1715
class ReadonlyPropertiesTest extends OrmFunctionalTestCase
1816
{
1917
protected function setUp(): void
@@ -22,10 +20,8 @@ protected function setUp(): void
2220
static::$sharedConn = TestUtil::getConnection();
2321
}
2422

25-
$this->_em = $this->getEntityManager(null, new AttributeDriver(
26-
[dirname(__DIR__, 2) . '/Models/ReadonlyProperties'],
27-
true,
28-
));
23+
$attributeDriver = AttributeDriverFactory::createAttributeDriver([__DIR__ . '/../../Models/ReadonlyProperties']);
24+
$this->_em = $this->getEntityManager(null, $attributeDriver);
2925
$this->_schemaTool = new SchemaTool($this->_em);
3026

3127
parent::setUp();

0 commit comments

Comments
 (0)