Completed
Pull Request — master (#50)
by Jonathan
04:19 queued 02:16
created

DefaultFileLocator::getAllClassNames()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 35
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 7.0671

Importance

Changes 0
Metric Value
eloc 17
dl 0
loc 35
ccs 16
cts 18
cp 0.8889
rs 8.8333
c 0
b 0
f 0
cc 7
nc 6
nop 1
crap 7.0671
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Persistence\Mapping\Driver;
6
7
use Doctrine\Persistence\Mapping\MappingException;
8
use RecursiveDirectoryIterator;
9
use RecursiveIteratorIterator;
10
use const DIRECTORY_SEPARATOR;
11
use function array_merge;
12
use function array_unique;
13
use function assert;
14
use function is_dir;
15
use function is_file;
16
use function is_string;
17
use function str_replace;
18
19
/**
20
 * Locates the file that contains the metadata information for a given class name.
21
 *
22
 * This behavior is independent of the actual content of the file. It just detects
23
 * the file which is responsible for the given class name.
24
 */
25
class DefaultFileLocator implements FileLocator
26
{
27
    /**
28
     * The paths where to look for mapping files.
29
     *
30
     * @var array<int, string>
31
     */
32
    protected $paths = [];
33
34
    /**
35
     * The file extension of mapping documents.
36
     *
37
     * @var string|null
38
     */
39
    protected $fileExtension;
40
41
    /**
42
     * Initializes a new FileDriver that looks in the given path(s) for mapping
43
     * documents and operates in the specified operating mode.
44
     *
45
     * @param string|array<int, string> $paths         One or multiple paths where mapping documents
46
     *                                                 can be found.
47
     * @param string|null               $fileExtension The file extension of mapping documents,
48
     *                                                 usually prefixed with a dot.
49
     */
50 11
    public function __construct($paths, ?string $fileExtension = null)
51
    {
52 11
        $this->addPaths((array) $paths);
53 11
        $this->fileExtension = $fileExtension;
54 11
    }
55
56
    /**
57
     * Appends lookup paths to metadata driver.
58
     *
59
     * @param array<int, string> $paths
60
     */
61 11
    public function addPaths(array $paths) : void
62
    {
63 11
        $this->paths = array_unique(array_merge($this->paths, $paths));
64 11
    }
65
66
    /**
67
     * Retrieves the defined metadata lookup paths.
68
     *
69
     * @return array<int, string>
70
     */
71 3
    public function getPaths() : array
72
    {
73 3
        return $this->paths;
74
    }
75
76
    /**
77
     * Gets the file extension used to look for mapping files under.
78
     */
79 2
    public function getFileExtension() : ?string
80
    {
81 2
        return $this->fileExtension;
82
    }
83
84
    /**
85
     * Sets the file extension used to look for mapping files under.
86
     *
87
     * @param string|null $fileExtension The file extension to set.
88
     */
89 1
    public function setFileExtension(?string $fileExtension) : void
90
    {
91 1
        $this->fileExtension = $fileExtension;
92 1
    }
93
94
    /**
95
     * {@inheritDoc}
96
     */
97 3
    public function findMappingFile(string $className) : string
98
    {
99 3
        $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
100
101
        // Check whether file exists
102 3
        foreach ($this->paths as $path) {
103 3
            if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) {
104 2
                return $path . DIRECTORY_SEPARATOR . $fileName;
105
            }
106
        }
107
108 1
        throw MappingException::mappingFileNotFound($className, $fileName);
109
    }
110
111
    /**
112
     * {@inheritDoc}
113
     */
114 2
    public function getAllClassNames(string $globalBasename) : array
115
    {
116 2
        if ($this->paths === []) {
117
            return [];
118
        }
119
120 2
        $classes = [];
121
122 2
        foreach ($this->paths as $path) {
123 2
            if (! is_dir($path)) {
124
                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
125
            }
126
127 2
            $iterator = new RecursiveIteratorIterator(
128 2
                new RecursiveDirectoryIterator($path),
129 2
                RecursiveIteratorIterator::LEAVES_ONLY
130
            );
131
132 2
            foreach ($iterator as $file) {
133 2
                $fileName = $file->getBasename($this->fileExtension);
134
135 2
                if ($fileName === $file->getBasename() || $fileName === $globalBasename) {
136 2
                    continue;
137
                }
138
139
                // NOTE: All files found here means classes are not transient!
140
141 1
                $class = str_replace('.', '\\', $fileName);
142 1
                assert(is_string($class));
143
144 1
                $classes[] = $class;
145
            }
146
        }
147
148 2
        return $classes;
149
    }
150
151
    /**
152
     * {@inheritDoc}
153
     */
154 2
    public function fileExists(string $className) : bool
155
    {
156 2
        $fileName = str_replace('\\', '.', $className) . $this->fileExtension;
157
158
        // Check whether file exists
159 2
        foreach ($this->paths as $path) {
160 2
            if (is_file($path . DIRECTORY_SEPARATOR . $fileName)) {
161 2
                return true;
162
            }
163
        }
164
165 2
        return false;
166
    }
167
}
168