<?php

if ( ! isset( $spl_autoloaders ) ) {
	$spl_autoloaders = array();
}

/**
 * Autoloader compatibility callback.
 *
 * @param string $classname Class to attempt autoloading.
 */
function __autoload( $classname ) {
	global $spl_autoloaders;
	foreach ( $spl_autoloaders as $autoloader ) {
		call_user_func( $autoloader, $classname );

		// If it has been autoloaded, stop processing.
		if ( class_exists( $classname, false ) ) {
			return;
		}
	}
}

/**
 * Register a function to be autoloaded.
 *
 * @param callable $autoload_function The function to register.
 * @param boolean $throw Should the function throw an exception if the function isn't callable?
 * @param boolean $prepend Should we prepend the function to the stack?
 */
function spl_autoload_register( $autoload_function, $throw = true, $prepend = false ) {
	if ( $throw && ! is_callable( $autoload_function ) ) {
		// String not translated to match PHP core.
		throw new Exception( 'Function not callable' );
	}

	global $spl_autoloaders;

	// Don't allow multiple registration.
	if ( in_array( $autoload_function, $spl_autoloaders ) ) {
		return;
	}

	if ( $prepend ) {
		array_unshift( $spl_autoloaders, $autoload_function );
	} else {
		$spl_autoloaders[] = $autoload_function;
	}
}

/**
 * Unregister an autoloader function.
 *
 * @param callable $function The function to unregister.
 * @return boolean True if the function was unregistered, false if it could not be.
 */
function spl_autoload_unregister( $function ) {
	global $spl_autoloaders;
	foreach ( $spl_autoloaders as &$autoloader ) {
		if ( $autoloader === $function ) {
			unset( $autoloader );
			return true;
		}
	}

	return false;
}

/**
 * Get the registered autoloader functions.
 *
 * @return array List of autoloader functions.
 */
function spl_autoload_functions() {
	return $GLOBALS['spl_autoloaders'];
}
