<?php
namespace Jackbooted\Util;
use \Jackbooted\Config\Cfg;
/**
* @copyright Confidential and copyright (c) 2016 Jackbooted Software. All rights reserved.
*
* Written by Brett Dutton of Jackbooted Software
* brett at brettdutton dot com
*
* This software is written and distributed under the GNU General Public
* License which means that its source code is freely-distributed and
* available to the general public.
*/
/**
* The day of require_once is now over for classes. This class will automatically set itself up to load any class from
* the classes folder and any of it's sub folders. The folowing code initializes and sets up the automatic class loader
* <pre>
* require_once ( Cfg::get ( 'classes_dir' ) . "/util/Log4PHP.inc" );
* if ( Cfg::get ( 'development') ) {
* Log4PHP::setLogLevel ( Log4PHP::ALL );
* }
*
* // need to require once the autoloader
* require_once ( Cfg::get ( 'classes_dir' ) . "/util/AutoLoader.inc" );
* AutoLoader::init ( Cfg::get ( 'classes_dir' ) );
* </pre>
*
* The ClassLocator scans all the files in all the sub folders looking for the class that you are trying to load.
*
* <b>Third Party Libraries</b><br>
* You can load third party libraries with the autoloader by creating a class with a dummy class name in comments and
* require_once the file containing the third party library. Example:
*
* <pre>
* <?php
* /*
* The tag below will fool the ClassLocator to associating this class with this file
* class Smarty
* * /
* // This is a dummy include so tha the autoloader finds this class and loads it up
* require_once( dirname ( dirname( __FILE__) ) . "/3rdparty/smarty/Smarty.class.php" );
* ?>
* </pre>
*
* @see ClassLocator
*/
class AutoLoader extends \Jackbooted\Util\JB {
/**
* Suffix for classes that are auto loaded
*/
const CLASS_SUFFIX = '.php';
const THIRD_PARTY_REGEX = '/^.*\/3rdparty\/.*$/';
/**
* initialization method
*/
const STATIC_INIT = 'init';
private static $log;
private static $ignoreList = [];
/**
* load set up the static variables of the class
* (still waiting on static initialisation from PHP)
* @param string $classesDir
*/
public static function init () {
spl_autoload_register ( __CLASS__ . '::autoload' );
self::$log = Log4PHP::logFactory ( __CLASS__ );
}
/**
* Adds a class to the ignore list.
* @param String $className
* @param String $fullName This is the full Java class Name. If it exists then assumes quercus and
* imports the class
* @return void
*/
public static function ignore ( $className, $fullName=null ) {
self::$ignoreList[$className] = true;
if ( $fullName != null && Cfg::get ( 'quercus', false ) ) {
eval ( 'import ' . $fullName . ';' );
}
}
/**
* This method is called by the autoloader - Registered somewhere (config)
* with spl_autoload_register ( 'AutoLoader::autoload' );
* This class must be manually loaded with require_one and then call init
* @param string $className Class name that needs to be loaded
*/
public static function autoload ( $className ) {
if ( isset ( self::$ignoreList[$className] ) ) return;
$tries = self::locateClassFromFileAndLoad ( $className );
if ( $tries === true ) return;
// If made it to here then we have not loaded anything
self::$log->error ( 'The system has attempted to autoload non existing class: ' . $className . ' tried: (' . implode ( ', ', $tries ) . ')' );
}
/**
* Loads a class based on the class name for legacy classes
* @param string $className This is the class that you are attemption to load
* @return mixed Return true on successful load, otherwise it returns a list of all the file locations
* that it tried to load from
*/
private static function locateClassFromFileAndLoad ( $className ) {
$fileToLoad = ClassLocator::getLocation( $className );
if ( $fileToLoad === false ) return [ 'none found' ];
if ( self::loadClassFromFile( $className, $fileToLoad ) ) return true;
return [ $fileToLoad ];
}
/**
* Loads a class from the passed file. Attempts to initialize the class
* @param string $className This is the class that youb are attemption to load
* @param string $fileToLoad The file that you are loading the class from
* @return boolean true on sucess
*/
public static function loadClassFromFile ( $className, $fileToLoad ) {
// If the file does not exist then get out
if ( ! file_exists ( $fileToLoad ) ) return false;
// Everything good!
require_once $fileToLoad;
// RUn class level initialization only on classes that follow JackBoot Web standard
if ( preg_match ( self::THIRD_PARTY_REGEX, $fileToLoad ) ) {
self::$log->trace ( "Skipping class initialization for {$className} from " . $fileToLoad );
}
else {
self::runClassInitialization ( $className );
}
self::$log->trace ( "Loaded {$className} from " . $fileToLoad );
return true;
}
/**
* Check to see if there is class level initialisation and then runs it
* Need this because PHP does not have static initialisation yet
* @param string $className to initialise
*/
private static function runClassInitialization ( $className ) {
if ( Cfg::get ( 'quercus', false ) ) {
@eval ( $className . '::' . self::STATIC_INIT . '();' );
}
else if ( method_exists ( $className, self::STATIC_INIT ) ) {
$classLevelInit = [ $className, self::STATIC_INIT ];
call_user_func ( $classLevelInit );
}
}
}
|