1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185:
<?php
namespace WPGMZA;
/**
* The AutoLoader class can be used to scan a directory and register any
* classes found in the PHP files there, recursively.
*
* These classes will be registered for autoloading.
*
* This class may be built on to use a JSON cache in the future.
*/
class AutoLoader
{
protected $filenamesByClass;
/**
* The AutoLoader constructor.
*/
public function __construct()
{
// TODO: Maybe cache these in a JSON object and only refreshin developer mode
$this->filenamesByClass = array();
}
/**
* Updates the JSON cache of classes
* @todo implement
* @return void
*/
protected function updateCache()
{
// TODO: Not yet implemented
/*$dst = plugin_dir_path(__FILE__) . 'classes.json';
$json = json_encode((object)array(
'filenamesByClass' => $this->filenamesByClass
));
file_put_contents($dst, $json);*/
}
/**
* Gets the first class defined in the specified file
* @param string $file The file to scan for a class
* @return string The fully qualified class, or NULL if none found
* NB: With thanks to netcoder - https://stackoverflow.com/questions/7153000/get-class-name-from-file
*/
public function getClassesInFile($file)
{
$fp = fopen($file, 'r');
$class = $namespace = $buffer = '';
$i = 0;
$results = array();
$buffer = file_get_contents($file);
if(!function_exists('token_get_all'))
{
// Regex fallback for users without token_get_all
if(preg_match('/^\s*namespace\s+(.+);/m', $buffer, $m))
$namespace = '\\' . trim($m[1]);
if(preg_match('/^(abstract)?\s*class\s+(\w+)/m', $buffer, $m))
$class = trim($m[2]);
$result = $namespace . '\\' . $class;
}
else
{
$tokens = @token_get_all($buffer);
for (;$i<count($tokens);$i++) {
if ($tokens[$i][0] === T_NAMESPACE) {
for ($j=$i+1;$j<count($tokens); $j++) {
if ($tokens[$j][0] === T_STRING) {
$namespace .= '\\'.$tokens[$j][1];
} else if ($tokens[$j] === '{' || $tokens[$j] === ';') {
break;
}
}
}
if ($tokens[$i][0] === T_CLASS) {
for ($j=$i+1;$j<count($tokens);$j++) {
if ($tokens[$j] === '{') {
$class = $tokens[$i+2][1];
}
}
}
if(!empty($class))
break;
}
$result = $namespace . '\\' . $class;
}
if(empty($class))
return null;
return $result;
}
/**
* Gets all the classes in PHP files in the specified path, recursively
* @param string $path The path to scan
* @return array An array of all the fully qualified
*/
public function getClassesInPathByFilename($path)
{
// var_dump("Getting classes in $path");
$results = array();
$dir = new \RecursiveDirectoryIterator($path);
$iter = new \RecursiveIteratorIterator($dir);
$regex = new \RegexIterator($iter, '/^.+(\.php)$/i', \RecursiveRegexIterator::GET_MATCH);
foreach($regex as $m) {
$file = $m[0];
$classes = $this->getClassesInFile($file);
$results[$file] = $classes;
}
return $results;
}
/**
* Recursively scans all PHP files in the given patch and registers any classes found.
* @param string $path The path to scan
* @return void
*/
public function registerClassesInPath($path)
{
global $wpgmza;
//$cacheFile = $relative . 'includes/auto-loader-cache.json';
//$useCache = empty($wpgmza->settings->developer_mode) && file_exists($cacheFile);
$classesByFilename = $this->getClassesInPathByFilename($path);
foreach($classesByFilename as $file => $class)
{
if(!empty($class))
$this->filenamesByClass[$class] = $file;
}
$this->updateCache();
}
/**
* This function is registered with PHPs native spl_autoloader_register to require the file associated with the class. This function is to be treated as private and should only be called by PHP itself.
* @internal
* @param string $class The class passed in by PHP
* @return void
*/
public function callback($class)
{
$pattern = "/^(\\\\?)WPGMZA/";
if(!preg_match($pattern, $class, $m))
return;
if(empty($m[1]))
$class = '\\' . $class;
if(!isset($this->filenamesByClass[$class]))
return;
$file = $this->filenamesByClass[$class];
require_once( $file );
}
}
global $wpgmza_auto_loader;
$wpgmza_auto_loader = new AutoLoader();
$wpgmza_auto_loader->registerClassesInPath(__DIR__);
spl_autoload_register(array($wpgmza_auto_loader, 'callback'));