2011-03-18 07:28:11 +01:00
|
|
|
<?php
|
2016-08-19 00:51:35 +02:00
|
|
|
|
|
|
|
namespace SilverStripe\Core\Manifest;
|
|
|
|
|
|
|
|
use SilverStripe\Core\ClassInfo;
|
|
|
|
use SilverStripe\Dev\Deprecation;
|
|
|
|
|
2011-03-18 07:28:11 +01:00
|
|
|
/**
|
|
|
|
* A class that handles loading classes and interfaces from a class manifest
|
|
|
|
* instance.
|
|
|
|
*/
|
2016-09-09 08:43:05 +02:00
|
|
|
class ClassLoader {
|
2011-03-18 07:28:11 +01:00
|
|
|
|
|
|
|
/**
|
2016-09-09 08:43:05 +02:00
|
|
|
* @var ClassLoader
|
2011-03-18 07:28:11 +01:00
|
|
|
*/
|
|
|
|
private static $instance;
|
|
|
|
|
|
|
|
/**
|
2016-09-09 08:43:05 +02:00
|
|
|
* @var array Map of 'instance' (ClassManifest) and other options.
|
2011-03-18 07:28:11 +01:00
|
|
|
*/
|
|
|
|
protected $manifests = array();
|
|
|
|
|
|
|
|
/**
|
2016-09-09 08:43:05 +02:00
|
|
|
* @return ClassLoader
|
2011-03-18 07:28:11 +01:00
|
|
|
*/
|
|
|
|
public static function instance() {
|
|
|
|
return self::$instance ? self::$instance : self::$instance = new self();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the currently active class manifest instance that is used for
|
|
|
|
* loading classes.
|
|
|
|
*
|
2016-09-09 08:43:05 +02:00
|
|
|
* @return ClassManifest
|
2011-03-18 07:28:11 +01:00
|
|
|
*/
|
|
|
|
public function getManifest() {
|
2011-11-27 10:49:42 +01:00
|
|
|
return $this->manifests[count($this->manifests) - 1]['instance'];
|
2011-03-18 07:28:11 +01:00
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2011-05-01 07:12:26 +02:00
|
|
|
/**
|
|
|
|
* Returns true if this class loader has a manifest.
|
|
|
|
*/
|
|
|
|
public function hasManifest() {
|
|
|
|
return (bool)$this->manifests;
|
|
|
|
}
|
2011-03-18 07:28:11 +01:00
|
|
|
|
|
|
|
/**
|
2013-03-21 00:16:21 +01:00
|
|
|
* Pushes a class manifest instance onto the top of the stack.
|
2011-03-18 07:28:11 +01:00
|
|
|
*
|
2016-09-09 08:43:05 +02:00
|
|
|
* @param ClassManifest $manifest
|
2016-08-19 00:51:35 +02:00
|
|
|
* @param bool $exclusive Marks the manifest as exclusive. If set to FALSE, will
|
2011-11-27 10:49:42 +01:00
|
|
|
* look for classes in earlier manifests as well.
|
2011-03-18 07:28:11 +01:00
|
|
|
*/
|
2016-09-09 08:43:05 +02:00
|
|
|
public function pushManifest(ClassManifest $manifest, $exclusive = true) {
|
2011-11-27 10:49:42 +01:00
|
|
|
$this->manifests[] = array('exclusive' => $exclusive, 'instance' => $manifest);
|
2011-03-18 07:28:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-09-09 08:43:05 +02:00
|
|
|
* @return ClassManifest
|
2011-03-18 07:28:11 +01:00
|
|
|
*/
|
|
|
|
public function popManifest() {
|
2011-11-27 10:49:42 +01:00
|
|
|
$manifest = array_pop($this->manifests);
|
|
|
|
return $manifest['instance'];
|
2011-03-18 07:28:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function registerAutoloader() {
|
|
|
|
spl_autoload_register(array($this, 'loadClass'));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Loads a class or interface if it is present in the currently active
|
|
|
|
* manifest.
|
|
|
|
*
|
|
|
|
* @param string $class
|
2011-11-27 10:49:42 +01:00
|
|
|
* @return String
|
2011-03-18 07:28:11 +01:00
|
|
|
*/
|
|
|
|
public function loadClass($class) {
|
2011-11-27 10:49:42 +01:00
|
|
|
if ($path = $this->getItemPath($class)) {
|
2011-03-18 07:28:11 +01:00
|
|
|
require_once $path;
|
|
|
|
}
|
2011-11-27 10:49:42 +01:00
|
|
|
return $path;
|
|
|
|
}
|
2014-08-15 08:53:05 +02:00
|
|
|
|
2011-11-27 10:49:42 +01:00
|
|
|
/**
|
|
|
|
* Returns the path for a class or interface in the currently active manifest,
|
|
|
|
* or any previous ones if later manifests aren't set to "exclusive".
|
2014-08-15 08:53:05 +02:00
|
|
|
*
|
2016-08-19 00:51:35 +02:00
|
|
|
* @param string $class
|
|
|
|
* @return string|false
|
2011-11-27 10:49:42 +01:00
|
|
|
*/
|
|
|
|
public function getItemPath($class) {
|
|
|
|
foreach(array_reverse($this->manifests) as $manifest) {
|
2016-09-09 08:43:05 +02:00
|
|
|
/** @var ClassManifest $manifestInst */
|
2011-11-27 10:49:42 +01:00
|
|
|
$manifestInst = $manifest['instance'];
|
2016-08-19 00:51:35 +02:00
|
|
|
if ($path = $manifestInst->getItemPath($class)) {
|
|
|
|
return $path;
|
|
|
|
}
|
|
|
|
if($manifest['exclusive']) {
|
|
|
|
break;
|
|
|
|
}
|
2011-11-27 10:49:42 +01:00
|
|
|
}
|
|
|
|
return false;
|
2011-03-18 07:28:11 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-02-14 23:02:50 +01:00
|
|
|
* Returns true if a class or interface name exists in the manifest.
|
2011-03-18 07:28:11 +01:00
|
|
|
*
|
|
|
|
* @param string $class
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function classExists($class) {
|
2016-01-04 09:15:17 +01:00
|
|
|
Deprecation::notice('4.0', 'Use ClassInfo::exists.');
|
|
|
|
return ClassInfo::exists($class);
|
2011-03-18 07:28:11 +01:00
|
|
|
}
|
|
|
|
|
2012-03-27 06:04:11 +02:00
|
|
|
}
|