<?php
/**
* Static class for autoloading class files
*/
class Quickload
{
/**
* Stores the array parsed from the ini file
* @access private
* @var array
*/
private static $ini = 0;
/**
* Stores the path to the ini for caching relative to this file
* default is '.quickload.ini' in the same directory as this file
* @access private
* @var array
*/
private static $iniPath = '.quickload.ini';
/**
* Stores the paths in which classes can be found
* @access public
* @var array
*/
public static $includePath = array();
/**
* Stores the paths which should not be searched for classes
* @access public
* @var array
*/
public static $excludePath = array();
/**
* Stores the extensions which mark classes
* default is .class.php and .class.php
* @access public
* @var array
*/
public static $extensions = array('.class.php', '.class.inc');
/**
* Lists recursively all .php Files in the given directories
* @param string|array $includeP single or list of directories to look for .php files
* @return array List of found .php files
*/
static private function listPhpFiles($includeP)
{
$files = array();
// if the parameter contains more than one directory (parameter is an array)
if(is_array($includeP))
{
foreach($includeP as $start_path)
$files = array_merge($files, Quickload::listPhpFiles($start_path));
return $files;
}
if (is_dir($includeP))
{
$fh = opendir($includeP);
// loop through the files
while (($file = readdir($fh)) !== false)
{
// skip . and ..
if (strcmp($file, '.')==0 || strcmp($file, '..')==0) continue;
$filepath = $includeP . '/' . $file;
if (is_dir($filepath))
{
// scan directory if it is not in the excludePath list
if(!in_array($filepath, Quickload::$excludePath))
{
$files = array_merge($files, Quickload::listPhpFiles($filepath));
}
}
else
{
// get the file extension
$ext = substr($filepath, strpos($filepath, '.'));
// check if the extension is in the list of allowed extensions
if(in_array($ext, Quickload::$extensions))
{
// store filepath in list of found class files
array_push($files, $filepath);
}
}
}
closedir($fh);
}
else
{
// false if the function was called with an invalid non-directory argument
$files = false;
}
return $files;
}
/**
* Saves given files into a ini structured file
* @param array $files List of file paths
* @return mixed The function returns the number of bytes that were written to the file, or FALSE on failure.
*/
static private function saveIni($files)
{
sort($files);
$ini = array();
foreach($files as $f)
{
// determine class name from filename
$classname = substr(basename($f), 0, strpos(basename($f), '.'));
$ini[] = $classname .' = "'.$f.'"';
}
return file_put_contents(realpath(dirname(__FILE__).'/'.Quickload::$iniPath), implode("\n", $ini)."\n");
}
/**
* Returns the path to the specified class by reading the stored ini or re-parsing the directories
* @param string $classname name of the class to find
* @return string path to the specified file
*/
static public function getPath($classname)
{
// if ini has not been parsed yes
if(!is_array(Quickload::$ini) && is_file(Quickload::$ini))
{
Quickload::$ini = parse_ini_file(realpath(dirname(__FILE__).'/'.Quickload::$iniPath));
}
// if classname does not exists in ini
if(!isset(Quickload::$ini[$classname]))
{
clearstatcache();
// rebuild ini
$files = Quickload::listPhpFiles(Quickload::$includePath);
$savedBytes = Quickload::saveIni($files);
// saveIni returns false if there was an error writing the ini
if($savedBytes === false)
{
$ini = realpath(dirname(__FILE__).'/'.Quickload::$iniPath);
die("could not write to ".$ini.'. File: '.__FILE__.' Line: '.__LINE__);
}
// parse ini again
Quickload::$ini = parse_ini_file(realpath(dirname(__FILE__).'/'.Quickload::$iniPath));
}
// if classname still does not exist in ini, die fatally
if(!isset(Quickload::$ini[$classname]))
die('class '.$classname.' not found. File: '.__FILE__.' Line: '.__LINE__);
else
return Quickload::$ini[$classname];
}
}
?>