Passed
Pull Request — master (#271)
by Andreas
02:25
created

AnnotationRegistry   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 10
Bugs 0 Features 0
Metric Value
eloc 37
c 10
b 0
f 0
dl 0
loc 155
rs 10
wmc 21

7 Methods

Rating   Name   Duplication   Size   Complexity  
A registerFile() 0 3 1
A registerUniqueLoader() 0 4 2
A registerAutoloadNamespace() 0 3 1
A registerLoader() 0 5 1
A registerAutoloadNamespaces() 0 3 1
A reset() 0 5 1
C loadAnnotationClass() 0 43 14
1
<?php
2
/*
3
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 *
15
 * This software consists of voluntary contributions made by many individuals
16
 * and is licensed under the MIT license. For more information, see
17
 * <http://www.doctrine-project.org>.
18
 */
19
20
namespace Doctrine\Common\Annotations;
21
22
final class AnnotationRegistry
23
{
24
    /**
25
     * A map of namespaces to use for autoloading purposes based on a PSR-0 convention.
26
     *
27
     * Contains the namespace as key and an array of directories as value. If the value is NULL
28
     * the include path is used for checking for the corresponding file.
29
     *
30
     * This autoloading mechanism does not utilize the PHP autoloading but implements autoloading on its own.
31
     *
32
     * @var string[][]|string[]|null[]
33
     */
34
    static private $autoloadNamespaces = [];
35
36
    /**
37
     * A map of autoloader callables.
38
     *
39
     * @var callable[]
40
     */
41
    static private $loaders = [];
42
43
    /**
44
     * An array of classes which cannot be found
45
     *
46
     * @var null[] indexed by class name
47
     */
48
    static private $failedToAutoload = [];
49
50
    public static function reset() : void
51
    {
52
        self::$autoloadNamespaces = [];
53
        self::$loaders            = [];
54
        self::$failedToAutoload   = [];
55
    }
56
57
    /**
58
     * Registers file.
59
     *
60
     * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
61
     *             autoloading should be deferred to the globally registered autoloader by then. For now,
62
     *             use @example AnnotationRegistry::registerLoader('class_exists')
63
     */
64
    public static function registerFile(string $file) : void
65
    {
66
        require_once $file;
67
    }
68
69
    /**
70
     * Adds a namespace with one or many directories to look for files or null for the include path.
71
     *
72
     * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
73
     *
74
     * @param string            $namespace
75
     * @param string|array|null $dirs
76
     *
77
     * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
78
     *             autoloading should be deferred to the globally registered autoloader by then. For now,
79
     *             use @example AnnotationRegistry::registerLoader('class_exists')
80
     */
81
    public static function registerAutoloadNamespace(string $namespace, $dirs = null) : void
82
    {
83
        self::$autoloadNamespaces[$namespace] = $dirs;
84
    }
85
86
    /**
87
     * Registers multiple namespaces.
88
     *
89
     * Loading of this namespaces will be done with a PSR-0 namespace loading algorithm.
90
     *
91
     * @param string[][]|string[]|null[] $namespaces indexed by namespace name
92
     *
93
     * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
94
     *             autoloading should be deferred to the globally registered autoloader by then. For now,
95
     *             use @example AnnotationRegistry::registerLoader('class_exists')
96
     */
97
    public static function registerAutoloadNamespaces(array $namespaces) : void
98
    {
99
        self::$autoloadNamespaces = \array_merge(self::$autoloadNamespaces, $namespaces);
100
    }
101
102
    /**
103
     * Registers an autoloading callable for annotations, much like spl_autoload_register().
104
     *
105
     * NOTE: These class loaders HAVE to be silent when a class was not found!
106
     * IMPORTANT: Loaders have to return true if they loaded a class that could contain the searched annotation class.
107
     *
108
     * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
109
     *             autoloading should be deferred to the globally registered autoloader by then. For now,
110
     *             use @example AnnotationRegistry::registerLoader('class_exists')
111
     */
112
    public static function registerLoader(callable $callable) : void
113
    {
114
        // Reset our static cache now that we have a new loader to work with
115
        self::$failedToAutoload   = [];
116
        self::$loaders[]          = $callable;
117
    }
118
119
    /**
120
     * Registers an autoloading callable for annotations, if it is not already registered
121
     *
122
     * @deprecated this method is deprecated and will be removed in doctrine/annotations 2.0
123
     */
124
    public static function registerUniqueLoader(callable $callable) : void
125
    {
126
        if ( ! in_array($callable, self::$loaders, true) ) {
127
            self::registerLoader($callable);
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...istry::registerLoader() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists') ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

127
            /** @scrutinizer ignore-deprecated */ self::registerLoader($callable);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
128
        }
129
    }
130
131
    /**
132
     * Autoloads an annotation class silently.
133
     */
134
    public static function loadAnnotationClass(string $class) : bool
135
    {
136
        if (\class_exists($class, false)) {
137
            return true;
138
        }
139
140
        if (\array_key_exists($class, self::$failedToAutoload)) {
141
            return false;
142
        }
143
144
        foreach (self::$autoloadNamespaces AS $namespace => $dirs) {
145
            if (\strpos($class, $namespace) === 0) {
146
                $file = \str_replace('\\', \DIRECTORY_SEPARATOR, $class) . '.php';
147
148
                if ($dirs === null) {
149
                    if ($path = stream_resolve_include_path($file)) {
150
                        require $path;
151
                        return true;
152
                    }
153
                } else {
154
                    foreach((array) $dirs AS $dir) {
155
                        if (is_file($dir . \DIRECTORY_SEPARATOR . $file)) {
156
                            require $dir . \DIRECTORY_SEPARATOR . $file;
157
                            return true;
158
                        }
159
                    }
160
                }
161
            }
162
        }
163
164
        foreach (self::$loaders AS $loader) {
165
            if ($loader($class) === true) {
166
                return true;
167
            }
168
        }
169
        
170
        if (self::$loaders === [] && self::$autoloadNamespaces === [] && \class_exists($class)) {
171
            return true;
172
        }
173
174
        self::$failedToAutoload[$class] = null;
175
176
        return false;
177
    }
178
}
179