Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Autoloader.php
Go to the documentation of this file.
1 <?php
24 #require_once 'Zend/Loader.php';
25 
36 {
40  protected static $_instance;
41 
45  protected $_autoloaders = array();
46 
50  protected $_defaultAutoloader = array('Zend_Loader', 'loadClass');
51 
55  protected $_fallbackAutoloader = false;
56 
61 
65  protected $_namespaces = array(
66  'Zend_' => true,
67  'ZendX_' => true,
68  );
69 
73  protected $_namespaceAutoloaders = array();
74 
78  protected $_suppressNotFoundWarnings = false;
79 
83  protected $_zfPath;
84 
90  public static function getInstance()
91  {
92  if (null === self::$_instance) {
93  self::$_instance = new self();
94  }
95  return self::$_instance;
96  }
97 
103  public static function resetInstance()
104  {
105  self::$_instance = null;
106  }
107 
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 
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 
158  public function getDefaultAutoloader()
159  {
161  }
162 
169  public function setAutoloaders(array $autoloaders)
170  {
171  $this->_autoloaders = $autoloaders;
172  return $this;
173  }
174 
180  public function getAutoloaders()
181  {
182  return $this->_autoloaders;
183  }
184 
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 
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 
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 
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 
286  public function suppressNotFoundWarnings($flag = null)
287  {
288  if (null === $flag) {
290  }
291  $this->_suppressNotFoundWarnings = (bool) $flag;
292  return $this;
293  }
294 
301  public function setFallbackAutoloader($flag)
302  {
303  $this->_fallbackAutoloader = (bool) $flag;
304  return $this;
305  }
306 
312  public function isFallbackAutoloader()
313  {
315  }
316 
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  if ((false === $namespace) || (strlen($ns) > strlen($namespace))) {
339  $namespace = $ns;
340  $autoloaders = $this->getNamespaceAutoloaders($ns);
341  }
342  }
343  }
344 
345  // Add internal namespaced autoloader
346  foreach ($this->getRegisteredNamespaces() as $ns) {
347  if (0 === strpos($class, $ns)) {
348  $namespace = $ns;
349  $autoloaders[] = $this->_internalAutoloader;
350  break;
351  }
352  }
353 
354  // Add non-namespaced autoloaders
355  $autoloadersNonNamespace = $this->getNamespaceAutoloaders('');
356  if (count($autoloadersNonNamespace)) {
357  foreach ($autoloadersNonNamespace as $ns) {
358  $autoloaders[] = $ns;
359  }
360  unset($autoloadersNonNamespace);
361  }
362 
363  // Add fallback autoloader
364  if (!$namespace && $this->isFallbackAutoloader()) {
365  $autoloaders[] = $this->_internalAutoloader;
366  }
367 
368  return $autoloaders;
369  }
370 
378  public function unshiftAutoloader($callback, $namespace = '')
379  {
380  $autoloaders = $this->getAutoloaders();
381  array_unshift($autoloaders, $callback);
382  $this->setAutoloaders($autoloaders);
383 
384  $namespace = (array) $namespace;
385  foreach ($namespace as $ns) {
386  $autoloaders = $this->getNamespaceAutoloaders($ns);
387  array_unshift($autoloaders, $callback);
388  $this->_setNamespaceAutoloaders($autoloaders, $ns);
389  }
390 
391  return $this;
392  }
393 
401  public function pushAutoloader($callback, $namespace = '')
402  {
403  $autoloaders = $this->getAutoloaders();
404  array_push($autoloaders, $callback);
405  $this->setAutoloaders($autoloaders);
406 
407  $namespace = (array) $namespace;
408  foreach ($namespace as $ns) {
409  $autoloaders = $this->getNamespaceAutoloaders($ns);
410  array_push($autoloaders, $callback);
411  $this->_setNamespaceAutoloaders($autoloaders, $ns);
412  }
413 
414  return $this;
415  }
416 
424  public function removeAutoloader($callback, $namespace = null)
425  {
426  if (null === $namespace) {
427  $autoloaders = $this->getAutoloaders();
428  if (false !== ($index = array_search($callback, $autoloaders, true))) {
429  unset($autoloaders[$index]);
430  $this->setAutoloaders($autoloaders);
431  }
432 
433  foreach ($this->_namespaceAutoloaders as $ns => $autoloaders) {
434  if (false !== ($index = array_search($callback, $autoloaders, true))) {
435  unset($autoloaders[$index]);
436  $this->_setNamespaceAutoloaders($autoloaders, $ns);
437  }
438  }
439  } else {
440  $namespace = (array) $namespace;
441  foreach ($namespace as $ns) {
442  $autoloaders = $this->getNamespaceAutoloaders($ns);
443  if (false !== ($index = array_search($callback, $autoloaders, true))) {
444  unset($autoloaders[$index]);
445  $this->_setNamespaceAutoloaders($autoloaders, $ns);
446  }
447  }
448  }
449 
450  return $this;
451  }
452 
460  protected function __construct()
461  {
462  spl_autoload_register(array(__CLASS__, 'autoload'));
463  $this->_internalAutoloader = array($this, '_autoload');
464  }
465 
472  protected function _autoload($class)
473  {
474  $callback = $this->getDefaultAutoloader();
475  try {
476  if ($this->suppressNotFoundWarnings()) {
477  @call_user_func($callback, $class);
478  } else {
479  call_user_func($callback, $class);
480  }
481  return $class;
482  } catch (Zend_Exception $e) {
483  return false;
484  }
485  }
486 
494  protected function _setNamespaceAutoloaders(array $autoloaders, $namespace = '')
495  {
496  $namespace = (string) $namespace;
497  $this->_namespaceAutoloaders[$namespace] = $autoloaders;
498  return $this;
499  }
500 
508  protected function _getVersionPath($path, $version)
509  {
510  $type = $this->_getVersionType($version);
511 
512  if ($type == 'latest') {
513  $version = 'latest';
514  }
515 
516  $availableVersions = $this->_getAvailableVersions($path, $version);
517  if (empty($availableVersions)) {
518  throw new Zend_Loader_Exception('No valid ZF installations discovered');
519  }
520 
521  $matchedVersion = array_pop($availableVersions);
522  return $matchedVersion;
523  }
524 
532  protected function _getVersionType($version)
533  {
534  if (strtolower($version) == 'latest') {
535  return 'latest';
536  }
537 
538  $parts = explode('.', $version);
539  $count = count($parts);
540  if (1 == $count) {
541  return 'major';
542  }
543  if (2 == $count) {
544  return 'minor';
545  }
546  if (3 < $count) {
547  throw new Zend_Loader_Exception('Invalid version string provided');
548  }
549  return 'specific';
550  }
551 
559  protected function _getAvailableVersions($path, $version)
560  {
561  if (!is_dir($path)) {
562  throw new Zend_Loader_Exception('Invalid ZF path provided');
563  }
564 
565  $path = rtrim($path, '/');
566  $path = rtrim($path, '\\');
567  $versionLen = strlen($version);
568  $versions = array();
569  $dirs = glob("$path/*", GLOB_ONLYDIR);
570  foreach ((array) $dirs as $dir) {
571  $dirName = substr($dir, strlen($path) + 1);
572  if (!preg_match('/^(?:ZendFramework-)?(\d+\.\d+\.\d+((a|b|pl|pr|p|rc)\d+)?)(?:-minimal)?$/i', $dirName, $matches)) {
573  continue;
574  }
575 
576  $matchedVersion = $matches[1];
577 
578  if (('latest' == $version)
579  || ((strlen($matchedVersion) >= $versionLen)
580  && (0 === strpos($matchedVersion, $version)))
581  ) {
582  $versions[$matchedVersion] = $dir . '/library';
583  }
584  }
585 
586  uksort($versions, 'version_compare');
587  return $versions;
588  }
589 }
unregisterNamespace($namespace)
Definition: Autoloader.php:228
getNamespaceAutoloaders($namespace)
Definition: Autoloader.php:191
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
unshiftAutoloader($callback, $namespace='')
Definition: Autoloader.php:378
setAutoloaders(array $autoloaders)
Definition: Autoloader.php:169
pushAutoloader($callback, $namespace='')
Definition: Autoloader.php:401
registerNamespace($namespace)
Definition: Autoloader.php:206
$count
Definition: recent.phtml:13
suppressNotFoundWarnings($flag=null)
Definition: Autoloader.php:286
$type
Definition: item.phtml:13
$_option $_optionId $class
Definition: date.phtml:13
_getAvailableVersions($path, $version)
Definition: Autoloader.php:559
setDefaultAutoloader($callback)
Definition: Autoloader.php:143
static autoload($class)
Definition: Autoloader.php:114
removeAutoloader($callback, $namespace=null)
Definition: Autoloader.php:424
_getVersionPath($path, $version)
Definition: Autoloader.php:508
_setNamespaceAutoloaders(array $autoloaders, $namespace='')
Definition: Autoloader.php:494
$index
Definition: list.phtml:44
setZfPath($spec, $version='latest')
Definition: Autoloader.php:254