[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to [email protected] so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Loader 17 * @subpackage Autoloader 18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 19 * @version $Id$ 20 * @license http://framework.zend.com/license/new-bsd New BSD License 21 */ 22 23 /** Zend_Loader */ 24 require_once 'Zend/Loader.php'; 25 26 /** 27 * Autoloader stack and namespace autoloader 28 * 29 * @uses Zend_Loader_Autoloader 30 * @package Zend_Loader 31 * @subpackage Autoloader 32 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 33 * @license http://framework.zend.com/license/new-bsd New BSD License 34 */ 35 class Zend_Loader_Autoloader 36 { 37 /** 38 * @var Zend_Loader_Autoloader Singleton instance 39 */ 40 protected static $_instance; 41 42 /** 43 * @var array Concrete autoloader callback implementations 44 */ 45 protected $_autoloaders = array(); 46 47 /** 48 * @var array Default autoloader callback 49 */ 50 protected $_defaultAutoloader = array('Zend_Loader', 'loadClass'); 51 52 /** 53 * @var bool Whether or not to act as a fallback autoloader 54 */ 55 protected $_fallbackAutoloader = false; 56 57 /** 58 * @var array Callback for internal autoloader implementation 59 */ 60 protected $_internalAutoloader; 61 62 /** 63 * @var array Supported namespaces 'Zend' and 'ZendX' by default. 64 */ 65 protected $_namespaces = array( 66 'Zend_' => true, 67 'ZendX_' => true, 68 ); 69 70 /** 71 * @var array Namespace-specific autoloaders 72 */ 73 protected $_namespaceAutoloaders = array(); 74 75 /** 76 * @var bool Whether or not to suppress file not found warnings 77 */ 78 protected $_suppressNotFoundWarnings = false; 79 80 /** 81 * @var null|string 82 */ 83 protected $_zfPath; 84 85 /** 86 * Retrieve singleton instance 87 * 88 * @return Zend_Loader_Autoloader 89 */ 90 public static function getInstance() 91 { 92 if (null === self::$_instance) { 93 self::$_instance = new self(); 94 } 95 return self::$_instance; 96 } 97 98 /** 99 * Reset the singleton instance 100 * 101 * @return void 102 */ 103 public static function resetInstance() 104 { 105 self::$_instance = null; 106 } 107 108 /** 109 * Autoload a class 110 * 111 * @param string $class 112 * @return bool 113 */ 114 public static function autoload($class) 115 { 116 $self = self::getInstance(); 117 118 foreach ($self->getClassAutoloaders($class) as $autoloader) { 119 if ($autoloader instanceof Zend_Loader_Autoloader_Interface) { 120 if ($autoloader->autoload($class)) { 121 return true; 122 } 123 } elseif (is_array($autoloader)) { 124 if (call_user_func($autoloader, $class)) { 125 return true; 126 } 127 } elseif (is_string($autoloader) || is_callable($autoloader)) { 128 if ($autoloader($class)) { 129 return true; 130 } 131 } 132 } 133 134 return false; 135 } 136 137 /** 138 * Set the default autoloader implementation 139 * 140 * @param string|array $callback PHP callback 141 * @return void 142 */ 143 public function setDefaultAutoloader($callback) 144 { 145 if (!is_callable($callback)) { 146 throw new Zend_Loader_Exception('Invalid callback specified for default autoloader'); 147 } 148 149 $this->_defaultAutoloader = $callback; 150 return $this; 151 } 152 153 /** 154 * Retrieve the default autoloader callback 155 * 156 * @return string|array PHP Callback 157 */ 158 public function getDefaultAutoloader() 159 { 160 return $this->_defaultAutoloader; 161 } 162 163 /** 164 * Set several autoloader callbacks at once 165 * 166 * @param array $autoloaders Array of PHP callbacks (or Zend_Loader_Autoloader_Interface implementations) to act as autoloaders 167 * @return Zend_Loader_Autoloader 168 */ 169 public function setAutoloaders(array $autoloaders) 170 { 171 $this->_autoloaders = $autoloaders; 172 return $this; 173 } 174 175 /** 176 * Get attached autoloader implementations 177 * 178 * @return array 179 */ 180 public function getAutoloaders() 181 { 182 return $this->_autoloaders; 183 } 184 185 /** 186 * Return all autoloaders for a given namespace 187 * 188 * @param string $namespace 189 * @return array 190 */ 191 public function getNamespaceAutoloaders($namespace) 192 { 193 $namespace = (string) $namespace; 194 if (!array_key_exists($namespace, $this->_namespaceAutoloaders)) { 195 return array(); 196 } 197 return $this->_namespaceAutoloaders[$namespace]; 198 } 199 200 /** 201 * Register a namespace to autoload 202 * 203 * @param string|array $namespace 204 * @return Zend_Loader_Autoloader 205 */ 206 public function registerNamespace($namespace) 207 { 208 if (is_string($namespace)) { 209 $namespace = (array) $namespace; 210 } elseif (!is_array($namespace)) { 211 throw new Zend_Loader_Exception('Invalid namespace provided'); 212 } 213 214 foreach ($namespace as $ns) { 215 if (!isset($this->_namespaces[$ns])) { 216 $this->_namespaces[$ns] = true; 217 } 218 } 219 return $this; 220 } 221 222 /** 223 * Unload a registered autoload namespace 224 * 225 * @param string|array $namespace 226 * @return Zend_Loader_Autoloader 227 */ 228 public function unregisterNamespace($namespace) 229 { 230 if (is_string($namespace)) { 231 $namespace = (array) $namespace; 232 } elseif (!is_array($namespace)) { 233 throw new Zend_Loader_Exception('Invalid namespace provided'); 234 } 235 236 foreach ($namespace as $ns) { 237 if (isset($this->_namespaces[$ns])) { 238 unset($this->_namespaces[$ns]); 239 } 240 } 241 return $this; 242 } 243 244 /** 245 * Get a list of registered autoload namespaces 246 * 247 * @return array 248 */ 249 public function getRegisteredNamespaces() 250 { 251 return array_keys($this->_namespaces); 252 } 253 254 public function setZfPath($spec, $version = 'latest') 255 { 256 $path = $spec; 257 if (is_array($spec)) { 258 if (!isset($spec['path'])) { 259 throw new Zend_Loader_Exception('No path specified for ZF'); 260 } 261 $path = $spec['path']; 262 if (isset($spec['version'])) { 263 $version = $spec['version']; 264 } 265 } 266 267 $this->_zfPath = $this->_getVersionPath($path, $version); 268 set_include_path(implode(PATH_SEPARATOR, array( 269 $this->_zfPath, 270 get_include_path(), 271 ))); 272 return $this; 273 } 274 275 public function getZfPath() 276 { 277 return $this->_zfPath; 278 } 279 280 /** 281 * Get or set the value of the "suppress not found warnings" flag 282 * 283 * @param null|bool $flag 284 * @return bool|Zend_Loader_Autoloader Returns boolean if no argument is passed, object instance otherwise 285 */ 286 public function suppressNotFoundWarnings($flag = null) 287 { 288 if (null === $flag) { 289 return $this->_suppressNotFoundWarnings; 290 } 291 $this->_suppressNotFoundWarnings = (bool) $flag; 292 return $this; 293 } 294 295 /** 296 * Indicate whether or not this autoloader should be a fallback autoloader 297 * 298 * @param bool $flag 299 * @return Zend_Loader_Autoloader 300 */ 301 public function setFallbackAutoloader($flag) 302 { 303 $this->_fallbackAutoloader = (bool) $flag; 304 return $this; 305 } 306 307 /** 308 * Is this instance acting as a fallback autoloader? 309 * 310 * @return bool 311 */ 312 public function isFallbackAutoloader() 313 { 314 return $this->_fallbackAutoloader; 315 } 316 317 /** 318 * Get autoloaders to use when matching class 319 * 320 * Determines if the class matches a registered namespace, and, if so, 321 * returns only the autoloaders for that namespace. Otherwise, it returns 322 * all non-namespaced autoloaders. 323 * 324 * @param string $class 325 * @return array Array of autoloaders to use 326 */ 327 public function getClassAutoloaders($class) 328 { 329 $namespace = false; 330 $autoloaders = array(); 331 332 // Add concrete namespaced autoloaders 333 foreach (array_keys($this->_namespaceAutoloaders) as $ns) { 334 if ('' == $ns) { 335 continue; 336 } 337 if (0 === strpos($class, $ns)) { 338 $namespace = $ns; 339 $autoloaders = $autoloaders + $this->getNamespaceAutoloaders($ns); 340 break; 341 } 342 } 343 344 // Add internal namespaced autoloader 345 foreach ($this->getRegisteredNamespaces() as $ns) { 346 if (0 === strpos($class, $ns)) { 347 $namespace = $ns; 348 $autoloaders[] = $this->_internalAutoloader; 349 break; 350 } 351 } 352 353 // Add non-namespaced autoloaders 354 $autoloaders = $autoloaders + $this->getNamespaceAutoloaders(''); 355 356 // Add fallback autoloader 357 if (!$namespace && $this->isFallbackAutoloader()) { 358 $autoloaders[] = $this->_internalAutoloader; 359 } 360 361 return $autoloaders; 362 } 363 364 /** 365 * Add an autoloader to the beginning of the stack 366 * 367 * @param object|array|string $callback PHP callback or Zend_Loader_Autoloader_Interface implementation 368 * @param string|array $namespace Specific namespace(s) under which to register callback 369 * @return Zend_Loader_Autoloader 370 */ 371 public function unshiftAutoloader($callback, $namespace = '') 372 { 373 $autoloaders = $this->getAutoloaders(); 374 array_unshift($autoloaders, $callback); 375 $this->setAutoloaders($autoloaders); 376 377 $namespace = (array) $namespace; 378 foreach ($namespace as $ns) { 379 $autoloaders = $this->getNamespaceAutoloaders($ns); 380 array_unshift($autoloaders, $callback); 381 $this->_setNamespaceAutoloaders($autoloaders, $ns); 382 } 383 384 return $this; 385 } 386 387 /** 388 * Append an autoloader to the autoloader stack 389 * 390 * @param object|array|string $callback PHP callback or Zend_Loader_Autoloader_Interface implementation 391 * @param string|array $namespace Specific namespace(s) under which to register callback 392 * @return Zend_Loader_Autoloader 393 */ 394 public function pushAutoloader($callback, $namespace = '') 395 { 396 $autoloaders = $this->getAutoloaders(); 397 array_push($autoloaders, $callback); 398 $this->setAutoloaders($autoloaders); 399 400 $namespace = (array) $namespace; 401 foreach ($namespace as $ns) { 402 $autoloaders = $this->getNamespaceAutoloaders($ns); 403 array_push($autoloaders, $callback); 404 $this->_setNamespaceAutoloaders($autoloaders, $ns); 405 } 406 407 return $this; 408 } 409 410 /** 411 * Remove an autoloader from the autoloader stack 412 * 413 * @param object|array|string $callback PHP callback or Zend_Loader_Autoloader_Interface implementation 414 * @param null|string|array $namespace Specific namespace(s) from which to remove autoloader 415 * @return Zend_Loader_Autoloader 416 */ 417 public function removeAutoloader($callback, $namespace = null) 418 { 419 if (null === $namespace) { 420 $autoloaders = $this->getAutoloaders(); 421 if (false !== ($index = array_search($callback, $autoloaders, true))) { 422 unset($autoloaders[$index]); 423 $this->setAutoloaders($autoloaders); 424 } 425 426 foreach ($this->_namespaceAutoloaders as $ns => $autoloaders) { 427 if (false !== ($index = array_search($callback, $autoloaders, true))) { 428 unset($autoloaders[$index]); 429 $this->_setNamespaceAutoloaders($autoloaders, $ns); 430 } 431 } 432 } else { 433 $namespace = (array) $namespace; 434 foreach ($namespace as $ns) { 435 $autoloaders = $this->getNamespaceAutoloaders($ns); 436 if (false !== ($index = array_search($callback, $autoloaders, true))) { 437 unset($autoloaders[$index]); 438 $this->_setNamespaceAutoloaders($autoloaders, $ns); 439 } 440 } 441 } 442 443 return $this; 444 } 445 446 /** 447 * Constructor 448 * 449 * Registers instance with spl_autoload stack 450 * 451 * @return void 452 */ 453 protected function __construct() 454 { 455 spl_autoload_register(array(__CLASS__, 'autoload')); 456 $this->_internalAutoloader = array($this, '_autoload'); 457 } 458 459 /** 460 * Internal autoloader implementation 461 * 462 * @param string $class 463 * @return bool 464 */ 465 protected function _autoload($class) 466 { 467 $callback = $this->getDefaultAutoloader(); 468 try { 469 if ($this->suppressNotFoundWarnings()) { 470 @call_user_func($callback, $class); 471 } else { 472 call_user_func($callback, $class); 473 } 474 return $class; 475 } catch (Zend_Exception $e) { 476 return false; 477 } 478 } 479 480 /** 481 * Set autoloaders for a specific namespace 482 * 483 * @param array $autoloaders 484 * @param string $namespace 485 * @return Zend_Loader_Autoloader 486 */ 487 protected function _setNamespaceAutoloaders(array $autoloaders, $namespace = '') 488 { 489 $namespace = (string) $namespace; 490 $this->_namespaceAutoloaders[$namespace] = $autoloaders; 491 return $this; 492 } 493 494 /** 495 * Retrieve the filesystem path for the requested ZF version 496 * 497 * @param string $path 498 * @param string $version 499 * @return void 500 */ 501 protected function _getVersionPath($path, $version) 502 { 503 $type = $this->_getVersionType($version); 504 505 if ($type == 'latest') { 506 $version = 'latest'; 507 } 508 509 $availableVersions = $this->_getAvailableVersions($path, $version); 510 if (empty($availableVersions)) { 511 throw new Zend_Loader_Exception('No valid ZF installations discovered'); 512 } 513 514 $matchedVersion = array_pop($availableVersions); 515 return $matchedVersion; 516 } 517 518 /** 519 * Retrieve the ZF version type 520 * 521 * @param string $version 522 * @return string "latest", "major", "minor", or "specific" 523 * @throws Zend_Loader_Exception if version string contains too many dots 524 */ 525 protected function _getVersionType($version) 526 { 527 if (strtolower($version) == 'latest') { 528 return 'latest'; 529 } 530 531 $parts = explode('.', $version); 532 $count = count($parts); 533 if (1 == $count) { 534 return 'major'; 535 } 536 if (2 == $count) { 537 return 'minor'; 538 } 539 if (3 < $count) { 540 throw new Zend_Loader_Exception('Invalid version string provided'); 541 } 542 return 'specific'; 543 } 544 545 /** 546 * Get available versions for the version type requested 547 * 548 * @param string $path 549 * @param string $version 550 * @return array 551 */ 552 protected function _getAvailableVersions($path, $version) 553 { 554 if (!is_dir($path)) { 555 throw new Zend_Loader_Exception('Invalid ZF path provided'); 556 } 557 558 $path = rtrim($path, '/'); 559 $path = rtrim($path, '\\'); 560 $versionLen = strlen($version); 561 $versions = array(); 562 $dirs = glob("$path/*", GLOB_ONLYDIR); 563 foreach ($dirs as $dir) { 564 $dirName = substr($dir, strlen($path) + 1); 565 if (!preg_match('/^(?:ZendFramework-)?(\d+\.\d+\.\d+((a|b|pl|pr|p|rc)\d+)?)(?:-minimal)?$/i', $dirName, $matches)) { 566 continue; 567 } 568 569 $matchedVersion = $matches[1]; 570 571 if (('latest' == $version) 572 || ((strlen($matchedVersion) >= $versionLen) 573 && (0 === strpos($matchedVersion, $version))) 574 ) { 575 $versions[$matchedVersion] = $dir . '/library'; 576 } 577 } 578 579 uksort($versions, 'version_compare'); 580 return $versions; 581 } 582 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |