[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/Loader/ -> Autoloader.php (source)

   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  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1