Failed Conditions
Push — master ( 3a6c46...2fbe69 )
by Luís
36s queued 11s
created

SymfonyFileLocator::getPaths()   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 0
crap 1
1
<?php
2
3
namespace Doctrine\Persistence\Mapping\Driver;
4
5
use Doctrine\Persistence\Mapping\MappingException;
6
use InvalidArgumentException;
7
use RecursiveDirectoryIterator;
8
use RecursiveIteratorIterator;
9
use const DIRECTORY_SEPARATOR;
10
use function array_keys;
11
use function array_merge;
12
use function is_dir;
13
use function is_file;
14
use function realpath;
15
use function str_replace;
16
use function strlen;
17
use function strpos;
18
use function strrpos;
19
use function strtr;
20
use function substr;
21
22
/**
23
 * The Symfony File Locator makes a simplifying assumptions compared
24
 * to the DefaultFileLocator. By assuming paths only contain entities of a certain
25
 * namespace the mapping files consists of the short classname only.
26
 */
27
class SymfonyFileLocator implements FileLocator
28
{
29
    /**
30
     * The paths where to look for mapping files.
31
     *
32
     * @var string[]
33
     */
34
    protected $paths = [];
35
36
    /**
37
     * A map of mapping directory path to namespace prefix used to expand class shortnames.
38
     *
39
     * @var string[]
40
     */
41
    protected $prefixes = [];
42
43
    /**
44
     * File extension that is searched for.
45
     *
46
     * @var string|null
47
     */
48
    protected $fileExtension;
49
50
    /**
51
     * Represents PHP namespace delimiters when looking for files
52
     *
53
     * @var string
54
     */
55
    private $nsSeparator;
56
57
    /**
58
     * @param string[]    $prefixes
59
     * @param string|null $fileExtension
60
     * @param string      $nsSeparator   String which would be used when converting FQCN to filename and vice versa. Should not be empty
61
     */
62 14
    public function __construct(array $prefixes, $fileExtension = null, $nsSeparator = '.')
63
    {
64 14
        $this->addNamespacePrefixes($prefixes);
65 14
        $this->fileExtension = $fileExtension;
66
67 14
        if (empty($nsSeparator)) {
68 1
            throw new InvalidArgumentException('Namespace separator should not be empty');
69
        }
70
71 13
        $this->nsSeparator = (string) $nsSeparator;
72 13
    }
73
74
    /**
75
     * Adds Namespace Prefixes.
76
     *
77
     * @param string[] $prefixes
78
     *
79
     * @return void
80
     */
81 14
    public function addNamespacePrefixes(array $prefixes)
82
    {
83 14
        $this->prefixes = array_merge($this->prefixes, $prefixes);
84 14
        $this->paths    = array_merge($this->paths, array_keys($prefixes));
85 14
    }
86
87
    /**
88
     * Gets Namespace Prefixes.
89
     *
90
     * @return string[]
91
     */
92 1
    public function getNamespacePrefixes()
93
    {
94 1
        return $this->prefixes;
95
    }
96
97
    /**
98
     * {@inheritDoc}
99
     */
100 1
    public function getPaths()
101
    {
102 1
        return $this->paths;
103
    }
104
105
    /**
106
     * {@inheritDoc}
107
     */
108 1
    public function getFileExtension()
109
    {
110 1
        return $this->fileExtension;
111
    }
112
113
    /**
114
     * Sets the file extension used to look for mapping files under.
115
     *
116
     * @param string $fileExtension The file extension to set.
117
     *
118
     * @return void
119
     */
120 1
    public function setFileExtension($fileExtension)
121
    {
122 1
        $this->fileExtension = $fileExtension;
123 1
    }
124
125
    /**
126
     * {@inheritDoc}
127
     */
128 1
    public function fileExists($className)
129
    {
130 1
        $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension;
131 1
        foreach ($this->paths as $path) {
132 1
            if (! isset($this->prefixes[$path])) {
133
                // global namespace class
134
                if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) {
135
                    return true;
136
                }
137
138
                continue;
139
            }
140
141 1
            $prefix = $this->prefixes[$path];
142
143 1
            if (strpos($className, $prefix . '\\') !== 0) {
144
                continue;
145
            }
146
147 1
            $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension;
148 1
            if (is_file($filename)) {
149 1
                return true;
150
            }
151
        }
152
153 1
        return false;
154
    }
155
156
    /**
157
     * {@inheritDoc}
158
     */
159 3
    public function getAllClassNames($globalBasename = null)
160
    {
161 3
        $classes = [];
162
163 3
        if ($this->paths) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->paths of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
164 3
            foreach ((array) $this->paths as $path) {
165 3
                if (! is_dir($path)) {
166
                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
167
                }
168
169 3
                $iterator = new RecursiveIteratorIterator(
170 3
                    new RecursiveDirectoryIterator($path),
171 3
                    RecursiveIteratorIterator::LEAVES_ONLY
172
                );
173
174 3
                foreach ($iterator as $file) {
175 3
                    $fileName = $file->getBasename($this->fileExtension);
176
177 3
                    if ($fileName === $file->getBasename() || $fileName === $globalBasename) {
178 3
                        continue;
179
                    }
180
181
                    // NOTE: All files found here means classes are not transient!
182 3
                    if (isset($this->prefixes[$path])) {
183
                        // Calculate namespace suffix for given prefix as a relative path from basepath to file path
184 3
                        $nsSuffix = strtr(
185 3
                            substr(realpath($file->getPath()), strlen(realpath($path))),
186 3
                            $this->nsSeparator,
187 3
                            '\\'
188
                        );
189
190 3
                        $classes[] = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' . str_replace($this->nsSeparator, '\\', $fileName);
191
                    } else {
192 3
                        $classes[] = str_replace($this->nsSeparator, '\\', $fileName);
193
                    }
194
                }
195
            }
196
        }
197
198 3
        return $classes;
199
    }
200
201
    /**
202
     * {@inheritDoc}
203
     */
204 6
    public function findMappingFile($className)
205
    {
206 6
        $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension;
207 6
        foreach ($this->paths as $path) {
208 6
            if (! isset($this->prefixes[$path])) {
209
                if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) {
210
                    return $path . DIRECTORY_SEPARATOR . $defaultFileName;
211
                }
212
213
                continue;
214
            }
215
216 6
            $prefix = $this->prefixes[$path];
217
218 6
            if (strpos($className, $prefix . '\\') !== 0) {
219
                continue;
220
            }
221
222 6
            $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension;
223 6
            if (is_file($filename)) {
224 6
                return $filename;
225
            }
226
        }
227
228 1
        throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1) . $this->fileExtension);
229
    }
230
}
231