Security update to Drupal 8.4.6
[yaffs-website] / vendor / doctrine / common / lib / Doctrine / Common / ClassLoader.php
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;
21
22 /**
23  * A <tt>ClassLoader</tt> is an autoloader for class files that can be
24  * installed on the SPL autoload stack. It is a class loader that either loads only classes
25  * of a specific namespace or all namespaces and it is suitable for working together
26  * with other autoloaders in the SPL autoload stack.
27  *
28  * If no include path is configured through the constructor or {@link setIncludePath}, a ClassLoader
29  * relies on the PHP <code>include_path</code>.
30  *
31  * @author Roman Borschel <roman@code-factory.org>
32  * @since 2.0
33  *
34  * @deprecated the ClassLoader is deprecated and will be removed in version 3.0 of doctrine/common.
35  */
36 class ClassLoader
37 {
38     /**
39      * PHP file extension.
40      *
41      * @var string
42      */
43     protected $fileExtension = '.php';
44
45     /**
46      * Current namespace.
47      *
48      * @var string|null
49      */
50     protected $namespace;
51
52     /**
53      * Current include path.
54      *
55      * @var string|null
56      */
57     protected $includePath;
58
59     /**
60      * PHP namespace separator.
61      *
62      * @var string
63      */
64     protected $namespaceSeparator = '\\';
65
66     /**
67      * Creates a new <tt>ClassLoader</tt> that loads classes of the
68      * specified namespace from the specified include path.
69      *
70      * If no include path is given, the ClassLoader relies on the PHP include_path.
71      * If neither a namespace nor an include path is given, the ClassLoader will
72      * be responsible for loading all classes, thereby relying on the PHP include_path.
73      *
74      * @param string|null $ns          The namespace of the classes to load.
75      * @param string|null $includePath The base include path to use.
76      */
77     public function __construct($ns = null, $includePath = null)
78     {
79         $this->namespace = $ns;
80         $this->includePath = $includePath;
81     }
82
83     /**
84      * Sets the namespace separator used by classes in the namespace of this ClassLoader.
85      *
86      * @param string $sep The separator to use.
87      *
88      * @return void
89      */
90     public function setNamespaceSeparator($sep)
91     {
92         $this->namespaceSeparator = $sep;
93     }
94
95     /**
96      * Gets the namespace separator used by classes in the namespace of this ClassLoader.
97      *
98      * @return string
99      */
100     public function getNamespaceSeparator()
101     {
102         return $this->namespaceSeparator;
103     }
104
105     /**
106      * Sets the base include path for all class files in the namespace of this ClassLoader.
107      *
108      * @param string|null $includePath
109      *
110      * @return void
111      */
112     public function setIncludePath($includePath)
113     {
114         $this->includePath = $includePath;
115     }
116
117     /**
118      * Gets the base include path for all class files in the namespace of this ClassLoader.
119      *
120      * @return string|null
121      */
122     public function getIncludePath()
123     {
124         return $this->includePath;
125     }
126
127     /**
128      * Sets the file extension of class files in the namespace of this ClassLoader.
129      *
130      * @param string $fileExtension
131      *
132      * @return void
133      */
134     public function setFileExtension($fileExtension)
135     {
136         $this->fileExtension = $fileExtension;
137     }
138
139     /**
140      * Gets the file extension of class files in the namespace of this ClassLoader.
141      *
142      * @return string
143      */
144     public function getFileExtension()
145     {
146         return $this->fileExtension;
147     }
148
149     /**
150      * Registers this ClassLoader on the SPL autoload stack.
151      *
152      * @return void
153      */
154     public function register()
155     {
156         spl_autoload_register([$this, 'loadClass']);
157     }
158
159     /**
160      * Removes this ClassLoader from the SPL autoload stack.
161      *
162      * @return void
163      */
164     public function unregister()
165     {
166         spl_autoload_unregister([$this, 'loadClass']);
167     }
168
169     /**
170      * Loads the given class or interface.
171      *
172      * @param string $className The name of the class to load.
173      *
174      * @return boolean TRUE if the class has been successfully loaded, FALSE otherwise.
175      */
176     public function loadClass($className)
177     {
178         if (self::typeExists($className)) {
179             return true;
180         }
181
182         if (! $this->canLoadClass($className)) {
183             return false;
184         }
185
186         require ($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '')
187                . str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className)
188                . $this->fileExtension;
189
190         return self::typeExists($className);
191     }
192
193     /**
194      * Asks this ClassLoader whether it can potentially load the class (file) with
195      * the given name.
196      *
197      * @param string $className The fully-qualified name of the class.
198      *
199      * @return boolean TRUE if this ClassLoader can load the class, FALSE otherwise.
200      */
201     public function canLoadClass($className)
202     {
203         if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) {
204             return false;
205         }
206
207         $file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension;
208
209         if ($this->includePath !== null) {
210             return is_file($this->includePath . DIRECTORY_SEPARATOR . $file);
211         }
212
213         return (false !== stream_resolve_include_path($file));
214     }
215
216     /**
217      * Checks whether a class with a given name exists. A class "exists" if it is either
218      * already defined in the current request or if there is an autoloader on the SPL
219      * autoload stack that is a) responsible for the class in question and b) is able to
220      * load a class file in which the class definition resides.
221      *
222      * If the class is not already defined, each autoloader in the SPL autoload stack
223      * is asked whether it is able to tell if the class exists. If the autoloader is
224      * a <tt>ClassLoader</tt>, {@link canLoadClass} is used, otherwise the autoload
225      * function of the autoloader is invoked and expected to return a value that
226      * evaluates to TRUE if the class (file) exists. As soon as one autoloader reports
227      * that the class exists, TRUE is returned.
228      *
229      * Note that, depending on what kinds of autoloaders are installed on the SPL
230      * autoload stack, the class (file) might already be loaded as a result of checking
231      * for its existence. This is not the case with a <tt>ClassLoader</tt>, who separates
232      * these responsibilities.
233      *
234      * @param string $className The fully-qualified name of the class.
235      *
236      * @return boolean TRUE if the class exists as per the definition given above, FALSE otherwise.
237      */
238     public static function classExists($className)
239     {
240         return self::typeExists($className, true);
241     }
242
243     /**
244      * Gets the <tt>ClassLoader</tt> from the SPL autoload stack that is responsible
245      * for (and is able to load) the class with the given name.
246      *
247      * @param string $className The name of the class.
248      *
249      * @return ClassLoader|null The <tt>ClassLoader</tt> for the class or NULL if no such <tt>ClassLoader</tt> exists.
250      */
251     public static function getClassLoader($className)
252     {
253          foreach (spl_autoload_functions() as $loader) {
254             if (is_array($loader)
255                 && ($classLoader = reset($loader))
256                 && $classLoader instanceof ClassLoader
257                 && $classLoader->canLoadClass($className)
258             ) {
259                 return $classLoader;
260             }
261         }
262
263         return null;
264     }
265
266     /**
267      * Checks whether a given type exists
268      *
269      * @param string $type
270      * @param bool   $autoload
271      *
272      * @return bool
273      */
274     private static function typeExists($type, $autoload = false)
275     {
276         return class_exists($type, $autoload)
277             || interface_exists($type, $autoload)
278             || trait_exists($type, $autoload);
279     }
280 }