Skip to content

Commit e2e1441

Browse files
Add path loader to fluent driver
1 parent 99f1182 commit e2e1441

File tree

1 file changed

+92
-2
lines changed

1 file changed

+92
-2
lines changed

src/FluentDriver.php

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@
66
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver;
77
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
88
use Doctrine\ORM\Mapping\MappingException;
9+
use FilesystemIterator;
910
use InvalidArgumentException;
1011
use LaravelDoctrine\Fluent\Builders\Builder;
1112
use LaravelDoctrine\Fluent\Mappers\MapperSet;
13+
use RecursiveDirectoryIterator;
14+
use RecursiveIteratorIterator;
15+
use RecursiveRegexIterator;
16+
use ReflectionClass;
17+
use RegexIterator;
1218

1319
class FluentDriver implements MappingDriver
1420
{
@@ -22,20 +28,37 @@ class FluentDriver implements MappingDriver
2228
*/
2329
protected $fluentFactory;
2430

31+
/**
32+
* The file extension of mapping documents.
33+
*
34+
* @var string
35+
*/
36+
protected $fileExtension = '.php';
37+
2538
/**
2639
* Initializes a new FileDriver that looks in the given path(s) for mapping
2740
* documents and operates in the specified operating mode.
2841
*
2942
* @param string[] $mappings
43+
* @param array $paths
44+
*
45+
* @throws MappingException
3046
*/
31-
public function __construct(array $mappings = [])
47+
public function __construct(array $mappings = [], array $paths = [])
3248
{
3349
$this->fluentFactory = function (ClassMetadata $metadata) {
3450
return new Builder(new ClassMetadataBuilder($metadata));
3551
};
3652

3753
$this->mappers = new MapperSet();
38-
$this->addMappings($mappings);
54+
55+
if (!empty($paths)) {
56+
$this->loadPaths($paths);
57+
}
58+
59+
if (!empty($mappings)) {
60+
$this->addMappings($mappings);
61+
}
3962
}
4063

4164
/**
@@ -78,8 +101,75 @@ public function isTransient($className)
78101
$this->mappers->getMapperFor($className)->isTransient();
79102
}
80103

104+
/**
105+
* @param array $paths
106+
*
107+
* @throws MappingException
108+
*/
109+
public function loadPaths(array $paths)
110+
{
111+
$classes = [];
112+
$includedFiles = [];
113+
114+
foreach ($paths as $path) {
115+
if (!is_dir($path)) {
116+
throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
117+
}
118+
119+
$iterator = new RegexIterator(
120+
new RecursiveIteratorIterator(
121+
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
122+
RecursiveIteratorIterator::LEAVES_ONLY
123+
),
124+
'/^.+'.preg_quote($this->fileExtension).'$/i',
125+
RecursiveRegexIterator::GET_MATCH
126+
);
127+
128+
foreach ($iterator as $file) {
129+
$sourceFile = $file[0];
130+
131+
if (!preg_match('(^phar:)i', $sourceFile)) {
132+
$sourceFile = realpath($sourceFile);
133+
}
134+
135+
require_once $sourceFile;
136+
137+
$includedFiles[] = $sourceFile;
138+
}
139+
140+
$declared = get_declared_classes();
141+
142+
foreach ($declared as $className) {
143+
$rc = new ReflectionClass($className);
144+
$sourceFile = $rc->getFileName();
145+
146+
if (!in_array($sourceFile, $includedFiles)) {
147+
continue;
148+
}
149+
150+
if ($rc->isAbstract() || $rc->isInterface()) {
151+
continue;
152+
}
153+
154+
if (!$rc->implementsInterface(Mapping::class)) {
155+
continue;
156+
}
157+
158+
if ($this->isTransient($className)) {
159+
160+
/** @var Mapping $mapping */
161+
$mapping = $rc->newInstanceWithoutConstructor();
162+
163+
$this->addMapping($mapping);
164+
}
165+
}
166+
}
167+
}
168+
81169
/**
82170
* @param string[] $mappings
171+
*
172+
* @throws InvalidArgumentException
83173
*/
84174
public function addMappings(array $mappings = [])
85175
{

0 commit comments

Comments
 (0)