|
1
|
|
|
<?php |
|
2
|
|
|
namespace Subreality\Dilmun\Nabu; |
|
3
|
|
|
|
|
4
|
|
|
use Subreality\Dilmun\Nabu\LoggerHandler\File; |
|
5
|
|
|
|
|
6
|
|
|
/** |
|
7
|
|
|
* Nabu was the god of writing and scribes and was the keeper of the Tablets of |
|
8
|
|
|
* Destiny, in which the fate of humankind was recorded. |
|
9
|
|
|
* |
|
10
|
|
|
* @author derek |
|
11
|
|
|
*/ |
|
12
|
|
|
class Autoloader |
|
13
|
|
|
{ |
|
14
|
|
|
protected $logger; |
|
15
|
|
|
|
|
16
|
|
|
protected $packages = array(); |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* Automatically initializes logging using a File handler |
|
20
|
|
|
*/ |
|
21
|
|
|
public function __construct() |
|
22
|
|
|
{ |
|
23
|
|
|
$logger_handler = new File("autoloader.log", DILMUN_LOGS_DIR); |
|
24
|
|
|
$logger_handler->initialize(); |
|
25
|
|
|
|
|
26
|
|
|
$this->logger = new Logger($logger_handler); |
|
27
|
|
|
} |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Registers the includeClass function as an autoloader. |
|
31
|
|
|
* |
|
32
|
|
|
* @see Autoloader::includeClass |
|
33
|
|
|
*/ |
|
34
|
|
|
public function register() |
|
35
|
|
|
{ |
|
36
|
|
|
spl_autoload_register(array($this,"includeClass")); |
|
37
|
|
|
} |
|
38
|
|
|
|
|
39
|
|
|
/** |
|
40
|
|
|
* @param $package |
|
41
|
|
|
* @param $path |
|
42
|
|
|
*/ |
|
43
|
|
|
public function registerPackages($package, $path) |
|
44
|
|
|
{ |
|
45
|
|
|
$this->logger->info("Preparing package for registration."); |
|
46
|
|
|
$this->logger->debug("Inputs: package: {$package}, path: {$path}"); |
|
47
|
|
|
|
|
48
|
|
|
$package = trim($package, "\\"); |
|
49
|
|
|
$package = $package . "\\"; |
|
50
|
|
|
|
|
51
|
|
|
$path = rtrim($path, "/"); |
|
52
|
|
|
$path = $path . "/"; |
|
53
|
|
|
|
|
54
|
|
|
$this->logger->debug("Registering index {$package} with {$path}"); |
|
55
|
|
|
$this->packages[$package][] = $path; |
|
56
|
|
|
|
|
57
|
|
|
$this->logger->info("Registered index {$package} as {$path}"); |
|
58
|
|
|
} |
|
59
|
|
|
|
|
60
|
|
|
/** |
|
61
|
|
|
* Includes the file corresponding with the class name to be autoloaded. |
|
62
|
|
|
* |
|
63
|
|
|
* @param callable $class class name as defined by PHP autoloading |
|
64
|
|
|
* |
|
65
|
|
|
* @return bool|string The path to the class on success; otherwise false |
|
66
|
|
|
* otherwise. |
|
67
|
|
|
*/ |
|
68
|
|
|
protected function includeClass($class) |
|
69
|
|
|
{ |
|
70
|
|
|
$this->logger->info("Setting up class for inclusion."); |
|
71
|
|
|
$this->logger->debug("Input: class: {$class}"); |
|
72
|
|
|
|
|
73
|
|
|
//Find the vendor based on the first backslash |
|
74
|
|
|
$vendor_end = strpos($class, '\\'); |
|
75
|
|
|
$this->logger->debug("The vendor name in {$class} ends at position {$vendor_end}"); |
|
76
|
|
|
|
|
77
|
|
|
//Maybe we'll need this one day... |
|
78
|
|
|
//$vendor_name = substr($class, 0, $vendor_end); |
|
|
|
|
|
|
79
|
|
|
|
|
80
|
|
|
$package_found = false; |
|
81
|
|
|
$package_loaded = false; |
|
82
|
|
|
|
|
83
|
|
|
foreach ($this->packages as $package => $sources) { |
|
84
|
|
|
if (strpos($class, $package) !== false) { |
|
85
|
|
|
$package_found = true; |
|
86
|
|
|
$this->logger->debug("Found package {$package} in {$class}!"); |
|
87
|
|
|
|
|
88
|
|
|
$package_string_length = strlen($package); |
|
89
|
|
|
|
|
90
|
|
|
$class_path = substr($class, $package_string_length); |
|
91
|
|
|
$this->logger->debug("Pulled out class path {$class_path}"); |
|
92
|
|
|
|
|
93
|
|
|
$package_loaded = $this->loadPackage($package, $class_path); |
|
94
|
|
|
|
|
95
|
|
|
if ($package_loaded) { |
|
96
|
|
|
$this->logger->info("Completed loading {$package_loaded}"); |
|
97
|
|
|
} else { |
|
98
|
|
|
$this->logger->alert("File not found for {$class_path} given {$package} package!"); |
|
99
|
|
|
} |
|
100
|
|
|
} |
|
101
|
|
|
} |
|
102
|
|
|
|
|
103
|
|
|
if (!$package_found) { |
|
104
|
|
|
$this->logger->alert("No registered packages found for {$class}!"); |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
return $package_loaded; |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
/** |
|
111
|
|
|
* Loads a package based on registered paths associated with the package. |
|
112
|
|
|
* |
|
113
|
|
|
* @param string $package_name The name of the package in Vendor\Package format |
|
114
|
|
|
* @param string $class_name The full, relative name of the class with the vendor and package names stripped |
|
115
|
|
|
* |
|
116
|
|
|
* @return bool|string The path to the class on success; otherwise false |
|
117
|
|
|
*/ |
|
118
|
|
|
protected function loadPackage($package_name, $class_name) |
|
119
|
|
|
{ |
|
120
|
|
|
$this->logger->info("Working on loading class via file include."); |
|
121
|
|
|
$this->logger->debug("Inputs: package_name: {$package_name}, class_name: {$class_name}"); |
|
122
|
|
|
|
|
123
|
|
|
$path_loaded = false; |
|
124
|
|
|
|
|
125
|
|
|
if (isset($this->packages[$package_name])) { |
|
126
|
|
|
$this->logger->debug("Package index of {$package_name} is set."); |
|
127
|
|
|
|
|
128
|
|
|
foreach ($this->packages[$package_name] as $path) { |
|
129
|
|
|
$converted_class = str_replace('\\', '/', $class_name); |
|
130
|
|
|
$class_path = $path . $converted_class . ".php"; |
|
131
|
|
|
$this->logger->debug("Set up class path as {$class_path}"); |
|
132
|
|
|
|
|
133
|
|
|
if (file_exists($class_path)) { |
|
134
|
|
|
$this->logger->debug("File {$class_path} exists"); |
|
135
|
|
|
|
|
136
|
|
|
$this->logger->debug("Including " . $class_path); |
|
137
|
|
|
/** @noinspection PhpIncludeInspection */ |
|
138
|
|
|
include $class_path; |
|
139
|
|
|
|
|
140
|
|
|
$path_loaded = $class_path; |
|
141
|
|
|
} else { |
|
142
|
|
|
$this->logger->debug("File {$class_path} does not exist"); |
|
143
|
|
|
|
|
144
|
|
|
$path_loaded = false; |
|
145
|
|
|
} |
|
146
|
|
|
} |
|
147
|
|
|
} |
|
148
|
|
|
|
|
149
|
|
|
$this->logger->debug("loadPackage is returning {$path_loaded}"); |
|
150
|
|
|
return $path_loaded; |
|
151
|
|
|
} |
|
152
|
|
|
} |
|
153
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.