Failed Conditions
Pull Request — master (#1)
by Jonathan
03:48
created

AnnotationDriver::getAllClassNames()   C

Complexity

Conditions 12
Paths 27

Size

Total Lines 62
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 13.152

Importance

Changes 0
Metric Value
dl 0
loc 62
ccs 28
cts 35
cp 0.8
rs 6.2072
c 0
b 0
f 0
cc 12
eloc 34
nc 27
nop 0
crap 13.152

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Doctrine\Common\Persistence\Mapping\Driver;
3
4
use Doctrine\Common\Annotations\AnnotationReader;
5
use Doctrine\Common\Persistence\Mapping\MappingException;
6
7
/**
8
 * The AnnotationDriver reads the mapping metadata from docblock annotations.
9
 *
10
 * @since  2.2
11
 * @author Benjamin Eberlei <[email protected]>
12
 * @author Guilherme Blanco <[email protected]>
13
 * @author Jonathan H. Wage <[email protected]>
14
 * @author Roman Borschel <[email protected]>
15
 */
16
abstract class AnnotationDriver implements MappingDriver
17
{
18
    /**
19
     * The AnnotationReader.
20
     *
21
     * @var AnnotationReader
22
     */
23
    protected $reader;
24
25
    /**
26
     * The paths where to look for mapping files.
27
     *
28
     * @var array
29
     */
30
    protected $paths = [];
31
32
    /**
33
     * The paths excluded from path where to look for mapping files.
34
     *
35
     * @var array
36
     */
37
    protected $excludePaths = [];
38
39
    /**
40
     * The file extension of mapping documents.
41
     *
42
     * @var string
43
     */
44
    protected $fileExtension = '.php';
45
46
    /**
47
     * Cache for AnnotationDriver#getAllClassNames().
48
     *
49
     * @var array|null
50
     */
51
    protected $classNames;
52
53
    /**
54
     * Name of the entity annotations as keys.
55
     *
56
     * @var array
57
     */
58
    protected $entityAnnotationClasses = [];
59
60
    /**
61
     * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
62
     * docblock annotations.
63
     *
64
     * @param AnnotationReader  $reader The AnnotationReader to use, duck-typed.
65
     * @param string|array|null $paths  One or multiple paths where mapping classes can be found.
66
     */
67 1
    public function __construct($reader, $paths = null)
68
    {
69 1
        $this->reader = $reader;
70 1
        if ($paths) {
71 1
            $this->addPaths((array) $paths);
72
        }
73 1
    }
74
75
    /**
76
     * Appends lookup paths to metadata driver.
77
     *
78
     * @param array $paths
79
     *
80
     * @return void
81
     */
82 1
    public function addPaths(array $paths)
83
    {
84 1
        $this->paths = array_unique(array_merge($this->paths, $paths));
85 1
    }
86
87
    /**
88
     * Retrieves the defined metadata lookup paths.
89
     *
90
     * @return array
91
     */
92
    public function getPaths()
93
    {
94
        return $this->paths;
95
    }
96
97
    /**
98
     * Append exclude lookup paths to metadata driver.
99
     *
100
     * @param array $paths
101
     */
102
    public function addExcludePaths(array $paths)
103
    {
104
        $this->excludePaths = array_unique(array_merge($this->excludePaths, $paths));
105
    }
106
107
    /**
108
     * Retrieve the defined metadata lookup exclude paths.
109
     *
110
     * @return array
111
     */
112
    public function getExcludePaths()
113
    {
114
        return $this->excludePaths;
115
    }
116
117
    /**
118
     * Retrieve the current annotation reader
119
     *
120
     * @return AnnotationReader
121
     */
122
    public function getReader()
123
    {
124
        return $this->reader;
125
    }
126
127
    /**
128
     * Gets the file extension used to look for mapping files under.
129
     *
130
     * @return string
131
     */
132
    public function getFileExtension()
133
    {
134
        return $this->fileExtension;
135
    }
136
137
    /**
138
     * Sets the file extension used to look for mapping files under.
139
     *
140
     * @param string $fileExtension The file extension to set.
141
     *
142
     * @return void
143
     */
144
    public function setFileExtension($fileExtension)
145
    {
146
        $this->fileExtension = $fileExtension;
147
    }
148
149
    /**
150
     * Returns whether the class with the specified name is transient. Only non-transient
151
     * classes, that is entities and mapped superclasses, should have their metadata loaded.
152
     *
153
     * A class is non-transient if it is annotated with an annotation
154
     * from the {@see AnnotationDriver::entityAnnotationClasses}.
155
     *
156
     * @param string $className
157
     *
158
     * @return boolean
159
     */
160 1
    public function isTransient($className)
161
    {
162 1
        $classAnnotations = $this->reader->getClassAnnotations(new \ReflectionClass($className));
163
164 1
        foreach ($classAnnotations as $annot) {
165 1
            if (isset($this->entityAnnotationClasses[get_class($annot)])) {
166 1
                return false;
167
            }
168
        }
169 1
        return true;
170
    }
171
172
    /**
173
     * {@inheritDoc}
174
     */
175 1
    public function getAllClassNames()
176
    {
177 1
        if ($this->classNames !== null) {
178
            return $this->classNames;
179
        }
180
181 1
        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...
182
            throw MappingException::pathRequired();
183
        }
184
185 1
        $classes       = [];
186 1
        $includedFiles = [];
187
188 1
        foreach ($this->paths as $path) {
189 1
            if ( ! is_dir($path)) {
190
                throw MappingException::fileMappingDriversRequireConfiguredDirectoryPath($path);
191
            }
192
193 1
            $iterator = new \RegexIterator(
194 1
                new \RecursiveIteratorIterator(
195 1
                    new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS),
196 1
                    \RecursiveIteratorIterator::LEAVES_ONLY
197
                ),
198 1
                '/^.+' . preg_quote($this->fileExtension) . '$/i',
199 1
                \RecursiveRegexIterator::GET_MATCH
200
            );
201
202 1
            foreach ($iterator as $file) {
203 1
                $sourceFile = $file[0];
204
205 1
                if ( ! preg_match('(^phar:)i', $sourceFile)) {
206 1
                    $sourceFile = realpath($sourceFile);
207
                }
208
209 1
                foreach ($this->excludePaths as $excludePath) {
210
                    $exclude = str_replace('\\', '/', realpath($excludePath));
211
                    $current = str_replace('\\', '/', $sourceFile);
212
213
                    if (strpos($current, $exclude) !== false) {
214
                        continue 2;
215
                    }
216
                }
217
218 1
                require_once $sourceFile;
219
220 1
                $includedFiles[] = $sourceFile;
221
            }
222
        }
223
224 1
        $declared = get_declared_classes();
225
226 1
        foreach ($declared as $className) {
227 1
            $rc         = new \ReflectionClass($className);
228 1
            $sourceFile = $rc->getFileName();
229 1
            if (in_array($sourceFile, $includedFiles) && ! $this->isTransient($className)) {
230 1
                $classes[] = $className;
231
            }
232
        }
233
234 1
        $this->classNames = $classes;
235
236 1
        return $classes;
237
    }
238
}
239