Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"phpstan/phpstan-strict-rules": "^1.1",
"doctrine/coding-standard": "^12",
"phpunit/phpunit": "^9.6",
"symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0"
"symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0",
"symfony/finder": "^4.4 || ^5.4 || ^6.0 || ^7.0"
},
"autoload": {
"psr-4": {
Expand Down
14 changes: 14 additions & 0 deletions src/Persistence/Mapping/Driver/ClassLocator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Doctrine\Persistence\Mapping\Driver;

/**
* ClassLocator is an interface for classes that can provide a list of class names.
*/
interface ClassLocator
{
/** @return list<class-string> */
public function getClassNames(): array;
}
23 changes: 23 additions & 0 deletions src/Persistence/Mapping/Driver/ClassNames.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Doctrine\Persistence\Mapping\Driver;

/**
* Basic implementation of ClassLocator that passes a list of class names.
*/
final class ClassNames implements ClassLocator
{
/** @param list<class-string> $classNames */
public function __construct(
private array $classNames,
) {
}

/** @return list<class-string> */
public function getClassNames(): array
{
return $this->classNames;
}
}
92 changes: 17 additions & 75 deletions src/Persistence/Mapping/Driver/ColocatedMappingDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,17 @@
namespace Doctrine\Persistence\Mapping\Driver;

use Doctrine\Persistence\Mapping\MappingException;
use ReflectionClass;

use function array_filter;
use function array_merge;
use function array_unique;
use function assert;
use function get_declared_classes;
use function preg_match;
use function realpath;
use function str_contains;
use function str_replace;

/**
* The ColocatedMappingDriver reads the mapping metadata located near the code.
*/
trait ColocatedMappingDriver
{
/** @var iterable<array-key,string> */
private iterable $filePaths;
private ClassLocator $classLocator;

/**
* The directory paths where to look for mapping files.
Expand Down Expand Up @@ -123,75 +116,24 @@ public function getAllClassNames(): array
return $this->classNames;
}

if ($this->paths === [] && ! isset($this->filePaths)) {
throw MappingException::pathRequiredForDriver(static::class);
}

$dirFilesIterator = new DirectoryFilesIterator($this->paths, $this->fileExtension);

/** @var iterable<string> $filePathsIterator */
$filePathsIterator = $this->concatIterables(
$this->filePaths ?? [],
new FilePathNameIterator($dirFilesIterator),
);

/** @var array<string,true> $includedFiles */
$includedFiles = [];

foreach ($filePathsIterator as $sourceFile) {
if (preg_match('(^phar:)i', $sourceFile) === 0) {
$sourceFile = realpath($sourceFile);
assert($sourceFile !== false);
}

foreach ($this->excludePaths as $excludePath) {
$realExcludePath = realpath($excludePath);
assert($realExcludePath !== false);
$exclude = str_replace('\\', '/', $realExcludePath);
$current = str_replace('\\', '/', $sourceFile);

if (str_contains($current, $exclude)) {
continue 2;
}
}

require_once $sourceFile;

$includedFiles[$sourceFile] = true;
}
if ($this->paths !== []) {
$classNames = FileClassLocator::createFromDirectories($this->paths, $this->excludePaths, $this->fileExtension)->getClassNames();

$classes = [];
$declared = get_declared_classes();

foreach ($declared as $className) {
$rc = new ReflectionClass($className);

$sourceFile = $rc->getFileName();

if (! isset($includedFiles[$sourceFile]) || $this->isTransient($className)) {
continue;
if (isset($this->classLocator)) {
$classNames = array_unique([
...$classNames,
...$this->classLocator->getClassNames(),
]);
}

$classes[] = $className;
} elseif (isset($this->classLocator)) {
$classNames = $this->classLocator->getClassNames();
} else {
throw MappingException::pathRequiredForDriver(static::class);
}

$this->classNames = $classes;

return $classes;
}

/**
* @param iterable<TKey, T> $iterable1
* @param iterable<TKey, T> $iterable2
*
* @return iterable<TKey, T>
*
* @template TKey
* @template T
*/
private function concatIterables(iterable $iterable1, iterable $iterable2): iterable
{
yield from $iterable1;
yield from $iterable2;
return $this->classNames = array_filter(
$classNames,
fn (string $className): bool => ! $this->isTransient($className),
);
}
}
61 changes: 0 additions & 61 deletions src/Persistence/Mapping/Driver/DirectoryFilesIterator.php

This file was deleted.

Loading