/
class.autoload.php
329 lines (293 loc) · 10.7 KB
/
class.autoload.php
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
<?php
/**
* @file
* @version 1.1.0
* @brief This file contains the new registry based autoloader.
*
* The autoloader has no dependencies for other files only constant WB_PATH(path to webroot) is needed.
* So it maybe usefull in other enviroments too.
*/
//no direct file access
if (count(get_included_files()) == 1) {
$z = "HTTP/1.0 404 Not Found";
header($z);
die($z);
}
/**
* @brief This is the main autoloader class in Websitebaker(CE)
*
* Actually this is the only one too besides from the Twig autoloader which is moved to a module soon.
*
* The autoloader is registry based , so all directories/files/patterns need to be registered somwhere in the CMS code.
* The registry allows Modules snipits Droplets and any other piece of code anywhere in WBCE to register its classes
* for further execution.
*
* Here some examples for register actions, all path values are expected to be given from WB_PATH as the starting point.
*
* @code
* // register a new directory to be searched
* WbAuto::AddDir("/classes/");
* WbAuto::AddDir("/classes/fields");
*
* // register a single file, this allows for classname != filename
* WbAuto::AddFile("MultiCrud","/classes/multicrud.php");
* WbAuto::AddFile("R","/includes/rb.php");
*
* // register additional search patterns for file search in directory %s is the classname.
* WbAuto::AddType("class.%s.inc.php");
*
* @endcode
*
* Everything is Global and can easyly be called from everywhere even the internal variables (for debugging if you like)
* @code
* echo "<pre>"; print_r(WbAuto::$Dirs); echo "</pre>";
* echo "<pre>"; print_r(WbAuto::$Files); echo "</pre>";
* echo "<pre>"; print_r(WbAuto::$Types); echo "</pre>";
* @endcode
*
* @attention There is one very usefull thing to keep in mind @code class_exists('MyClass'); @endcode triggers the autoloader, so it tests if the class is available and loads it.
*
* @note A last note to mention the $DirektPath Option should allow to access directories outside of webroot .
*/
// !!! Need to remember, that i need to extend this so it loads directories above webroot!!!
// !!! Need to add a list of loaded classes for debugging.
class WbAuto
{
/**
* @brief Stores the dirs to search in loader
* @var array $Dirs
*/
public static $Dirs = array();
/**
* @brief Stores class filename combinations for loader.
* @var array $Files
*/
public static $Files = array();
/**
* @brief Stores search templates to search for in the search dirs.
* @var array $Types
*/
public static $Types = array('class.%s.php',
'%s.php',
'%s.class.php',
'%s.class.inc',
'%s.inc',
'%s.inc.php',
'class.%s.inc');
/**
* @brief The actual loader that is registered whith spl_autoload_register('WbAuto::Loader');
*
* This is the workhorse that does the actual loading.
*/
public static function Loader($ClassName)
{
//already loaded, never mind
if (class_exists($ClassName, false)) {
return false;
}
// Filebased loading first
//if there is an fileentry for this class
if (array_key_exists($ClassName, self::$Files)) {
require_once(self::$Files[$ClassName]);
return false;
}
//replace "\" whith DIRECTORY_SEPARATOR
$ClassName = str_replace(array("\\", "/"), DIRECTORY_SEPARATOR, $ClassName);
//already loaded, never mind
//if (class_exists(basename($ClassName), FALSE)) return FALSE;
$ClassPath = dirname($ClassName);
if ($ClassPath == ".") {
$ClassPath = "";
} elseif ($ClassPath == "/") {
$ClassPath = "";
} else {
$ClassPath = strtolower($ClassPath) . "/";
}
//Search dirs for matching class files
foreach (WbAuto::$Dirs as $sDirVal) {
foreach (WbAuto::$Types as $sTypeVal) {
$sTestFile = $sDirVal . $ClassPath . strtolower(sprintf($sTypeVal, basename($ClassName)));
if (is_file($sTestFile)) {
include($sTestFile);
return false;
}
}
}
}
/**
* @brief Adds a single class <-> file combination to the autoload list.
*
* These combinations allow for filename != clasname and are loaded first as it needs no directory searching.
* The path starts from WB_PATH. And it allows for overwrite of already existing entries.
* And as its loaded first it has priority over directory based class loading.
*
* @code
* WbAuto::AddFile("MultiCrud","/modules/multicrud/classes/multicrud.php");
* WbAuto::AddFile("R","/classes/rb.php");
* WbAuto::AddFile("R","/includes/rb.php", true);
*
* // namespace classes .. (needs more testing)
* WbAuto::AddFile("persistence\database","/framework/classes/persistence/database.php", true);
* @endcode
*
* @note Autodetection for direct path added , so in most cases you no longer need
* the direct path parameter.
*
* @param string $ClassName
* The actual name of the class to be loaded.
*
* @param string $ClassFile
* The path to the file to load for this class.
*
* @param boolean $Overwrite
* Set to true already set entries are overwritten.
*
* @param boolean $DirektPath
* Set to true to add a direkt path whithout added WB_PATH
*
* @retval boolean/string
* Returns false on success, and an error message on failure.
*/
public static function AddFile($ClassName = "", $ClassFile = "", $Overwrite = false, $DirektPath = false)
{
//Check for valid call return error if invalid
if ($ClassName == "") {
return ("AddFile, no 'ClassName' set!");
}
if ($ClassFile == "") {
return ("AddFile, no 'ClassFile' set!");
}
if (!is_string($ClassName)) {
return ("AddFile,'ClassName' is not a string");
}
if (!is_string($ClassFile)) {
return ("AddFile,'ClassFile' is not a string");
}
if (!is_bool($Overwrite)) {
return ("AddFile invalid parameter 'Overwrite' is not a boolean! ");
}
if (!is_bool($DirektPath)) {
return ("AddFile invalid parameter 'DirektPath' is not a boolean! ");
}
if (isset(WbAuto::$Files[$ClassName]) and $Overwrite == false) {
return ("Class already exists ($ClassName)");
}
// for windooze make sure we got the right seperator
$ClassFile = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $ClassFile);
// allow to add files directly
if (
strpos($ClassFile, WB_PATH) !== false || //Autodetection of direct path added
$DirektPath
) {
//this file delivers a full file path whithout adding WB path
$LoadFile = $ClassFile;
} else {
//construct full filepath whith WB path default behavior
$LoadFile = WB_PATH . $ClassFile;
}
if (!is_file($LoadFile)) {
return ("AddFile, File does not exist or not a file: $LoadFile");
}
if (!is_readable($LoadFile)) {
return ("AddFile, File not readable: $LoadFile");
}
// if all is ok set new Classfile
WbAuto::$Files[$ClassName] = $LoadFile;
return false;
}
/**
* @brief Add a directory to be searched for matching class names/files.
*
* Directories added here are searched for matching classfiles using patterns from the types array.
* The direcctory path starts from WB_PATH(webroot). The defautl patters in WB is class.classname.php all lowercase letters.
*
* @code
* WbAuto::AddDir("/classes/");
* WbAuto::AddDir("/modules/mymodule/classes/");
* WbAuto::AddDir("/var/web345/html/websitebaker/modules/mymodule/classes/" ,true);
* @endcode
*
* @note Autodetection for direct path added , so in most cases you no longer need
* the direct path parameter.
*
* @param string $Dir
* The path to the Directory to include starting from WB_PATH
*
* @param bool $Dir
* if set to true WB_PATH is not added
*
* @param boolean $DirektPath
* Set to true to add a direkt path whithout added WB_PATH
*
*
* @retval boolean/string
* Returns false on success, and an error message on failure.
*/
public static function AddDir($Dir = "", $DirektPath = false)
{
// some checks
if (!is_string($Dir)) {
return ("AddDir: Directory needs to be a string.");
}
if (empty($Dir)) {
return ("AddDir: Directory is empty.");
}
// for windooze make sure we got the right seperator
$Dir = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $Dir);
//always trim and re-add so we make sure we have a seperator at the end
$Dir = rtrim($Dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
// allow to add dirs directly
if (
strpos($Dir, WB_PATH) !== false || //Autodetection of direct path added
$DirektPath
) {
//construct full dir whithout WB path
$AddDir = $Dir;
} else {
//construct full dir whith WB path
$AddDir = WB_PATH . "/" . $Dir;
}
//Some more checks
if (!is_dir($AddDir)) {
return ("AddDir: Not a directory using is_dir: $AddDir");
}
if (!is_readable($AddDir)) {
return ("AddDir: Directory not readable: $AddDir");
}
// Add Dir
WbAuto::$Dirs[] = $AddDir;
//avoid double entries
WbAuto::$Dirs = array_unique(WbAuto::$Dirs);
return false;
}
/**
* @brief Adds a new search template to the list of search templates.
*
* Templates are used to look for matching files in the directory search.
*
* @code
* // %s is the classname.
* WbAuto::AddType("class.%s.inc.php");
* WbAuto::AddType("%s.php");
* WbAuto::AddType("%s.class.php");
* @endcode
*
* @param string $Type
* The search pattern/template to add.
*
* @retval boolean/string
* Returns false on success, and an error message on failure.
*/
public static function AddType($Type)
{
// Add Search template
WbAuto::$Types[] = $Type;
//avoid double entries
WbAuto::$Types = array_unique(WbAuto::$Types);
return false;
}
}
/// Finally register this autoloader
spl_autoload_register('WbAuto::Loader');
/// Then we add all stuff needed for WBCE
WbAuto::AddDir(dirname(__FILE__) . "/", true);