Failed Conditions
Pull Request — master (#1)
by Jonathan
10:52
created

SymfonyFileLocator::getAllClassNames()   C

Complexity

Conditions 8
Paths 3

Size

Total Lines 40
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 5.3846
c 0
b 0
f 0
cc 8
eloc 21
nc 3
nop 1
1
<?php
2
namespace Doctrine\Common\Persistence\Mapping\Driver;
3
4
use Doctrine\Common\Persistence\Mapping\MappingException;
5
6
/**
7
 * The Symfony File Locator makes a simplifying assumptions compared
8
 * to the DefaultFileLocator. By assuming paths only contain entities of a certain
9
 * namespace the mapping files consists of the short classname only.
10
 *
11
 * @author  Fabien Potencier <[email protected]>
12
 * @author  Benjamin Eberlei <[email protected]>
13
 * @license MIT
14
 */
15
class SymfonyFileLocator implements FileLocator
16
{
17
    /**
18
     * The paths where to look for mapping files.
19
     *
20
     * @var array
21
     */
22
    protected $paths = [];
23
24
    /**
25
     * A map of mapping directory path to namespace prefix used to expand class shortnames.
26
     *
27
     * @var array
28
     */
29
    protected $prefixes = [];
30
31
    /**
32
     * File extension that is searched for.
33
     *
34
     * @var string|null
35
     */
36
    protected $fileExtension;
37
38
    /**
39
     * Represents PHP namespace delimiters when looking for files
40
     *
41
     * @var string
42
     */
43
    private $nsSeparator;
44
45
    /**
46
     * Constructor.
47
     *
48
     * @param array       $prefixes
49
     * @param string|null $fileExtension
50
     * @param string      $nsSeparator String which would be used when converting FQCN to filename and vice versa. Should not be empty
51
     */
52
    public function __construct(array $prefixes, $fileExtension = null, $nsSeparator = '.')
53
    {
54
        $this->addNamespacePrefixes($prefixes);
55
        $this->fileExtension = $fileExtension;
56
57
        if (empty($nsSeparator)) {
58
            throw new \InvalidArgumentException('Namespace separator should not be empty');
59
        }
60
61
        $this->nsSeparator = (string) $nsSeparator;
62
    }
63
64
    /**
65
     * Adds Namespace Prefixes.
66
     *
67
     * @param array $prefixes
68
     *
69
     * @return void
70
     */
71
    public function addNamespacePrefixes(array $prefixes)
72
    {
73
        $this->prefixes = array_merge($this->prefixes, $prefixes);
74
        $this->paths    = array_merge($this->paths, array_keys($prefixes));
75
    }
76
77
    /**
78
     * Gets Namespace Prefixes.
79
     *
80
     * @return array
81
     */
82
    public function getNamespacePrefixes()
83
    {
84
        return $this->prefixes;
85
    }
86
87
    /**
88
     * {@inheritDoc}
89
     */
90
    public function getPaths()
91
    {
92
        return $this->paths;
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98
    public function getFileExtension()
99
    {
100
        return $this->fileExtension;
101
    }
102
103
    /**
104
     * Sets the file extension used to look for mapping files under.
105
     *
106
     * @param string $fileExtension The file extension to set.
107
     *
108
     * @return void
109
     */
110
    public function setFileExtension($fileExtension)
111
    {
112
        $this->fileExtension = $fileExtension;
113
    }
114
115
    /**
116
     * {@inheritDoc}
117
     */
118
    public function fileExists($className)
119
    {
120
        $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension;
121
        foreach ($this->paths as $path) {
122
            if ( ! isset($this->prefixes[$path])) {
123
                // global namespace class
124
                if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) {
125
                    return true;
126
                }
127
128
                continue;
129
            }
130
131
            $prefix = $this->prefixes[$path];
132
133
            if (0 !== strpos($className, $prefix . '\\')) {
134
                continue;
135
            }
136
137
            $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension;
138
            if (is_file($filename)) {
139
                return true;
140
            }
141
        }
142
143
        return false;
144
    }
145
146
    /**
147
     * {@inheritDoc}
148
     */
149
    public function getAllClassNames($globalBasename = null)
150
    {
151
        $classes = [];
152
153
        if ($this->paths) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->paths of type array 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...
154
            foreach ((array) $this->paths as $path) {
155
                if ( ! is_dir($path)) {
156
                    throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
157
                }
158
159
                $iterator = new \RecursiveIteratorIterator(
160
                    new \RecursiveDirectoryIterator($path),
161
                    \RecursiveIteratorIterator::LEAVES_ONLY
162
                );
163
164
                foreach ($iterator as $file) {
165
                    $fileName = $file->getBasename($this->fileExtension);
166
167
                    if ($fileName == $file->getBasename() || $fileName == $globalBasename) {
168
                        continue;
169
                    }
170
171
                    // NOTE: All files found here means classes are not transient!
172
                    if (isset($this->prefixes[$path])) {
173
                        // Calculate namespace suffix for given prefix as a relative path from basepath to file path
174
                        $nsSuffix = strtr(
175
                            substr(realpath($file->getPath()), strlen(realpath($path))),
176
                            $this->nsSeparator,
177
                            '\\'
178
                        );
179
180
                        $classes[] = $this->prefixes[$path] . str_replace(DIRECTORY_SEPARATOR, '\\', $nsSuffix) . '\\' . str_replace($this->nsSeparator, '\\', $fileName);
181
                    } else {
182
                        $classes[] = str_replace($this->nsSeparator, '\\', $fileName);
183
                    }
184
                }
185
            }
186
        }
187
188
        return $classes;
189
    }
190
191
    /**
192
     * {@inheritDoc}
193
     */
194
    public function findMappingFile($className)
195
    {
196
        $defaultFileName = str_replace('\\', $this->nsSeparator, $className) . $this->fileExtension;
197
        foreach ($this->paths as $path) {
198
            if ( ! isset($this->prefixes[$path])) {
199
                if (is_file($path . DIRECTORY_SEPARATOR . $defaultFileName)) {
200
                    return $path . DIRECTORY_SEPARATOR . $defaultFileName;
201
                }
202
203
                continue;
204
            }
205
206
            $prefix = $this->prefixes[$path];
207
208
            if (0 !== strpos($className, $prefix . '\\')) {
209
                continue;
210
            }
211
212
            $filename = $path . '/' . strtr(substr($className, strlen($prefix) + 1), '\\', $this->nsSeparator) . $this->fileExtension;
213
            if (is_file($filename)) {
214
                return $filename;
215
            }
216
        }
217
218
        throw MappingException::mappingFileNotFound($className, substr($className, strrpos($className, '\\') + 1) . $this->fileExtension);
219
    }
220
}
221