1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Loader
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
#require_once dirname(__FILE__) . '/SplAutoloader.php';
if (class_exists('Zend_Loader_AutoloaderFactory')) return;
/**
* @package Zend_Loader
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/
abstract class Zend_Loader_AutoloaderFactory
{
const STANDARD_AUTOLOADER = 'Zend_Loader_StandardAutoloader';
const CLASS_MAP_AUTOLOADER = 'Zend_Loader_ClassMapAutoloader';
/**
* @var array All autoloaders registered using the factory
*/
protected static $loaders = array();
/**
* @var Zend_Loader_StandardAutoloader StandardAutoloader instance for resolving
* autoloader classes via the include_path
*/
protected static $standardAutoloader;
/**
* Factory for autoloaders
*
* Options should be an array or Traversable object of the following structure:
* <code>
* array(
* '<autoloader class name>' => $autoloaderOptions,
* )
* </code>
*
* The factory will then loop through and instantiate each autoloader with
* the specified options, and register each with the spl_autoloader.
*
* You may retrieve the concrete autoloader instances later using
* {@link getRegisteredAutoloaders()}.
*
* Note that the class names must be resolvable on the include_path or via
* the Zend library, using PSR-0 rules (unless the class has already been
* loaded).
*
* @param array|Traversable $options (optional) options to use. Defaults to Zend_Loader_StandardAutoloader
* @return void
* @throws Zend_Loader_Exception_InvalidArgumentException for invalid options
* @throws Zend_Loader_Exception_InvalidArgumentException for unloadable autoloader classes
*/
public static function factory($options = null)
{
if (null === $options) {
if (!isset(self::$loaders[self::STANDARD_AUTOLOADER])) {
$autoloader = self::getStandardAutoloader();
$autoloader->register();
self::$loaders[self::STANDARD_AUTOLOADER] = $autoloader;
}
// Return so we don't hit the next check's exception (we're done here anyway)
return;
}
if (!is_array($options) && !($options instanceof Traversable)) {
#require_once 'Exception/InvalidArgumentException.php';
throw new Zend_Loader_Exception_InvalidArgumentException(
'Options provided must be an array or Traversable'
);
}
foreach ($options as $class => $options) {
if (!isset(self::$loaders[$class])) {
// Check class map autoloader
if ($class == self::CLASS_MAP_AUTOLOADER) {
if (!class_exists(self::CLASS_MAP_AUTOLOADER)) {
// Extract the filename from the classname
$classMapLoader = substr(
strrchr(self::CLASS_MAP_AUTOLOADER, '_'), 1
);
require_once dirname(__FILE__) . "/$classMapLoader.php";
}
}
// Autoload with standard autoloader
$autoloader = self::getStandardAutoloader();
if (!class_exists($class) && !$autoloader->autoload($class)) {
#require_once 'Exception/InvalidArgumentException.php';
throw new Zend_Loader_Exception_InvalidArgumentException(sprintf(
'Autoloader class "%s" not loaded',
$class
));
}
// unfortunately is_subclass_of is broken on some 5.3 versions
// additionally instanceof is also broken for this use case
if (version_compare(PHP_VERSION, '5.3.7', '>=')) {
if (!is_subclass_of($class, 'Zend_Loader_SplAutoloader')) {
#require_once 'Exception/InvalidArgumentException.php';
throw new Zend_Loader_Exception_InvalidArgumentException(sprintf(
'Autoloader class %s must implement Zend\\Loader\\SplAutoloader',
$class
));
}
}
if ($class === self::STANDARD_AUTOLOADER) {
$autoloader->setOptions($options);
} else {
$autoloader = new $class($options);
}
$autoloader->register();
self::$loaders[$class] = $autoloader;
} else {
self::$loaders[$class]->setOptions($options);
}
}
}
/**
* Get an list of all autoloaders registered with the factory
*
* Returns an array of autoloader instances.
*
* @return array
*/
public static function getRegisteredAutoloaders()
{
return self::$loaders;
}
/**
* Retrieves an autoloader by class name
*
* @param string $class
* @return Zend_Loader_SplAutoloader
* @throws Zend_Loader_Exception_InvalidArgumentException for non-registered class
*/
public static function getRegisteredAutoloader($class)
{
if (!isset(self::$loaders[$class])) {
#require_once 'Exception/InvalidArgumentException.php';
throw new Zend_Loader_Exception_InvalidArgumentException(sprintf('Autoloader class "%s" not loaded', $class));
}
return self::$loaders[$class];
}
/**
* Unregisters all autoloaders that have been registered via the factory.
* This will NOT unregister autoloaders registered outside of the fctory.
*
* @return void
*/
public static function unregisterAutoloaders()
{
foreach (self::getRegisteredAutoloaders() as $class => $autoloader) {
spl_autoload_unregister(array($autoloader, 'autoload'));
unset(self::$loaders[$class]);
}
}
/**
* Unregister a single autoloader by class name
*
* @param string $autoloaderClass
* @return bool
*/
public static function unregisterAutoloader($autoloaderClass)
{
if (!isset(self::$loaders[$autoloaderClass])) {
return false;
}
$autoloader = self::$loaders[$autoloaderClass];
spl_autoload_unregister(array($autoloader, 'autoload'));
unset(self::$loaders[$autoloaderClass]);
return true;
}
/**
* Get an instance of the standard autoloader
*
* Used to attempt to resolve autoloader classes, using the
* StandardAutoloader. The instance is marked as a fallback autoloader, to
* allow resolving autoloaders not under the "Zend" or "Zend" namespaces.
*
* @return Zend_Loader_SplAutoloader
*/
protected static function getStandardAutoloader()
{
if (null !== self::$standardAutoloader) {
return self::$standardAutoloader;
}
// Extract the filename from the classname
$stdAutoloader = substr(strrchr(self::STANDARD_AUTOLOADER, '_'), 1);
if (!class_exists(self::STANDARD_AUTOLOADER)) {
#require_once dirname(__FILE__) . "/$stdAutoloader.php";
}
$loader = new Zend_Loader_StandardAutoloader();
self::$standardAutoloader = $loader;
return self::$standardAutoloader;
}
}