|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00024 require_once 'Zend/Loader.php'; 00025 00035 class Zend_Loader_Autoloader 00036 { 00040 protected static $_instance; 00041 00045 protected $_autoloaders = array(); 00046 00050 protected $_defaultAutoloader = array('Zend_Loader', 'loadClass'); 00051 00055 protected $_fallbackAutoloader = false; 00056 00060 protected $_internalAutoloader; 00061 00065 protected $_namespaces = array( 00066 'Zend_' => true, 00067 'ZendX_' => true, 00068 ); 00069 00073 protected $_namespaceAutoloaders = array(); 00074 00078 protected $_suppressNotFoundWarnings = false; 00079 00083 protected $_zfPath; 00084 00090 public static function getInstance() 00091 { 00092 if (null === self::$_instance) { 00093 self::$_instance = new self(); 00094 } 00095 return self::$_instance; 00096 } 00097 00103 public static function resetInstance() 00104 { 00105 self::$_instance = null; 00106 } 00107 00114 public static function autoload($class) 00115 { 00116 $self = self::getInstance(); 00117 00118 foreach ($self->getClassAutoloaders($class) as $autoloader) { 00119 if ($autoloader instanceof Zend_Loader_Autoloader_Interface) { 00120 if ($autoloader->autoload($class)) { 00121 return true; 00122 } 00123 } elseif (is_array($autoloader)) { 00124 if (call_user_func($autoloader, $class)) { 00125 return true; 00126 } 00127 } elseif (is_string($autoloader) || is_callable($autoloader)) { 00128 if ($autoloader($class)) { 00129 return true; 00130 } 00131 } 00132 } 00133 00134 return false; 00135 } 00136 00143 public function setDefaultAutoloader($callback) 00144 { 00145 if (!is_callable($callback)) { 00146 throw new Zend_Loader_Exception('Invalid callback specified for default autoloader'); 00147 } 00148 00149 $this->_defaultAutoloader = $callback; 00150 return $this; 00151 } 00152 00158 public function getDefaultAutoloader() 00159 { 00160 return $this->_defaultAutoloader; 00161 } 00162 00169 public function setAutoloaders(array $autoloaders) 00170 { 00171 $this->_autoloaders = $autoloaders; 00172 return $this; 00173 } 00174 00180 public function getAutoloaders() 00181 { 00182 return $this->_autoloaders; 00183 } 00184 00191 public function getNamespaceAutoloaders($namespace) 00192 { 00193 $namespace = (string) $namespace; 00194 if (!array_key_exists($namespace, $this->_namespaceAutoloaders)) { 00195 return array(); 00196 } 00197 return $this->_namespaceAutoloaders[$namespace]; 00198 } 00199 00206 public function registerNamespace($namespace) 00207 { 00208 if (is_string($namespace)) { 00209 $namespace = (array) $namespace; 00210 } elseif (!is_array($namespace)) { 00211 throw new Zend_Loader_Exception('Invalid namespace provided'); 00212 } 00213 00214 foreach ($namespace as $ns) { 00215 if (!isset($this->_namespaces[$ns])) { 00216 $this->_namespaces[$ns] = true; 00217 } 00218 } 00219 return $this; 00220 } 00221 00228 public function unregisterNamespace($namespace) 00229 { 00230 if (is_string($namespace)) { 00231 $namespace = (array) $namespace; 00232 } elseif (!is_array($namespace)) { 00233 throw new Zend_Loader_Exception('Invalid namespace provided'); 00234 } 00235 00236 foreach ($namespace as $ns) { 00237 if (isset($this->_namespaces[$ns])) { 00238 unset($this->_namespaces[$ns]); 00239 } 00240 } 00241 return $this; 00242 } 00243 00249 public function getRegisteredNamespaces() 00250 { 00251 return array_keys($this->_namespaces); 00252 } 00253 00254 public function setZfPath($spec, $version = 'latest') 00255 { 00256 $path = $spec; 00257 if (is_array($spec)) { 00258 if (!isset($spec['path'])) { 00259 throw new Zend_Loader_Exception('No path specified for ZF'); 00260 } 00261 $path = $spec['path']; 00262 if (isset($spec['version'])) { 00263 $version = $spec['version']; 00264 } 00265 } 00266 00267 $this->_zfPath = $this->_getVersionPath($path, $version); 00268 set_include_path(implode(PATH_SEPARATOR, array( 00269 $this->_zfPath, 00270 get_include_path(), 00271 ))); 00272 return $this; 00273 } 00274 00275 public function getZfPath() 00276 { 00277 return $this->_zfPath; 00278 } 00279 00286 public function suppressNotFoundWarnings($flag = null) 00287 { 00288 if (null === $flag) { 00289 return $this->_suppressNotFoundWarnings; 00290 } 00291 $this->_suppressNotFoundWarnings = (bool) $flag; 00292 return $this; 00293 } 00294 00301 public function setFallbackAutoloader($flag) 00302 { 00303 $this->_fallbackAutoloader = (bool) $flag; 00304 return $this; 00305 } 00306 00312 public function isFallbackAutoloader() 00313 { 00314 return $this->_fallbackAutoloader; 00315 } 00316 00327 public function getClassAutoloaders($class) 00328 { 00329 $namespace = false; 00330 $autoloaders = array(); 00331 00332 // Add concrete namespaced autoloaders 00333 foreach (array_keys($this->_namespaceAutoloaders) as $ns) { 00334 if ('' == $ns) { 00335 continue; 00336 } 00337 if (0 === strpos($class, $ns)) { 00338 $namespace = $ns; 00339 $autoloaders = $autoloaders + $this->getNamespaceAutoloaders($ns); 00340 break; 00341 } 00342 } 00343 00344 // Add internal namespaced autoloader 00345 foreach ($this->getRegisteredNamespaces() as $ns) { 00346 if (0 === strpos($class, $ns)) { 00347 $namespace = $ns; 00348 $autoloaders[] = $this->_internalAutoloader; 00349 break; 00350 } 00351 } 00352 00353 // Add non-namespaced autoloaders 00354 $autoloaders = $autoloaders + $this->getNamespaceAutoloaders(''); 00355 00356 // Add fallback autoloader 00357 if (!$namespace && $this->isFallbackAutoloader()) { 00358 $autoloaders[] = $this->_internalAutoloader; 00359 } 00360 00361 return $autoloaders; 00362 } 00363 00371 public function unshiftAutoloader($callback, $namespace = '') 00372 { 00373 $autoloaders = $this->getAutoloaders(); 00374 array_unshift($autoloaders, $callback); 00375 $this->setAutoloaders($autoloaders); 00376 00377 $namespace = (array) $namespace; 00378 foreach ($namespace as $ns) { 00379 $autoloaders = $this->getNamespaceAutoloaders($ns); 00380 array_unshift($autoloaders, $callback); 00381 $this->_setNamespaceAutoloaders($autoloaders, $ns); 00382 } 00383 00384 return $this; 00385 } 00386 00394 public function pushAutoloader($callback, $namespace = '') 00395 { 00396 $autoloaders = $this->getAutoloaders(); 00397 array_push($autoloaders, $callback); 00398 $this->setAutoloaders($autoloaders); 00399 00400 $namespace = (array) $namespace; 00401 foreach ($namespace as $ns) { 00402 $autoloaders = $this->getNamespaceAutoloaders($ns); 00403 array_push($autoloaders, $callback); 00404 $this->_setNamespaceAutoloaders($autoloaders, $ns); 00405 } 00406 00407 return $this; 00408 } 00409 00417 public function removeAutoloader($callback, $namespace = null) 00418 { 00419 if (null === $namespace) { 00420 $autoloaders = $this->getAutoloaders(); 00421 if (false !== ($index = array_search($callback, $autoloaders, true))) { 00422 unset($autoloaders[$index]); 00423 $this->setAutoloaders($autoloaders); 00424 } 00425 00426 foreach ($this->_namespaceAutoloaders as $ns => $autoloaders) { 00427 if (false !== ($index = array_search($callback, $autoloaders, true))) { 00428 unset($autoloaders[$index]); 00429 $this->_setNamespaceAutoloaders($autoloaders, $ns); 00430 } 00431 } 00432 } else { 00433 $namespace = (array) $namespace; 00434 foreach ($namespace as $ns) { 00435 $autoloaders = $this->getNamespaceAutoloaders($ns); 00436 if (false !== ($index = array_search($callback, $autoloaders, true))) { 00437 unset($autoloaders[$index]); 00438 $this->_setNamespaceAutoloaders($autoloaders, $ns); 00439 } 00440 } 00441 } 00442 00443 return $this; 00444 } 00445 00453 protected function __construct() 00454 { 00455 spl_autoload_register(array(__CLASS__, 'autoload')); 00456 $this->_internalAutoloader = array($this, '_autoload'); 00457 } 00458 00465 protected function _autoload($class) 00466 { 00467 $callback = $this->getDefaultAutoloader(); 00468 try { 00469 if ($this->suppressNotFoundWarnings()) { 00470 @call_user_func($callback, $class); 00471 } else { 00472 call_user_func($callback, $class); 00473 } 00474 return $class; 00475 } catch (Zend_Exception $e) { 00476 return false; 00477 } 00478 } 00479 00487 protected function _setNamespaceAutoloaders(array $autoloaders, $namespace = '') 00488 { 00489 $namespace = (string) $namespace; 00490 $this->_namespaceAutoloaders[$namespace] = $autoloaders; 00491 return $this; 00492 } 00493 00501 protected function _getVersionPath($path, $version) 00502 { 00503 $type = $this->_getVersionType($version); 00504 00505 if ($type == 'latest') { 00506 $version = 'latest'; 00507 } 00508 00509 $availableVersions = $this->_getAvailableVersions($path, $version); 00510 if (empty($availableVersions)) { 00511 throw new Zend_Loader_Exception('No valid ZF installations discovered'); 00512 } 00513 00514 $matchedVersion = array_pop($availableVersions); 00515 return $matchedVersion; 00516 } 00517 00525 protected function _getVersionType($version) 00526 { 00527 if (strtolower($version) == 'latest') { 00528 return 'latest'; 00529 } 00530 00531 $parts = explode('.', $version); 00532 $count = count($parts); 00533 if (1 == $count) { 00534 return 'major'; 00535 } 00536 if (2 == $count) { 00537 return 'minor'; 00538 } 00539 if (3 < $count) { 00540 throw new Zend_Loader_Exception('Invalid version string provided'); 00541 } 00542 return 'specific'; 00543 } 00544 00552 protected function _getAvailableVersions($path, $version) 00553 { 00554 if (!is_dir($path)) { 00555 throw new Zend_Loader_Exception('Invalid ZF path provided'); 00556 } 00557 00558 $path = rtrim($path, '/'); 00559 $path = rtrim($path, '\\'); 00560 $versionLen = strlen($version); 00561 $versions = array(); 00562 $dirs = glob("$path/*", GLOB_ONLYDIR); 00563 foreach ($dirs as $dir) { 00564 $dirName = substr($dir, strlen($path) + 1); 00565 if (!preg_match('/^(?:ZendFramework-)?(\d+\.\d+\.\d+((a|b|pl|pr|p|rc)\d+)?)(?:-minimal)?$/i', $dirName, $matches)) { 00566 continue; 00567 } 00568 00569 $matchedVersion = $matches[1]; 00570 00571 if (('latest' == $version) 00572 || ((strlen($matchedVersion) >= $versionLen) 00573 && (0 === strpos($matchedVersion, $version))) 00574 ) { 00575 $versions[$matchedVersion] = $dir . '/library'; 00576 } 00577 } 00578 00579 uksort($versions, 'version_compare'); 00580 return $versions; 00581 } 00582 }