mirror of
https://github.com/hotspotbilling/phpnuxbill.git
synced 2025-02-24 23:45:38 +08:00
243 lines
7.4 KiB
PHP
243 lines
7.4 KiB
PHP
|
<?php
|
||
|
namespace PEAR2;
|
||
|
if (!class_exists('\PEAR2\Autoload', false)) {
|
||
|
class Autoload
|
||
|
{
|
||
|
/**
|
||
|
* Whether the autoload class has been spl_autoload_register-ed
|
||
|
*
|
||
|
* @var bool
|
||
|
*/
|
||
|
protected static $registered = false;
|
||
|
|
||
|
/**
|
||
|
* Array of PEAR2 autoload paths registered
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected static $paths = array();
|
||
|
|
||
|
/**
|
||
|
* Array of classname-to-file mapping
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected static $map = array();
|
||
|
|
||
|
/**
|
||
|
* Array of class maps loaded
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected static $maps = array();
|
||
|
|
||
|
/**
|
||
|
* Last classmap specified
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected static $mapfile = null;
|
||
|
|
||
|
/**
|
||
|
* Array of classes loaded automatically not in the map
|
||
|
*
|
||
|
* @var array
|
||
|
*/
|
||
|
protected static $unmapped = array();
|
||
|
|
||
|
/**
|
||
|
* Initialize the PEAR2 autoloader
|
||
|
*
|
||
|
* @param string $path Directory path to register
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
static function initialize($path, $mapfile = null)
|
||
|
{
|
||
|
self::register();
|
||
|
self::addPath($path);
|
||
|
self::addMap($mapfile);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Register the PEAR2 autoload class with spl_autoload_register
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
protected static function register()
|
||
|
{
|
||
|
if (!self::$registered) {
|
||
|
// set up __autoload
|
||
|
$autoload = spl_autoload_functions();
|
||
|
spl_autoload_register('PEAR2\Autoload::load');
|
||
|
if (function_exists('__autoload') && ($autoload === false)) {
|
||
|
// __autoload() was being used, but now would be ignored, add
|
||
|
// it to the autoload stack
|
||
|
spl_autoload_register('__autoload');
|
||
|
}
|
||
|
}
|
||
|
self::$registered = true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a path
|
||
|
*
|
||
|
* @param string $path The directory to add to the set of PEAR2 paths
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
protected static function addPath($path)
|
||
|
{
|
||
|
if (!in_array($path, self::$paths)) {
|
||
|
self::$paths[] = $path;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Add a classname-to-file map
|
||
|
*
|
||
|
* @param string $mapfile The filename of the classmap
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
protected static function addMap($mapfile)
|
||
|
{
|
||
|
if (! in_array($mapfile, self::$maps)) {
|
||
|
|
||
|
// keep track of specific map file loaded in this
|
||
|
// instance so we can update it if necessary
|
||
|
self::$mapfile = $mapfile;
|
||
|
|
||
|
if (file_exists($mapfile)) {
|
||
|
$map = include $mapfile;
|
||
|
if (is_array($map)) {
|
||
|
// mapfile contains a valid map, so we'll keep it
|
||
|
self::$maps[] = $mapfile;
|
||
|
self::$map = array_merge(self::$map, $map);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if the class is already defined in a classmap
|
||
|
*
|
||
|
* @param string $class The class to look for
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
protected static function isMapped($class)
|
||
|
{
|
||
|
if (isset(self::$map[$class])) {
|
||
|
return true;
|
||
|
}
|
||
|
if (isset(self::$mapfile) && ! isset(self::$map[$class])) {
|
||
|
self::$unmapped[] = $class;
|
||
|
return false;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Load a PEAR2 class
|
||
|
*
|
||
|
* @param string $class The class to load
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
static function load($class)
|
||
|
{
|
||
|
// need to check if there's a current map file specified ALSO.
|
||
|
// this could be the first time writing it.
|
||
|
$mapped = self::isMapped($class);
|
||
|
if ($mapped) {
|
||
|
require self::$map[$class];
|
||
|
if (!self::loadSuccessful($class)) {
|
||
|
// record this failure & keep going, we may still find it
|
||
|
self::$unmapped[] = $class;
|
||
|
} else {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$file = str_replace(array('_', '\\'), DIRECTORY_SEPARATOR, $class) . '.php';
|
||
|
foreach (self::$paths as $path) {
|
||
|
if (file_exists($path . DIRECTORY_SEPARATOR . $file)) {
|
||
|
require $path . DIRECTORY_SEPARATOR . $file;
|
||
|
if (!self::loadSuccessful($class)) {
|
||
|
throw new \Exception('Class ' . $class . ' was not present in ' .
|
||
|
$path . DIRECTORY_SEPARATOR . $file .
|
||
|
'") [PEAR2_Autoload-0.2.4]');
|
||
|
}
|
||
|
|
||
|
if (in_array($class, self::$unmapped)) {
|
||
|
self::updateMap($class, $path . DIRECTORY_SEPARATOR . $file);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$e = new \Exception('Class ' . $class . ' could not be loaded from ' .
|
||
|
$file . ', file does not exist (registered paths="' .
|
||
|
implode(PATH_SEPARATOR, self::$paths) .
|
||
|
'") [PEAR2_Autoload-0.2.4]');
|
||
|
$trace = $e->getTrace();
|
||
|
if (isset($trace[2]) && isset($trace[2]['function']) &&
|
||
|
in_array($trace[2]['function'], array('class_exists', 'interface_exists'))) {
|
||
|
return false;
|
||
|
}
|
||
|
if (isset($trace[1]) && isset($trace[1]['function']) &&
|
||
|
in_array($trace[1]['function'], array('class_exists', 'interface_exists'))) {
|
||
|
return false;
|
||
|
}
|
||
|
throw $e;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Check if the requested class was loaded from the specified path
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
protected static function loadSuccessful($class)
|
||
|
{
|
||
|
if (!class_exists($class, false) && !interface_exists($class, false)) {
|
||
|
return false;
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* If possible, update the classmap file with newly-discovered
|
||
|
* mapping.
|
||
|
*
|
||
|
* @param string $class Class name discovered
|
||
|
*
|
||
|
* @param string $origin File where class was found
|
||
|
*
|
||
|
*/
|
||
|
protected static function updateMap($class, $origin)
|
||
|
{
|
||
|
if (is_writable(self::$mapfile) || is_writable(dirname(self::$mapfile))) {
|
||
|
self::$map[$class] = $origin;
|
||
|
file_put_contents(self::$mapfile,
|
||
|
'<'."?php\n"
|
||
|
. "// PEAR2\Autoload auto-generated classmap\n"
|
||
|
. "return " . var_export(self::$map, true) . ';',
|
||
|
LOCK_EX
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* return the array of paths PEAR2 autoload has registered
|
||
|
*
|
||
|
* @return array
|
||
|
*/
|
||
|
static function getPaths()
|
||
|
{
|
||
|
return self::$paths;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Autoload::initialize(dirname(__DIR__));
|