diff --git a/UPGRADE.md b/UPGRADE.md index 5bf1ef0a..79288df4 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -6,6 +6,25 @@ awareness about deprecated code. - Use of our low-overhead runtime deprecation API, details: https://github.com/doctrine/deprecations/ +# Upgrade to 4.1 + +## Added `ColocatedMappingDriver::$fileRegex` + +You can search for mapping files with regex: + +```php +// Search for all files but ending with Test, Fixture, Service +$driver->setFileRegex('/(?excludePaths; } - /** Gets the file extension used to look for mapping files under. */ - public function getFileExtension(): string + /** Gets the file regex used to look for mapping files under. */ + public function getFileRegex(): string + { + return $this->fileRegex; + } + + /** Sets the file regex used to look for mapping files with. */ + public function setFileRegex(string $fileRegex): void + { + $this->fileRegex = $fileRegex; + $this->fileExtension = null; + } + + /** + * Gets the file extension used to look for mapping files under. + * + * @deprecated Use {@see getFileRegex()} instead. + */ + public function getFileExtension(): string|null { return $this->fileExtension; } - /** Sets the file extension used to look for mapping files under. */ + /** + * Sets the file extension used to look for mapping files under. + * + * @deprecated Use {@see setFileRegex()} instead. + */ public function setFileExtension(string $fileExtension): void { $this->fileExtension = $fileExtension; + $this->fileRegex = sprintf('/%s$/', preg_quote($fileExtension, '/')); } /** @@ -140,20 +170,22 @@ public function getAllClassNames(): array throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path); } + /** @var iterable $iterator */ $iterator = new RegexIterator( new RecursiveIteratorIterator( new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::LEAVES_ONLY, ), - '/^.+' . preg_quote($this->fileExtension) . '$/i', - RecursiveRegexIterator::GET_MATCH, + $this->fileRegex, + RegexIterator::MATCH, ); foreach ($iterator as $file) { - $sourceFile = $file[0]; + $sourceFile = $file->getPathname(); if (preg_match('(^phar:)i', $sourceFile) === 0) { $sourceFile = realpath($sourceFile); + assert($sourceFile !== false); } foreach ($this->excludePaths as $excludePath) { diff --git a/tests/Persistence/Mapping/ColocatedMappingDriverTest.php b/tests/Persistence/Mapping/ColocatedMappingDriverTest.php index cbb4fea6..ee4295d2 100644 --- a/tests/Persistence/Mapping/ColocatedMappingDriverTest.php +++ b/tests/Persistence/Mapping/ColocatedMappingDriverTest.php @@ -4,14 +4,16 @@ namespace Doctrine\Tests\Persistence\Mapping; +use Doctrine\EntityFixture; use Doctrine\Persistence\Mapping\ClassMetadata; use Doctrine\Persistence\Mapping\Driver\ColocatedMappingDriver; use Doctrine\Persistence\Mapping\Driver\MappingDriver; -use Doctrine\TestClass; +use Doctrine\Tests\Persistence\Mapping\_files\colocated\Entity; +use Doctrine\Tests\Persistence\Mapping\_files\colocated\TestClass; use Generator; use PHPUnit\Framework\TestCase; -use function array_values; +use function sort; class ColocatedMappingDriverTest extends TestCase { @@ -44,6 +46,18 @@ public function testAddGetExcludePaths(): void ], $driver->getExcludePaths()); } + public function testGetSetFileRegex(): void + { + $driver = $this->createDriver(__DIR__ . '/_files/colocated'); + self::assertSame('/\.php$/', $driver->getFileRegex()); + + $driver->setFileRegex('/\.php1$/'); + + self::assertSame('/\.php1$/', $driver->getFileRegex()); + self::assertNull($driver->getFileExtension()); + } + + /** @deprecated */ public function testGetSetFileExtension(): void { $driver = $this->createDriver(__DIR__ . '/_files/colocated'); @@ -52,6 +66,7 @@ public function testGetSetFileExtension(): void $driver->setFileExtension('.php1'); self::assertSame('.php1', $driver->getFileExtension()); + self::assertSame('/\.php1$/', $driver->getFileRegex()); } /** @dataProvider pathProvider */ @@ -61,7 +76,22 @@ public function testGetAllClassNames(string $path): void $classes = $driver->getAllClassNames(); - self::assertSame([TestClass::class], $classes); + sort($classes); + self::assertSame([EntityFixture::class, Entity::class], $classes); + } + + public function testGetAllClassNamesWithRegex(): void + { + $regex = '/(?createDriver(__DIR__ . '/_files/colocated', $regex); + + $classes = $driver->getAllClassNames(); + + self::assertSame( + [Entity::class], + $classes, + 'EntityFixture.php should be excluded by the regex, since it ends with Fixture suffix.', + ); } /** @return Generator */ @@ -71,9 +101,9 @@ public static function pathProvider(): Generator yield 'winding path' => [__DIR__ . '/../Mapping/_files/colocated']; } - private function createDriver(string $path): MyDriver + private function createDriver(string $path, string|null $fileRegex = null): MyDriver { - return new MyDriver($path); + return new MyDriver([$path], $fileRegex); } } @@ -81,10 +111,19 @@ final class MyDriver implements MappingDriver { use ColocatedMappingDriver; - /** @param string ...$paths One or multiple paths where mapping classes can be found. */ - public function __construct(string ...$paths) + /** + * @param non-empty-list $paths One or multiple paths where mapping classes can be found. + * @param string|null $fileRegex The regex used to look for mapping files with. + */ + public function __construct(array $paths, string|null $fileRegex = null) { - $this->addPaths(array_values($paths)); + $this->addPaths($paths); + + if ($fileRegex === null) { + return; + } + + $this->setFileRegex($fileRegex); } /** @@ -96,6 +135,6 @@ public function loadMetadataForClass($className, ClassMetadata $metadata): void public function isTransient(string $className): bool { - return $className !== TestClass::class; + return $className === TestClass::class; } } diff --git a/tests/Persistence/Mapping/_files/colocated/Entity.php b/tests/Persistence/Mapping/_files/colocated/Entity.php new file mode 100644 index 00000000..352fe10e --- /dev/null +++ b/tests/Persistence/Mapping/_files/colocated/Entity.php @@ -0,0 +1,9 @@ +