Failed Conditions
Push — types ( 93a36a...3e2fad )
by Jonathan
02:15
created

StaticPHPDriver::addPaths()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Persistence\Mapping\Driver;
6
7
use Doctrine\Persistence\Mapping\ClassMetadata;
8
use Doctrine\Persistence\Mapping\MappingException;
9
use RecursiveDirectoryIterator;
10
use RecursiveIteratorIterator;
11
use ReflectionClass;
12
use function array_merge;
13
use function array_unique;
14
use function get_declared_classes;
15
use function in_array;
16
use function is_dir;
17
use function method_exists;
18
use function realpath;
19
20
/**
21
 * The StaticPHPDriver calls a static loadMetadata() method on your entity
22
 * classes where you can manually populate the ClassMetadata instance.
23
 */
24
class StaticPHPDriver implements MappingDriver
25
{
26
    /**
27
     * Paths of entity directories.
28
     *
29
     * @var array<int, string>
30
     */
31
    private $paths = [];
32
33
    /**
34
     * Map of all class names.
35
     *
36
     * @var array<int, string>
37
     */
38
    private $classNames;
39
40
    /**
41
     * @param array<int, string>|string $paths
42
     */
43 2
    public function __construct($paths)
44
    {
45 2
        $this->addPaths((array) $paths);
46 2
    }
47
48
    /**
49
     * @param array<int, string> $paths
50
     */
51 2
    public function addPaths(array $paths) : void
52
    {
53 2
        $this->paths = array_unique(array_merge($this->paths, $paths));
54 2
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59 1
    public function loadMetadataForClass(string $className, ClassMetadata $metadata) : void
60
    {
61 1
        $className::loadMetadata($metadata);
62 1
    }
63
64
    /**
65
     * {@inheritDoc}
66
     *
67
     * @todo Same code exists in AnnotationDriver, should we re-use it somehow or not worry about it?
68
     */
69 1
    public function getAllClassNames() : array
70
    {
71 1
        if ($this->classNames !== null) {
72
            return $this->classNames;
73
        }
74
75 1
        if ($this->paths === []) {
76
            throw MappingException::pathRequired();
77
        }
78
79 1
        $classes       = [];
80 1
        $includedFiles = [];
81
82 1
        foreach ($this->paths as $path) {
83 1
            if (! is_dir($path)) {
84
                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
85
            }
86
87 1
            $iterator = new RecursiveIteratorIterator(
88 1
                new RecursiveDirectoryIterator($path),
89 1
                RecursiveIteratorIterator::LEAVES_ONLY
90
            );
91
92 1
            foreach ($iterator as $file) {
93 1
                if ($file->getBasename('.php') === $file->getBasename()) {
94 1
                    continue;
95
                }
96
97 1
                $sourceFile = realpath($file->getPathName());
98 1
                require_once $sourceFile;
99 1
                $includedFiles[] = $sourceFile;
100
            }
101
        }
102
103 1
        $declared = get_declared_classes();
104
105 1
        foreach ($declared as $className) {
106 1
            $rc = new ReflectionClass($className);
107
108 1
            $sourceFile = $rc->getFileName();
109
110 1
            if (! in_array($sourceFile, $includedFiles, true) || $this->isTransient($className)) {
111 1
                continue;
112
            }
113
114 1
            $classes[] = $className;
115
        }
116
117 1
        $this->classNames = $classes;
118
119 1
        return $classes;
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125 1
    public function isTransient(string $className) : bool
126
    {
127 1
        return ! method_exists($className, 'loadMetadata');
128
    }
129
}
130