Skip to content

Commit fb34616

Browse files
author
Fredrick Peter
committed
Autoload Resgister Update
1 parent f58d404 commit fb34616

File tree

5 files changed

+201
-58
lines changed

5 files changed

+201
-58
lines changed

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ Prior to installing `php-orm-database` get the [Composer](https://getcomposer.or
110110
**Step 1** — update your `composer.json`:
111111
```composer.json
112112
"require": {
113-
"peterson/php-orm-database": "^4.1.4"
113+
"peterson/php-orm-database": "^4.1.5"
114114
}
115115
```
116116

@@ -1263,7 +1263,7 @@ true|false
12631263

12641264
## OrmDotEnv Servers
12651265
- Returns assoc arrays of Server
1266-
- `server/|domain/|protocol`
1266+
- `server\|domain\|protocol`
12671267

12681268
```
12691269
use builder\Database\OrmDotEnv;
@@ -1276,17 +1276,17 @@ dot_env()->getServers('domain');
12761276
```
12771277

12781278
## Autoload Register
1279-
- You can use register collection of all folder files
1280-
- This automatically includes all file in that folder and sub-folders
1279+
- Takes an `string\|array` as param
1280+
- You can use register a folder containing all needed files
1281+
- This automatically register `Files\|Classes` in the folder and sub-folders.
12811282

12821283
```
12831284
use builder\Database\AutoloadRegister;
12841285
12851286
AutoloadRegister::load('folder');
12861287
12871288
or
1288-
autoload_register()::load('folder');
1289-
autoload_register()->load('folder');
1289+
autoload_register(['folder', 'folder2]);
12901290
```
12911291

12921292
## Collation And Charset
@@ -1343,18 +1343,18 @@ class PostClass extends DB{
13431343
| migration() | Return instance of `(new Migration)` class |
13441344
| schema() | Return instance of `(new Schema)` class |
13451345
| dot_env() | Return instance of `(new OrmDotEnv)` class |
1346-
| autoload_register() | Return instance of `(new AutoloadRegister)` class |
13471346
| autoload_env() | Return instance of `(new AutoloadEnv)` class |
1348-
| env_start() | Same as `AutoloadEnv::start()` |
1347+
| autoload_register() | Same as `AutoloadRegister::load()` |
1348+
| env_start() | Same as `AutoloadEnv::start()` |
13491349
| config_database() | Same as `Direct DB Connection` get access to `DATABASE_CONNECTION` Constant |
13501350
| configure_pagination() | Same as `$db->configurePagination()` or `AutoloadEnv::configurePagination` |
1351-
| app_config() | Same as `$db->AppConfig()` |
1352-
| get_connection() | Same as `$db->getConnection()` |
1353-
| get_app_data() | Get `path` `database` & `pagination` info |
1354-
| get_query() | Same as `$db->getQuery()` |
1355-
| to_array() | `array` Convert items to array |
1356-
| to_object() | `object` Convert items to object |
1357-
| to_json() | `string` Convert items to json |
1351+
| app_config() | Same as `$db->AppConfig()` |
1352+
| get_connection() | Same as `$db->getConnection()` |
1353+
| get_query() | Same as `$db->getQuery()` |
1354+
| get_app_data() | Get `path\|database\|pagination` info |
1355+
| to_array() | `array` Convert items to array |
1356+
| to_object() | `object` Convert items to object |
1357+
| to_json() | `string` Convert items to json |
13581358

13591359
## Error Dump
13601360

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
},
3939
"extra": {
4040
"branch-alias": {
41-
"dev-main": "4.1.4-dev"
41+
"dev-main": "4.1.5-dev"
4242
}
4343
},
4444
"minimum-stability": "stable",

src/AutoloadRegister.php

Lines changed: 177 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,57 +11,186 @@
1111
class AutoloadRegister{
1212

1313
/**
14-
* Autoload All Folder and Sub-Folder files
15-
*
16-
* @param string $path_to_folder
17-
* - Specify the folder to autoload
14+
* The base directory to scan for classes and files.
15+
* @var string
16+
*/
17+
static private $baseDirectory;
18+
19+
/**
20+
* The class map that stores the class names and their corresponding file paths.
21+
* @var array
22+
*/
23+
private static $classMap = [];
24+
25+
/**
26+
* The file map that stores the file paths and their corresponding relative paths.
27+
* @var array
28+
*/
29+
private static $fileMap = [];
30+
31+
/**
32+
* Autoload function to load class and files in a given folder
33+
*
34+
* @param string|array $baseDirectory
35+
* - The directory path to load
1836
* - Do not include the root path, as The Application already have a copy of your path
1937
* - e.g [classes] or [app/main]
2038
*
2139
* @return void
2240
*/
23-
static public function load(?string $path_to_folder = null)
41+
static public function load(string|array $baseDirectory)
2442
{
25-
// If path is not null
26-
if(!empty($path_to_folder)){
27-
spl_autoload_register(function ($className) use($path_to_folder) {
28-
self::register($path_to_folder);
29-
});
43+
if(is_array($baseDirectory)){
44+
foreach($baseDirectory as $directory){
45+
self::$baseDirectory = self::getBasePath($directory);
46+
// only allow is an existing directory
47+
if(is_dir(self::$baseDirectory)){
48+
self::boot();
49+
}
50+
}
51+
} else{
52+
self::$baseDirectory = self::getBasePath($baseDirectory);
53+
// only allow is an existing directory
54+
if(is_dir(self::$baseDirectory)){
55+
self::boot();
56+
}
3057
}
3158
}
3259

3360
/**
34-
* Register method
35-
*
36-
* @param string $path_to_folder
37-
*
61+
* Boot the autoloader by setting the base directory,
62+
* - Scanning the directory, and registering the autoload method.
63+
* @return void
64+
*/
65+
private static function boot()
66+
{
67+
self::generateClassMap();
68+
self::generateFileMap();
69+
self::loadFiles();
70+
spl_autoload_register([__CLASS__, 'loadClass']);
71+
}
72+
73+
/**
74+
* Autoload function to load the class file based on the class name.
75+
*
76+
* @param string $className The name of the class to load.
77+
* @return void
78+
*/
79+
private static function loadClass($className)
80+
{
81+
$filePath = self::$classMap[$className] ?? null;
82+
if ($filePath && file_exists($filePath)) {
83+
require_once $filePath;
84+
}
85+
}
86+
87+
/**
88+
* Load the files from the file map.
89+
*
90+
* @return void
91+
*/
92+
private static function loadFiles()
93+
{
94+
foreach (self::$fileMap as $fileName => $filePath) {
95+
if (file_exists($filePath)) {
96+
require_once $filePath;
97+
}
98+
}
99+
}
100+
101+
/**
102+
* Generate the class map by scanning the base directory and its subdirectories.
103+
*
38104
* @return void
39105
*/
40-
static private function register($path_to_folder)
106+
private static function generateClassMap()
41107
{
42-
// directory full path
43-
$directory = self::convertPath($path_to_folder);
108+
$fileIterator = new RecursiveIteratorIterator(
109+
new RecursiveDirectoryIterator(self::$baseDirectory)
110+
);
44111

45-
if (!is_dir($directory)) {
46-
return;
112+
foreach ($fileIterator as $file) {
113+
if ($file->isFile() && $file->getExtension() === 'php') {
114+
$filePath = $file->getPathname();
115+
$className = self::getClassName($filePath);
116+
if (!is_null($className)) {
117+
self::$classMap[ltrim($className, '\\')] = self::pathReplacer($filePath);
118+
}
119+
}
47120
}
121+
}
48122

49-
// Create a recursive iterator to iterate through the directory
50-
$iterator = new RecursiveIteratorIterator(
51-
new RecursiveDirectoryIterator(
52-
$directory,
53-
RecursiveDirectoryIterator::SKIP_DOTS
54-
),
55-
RecursiveIteratorIterator::LEAVES_ONLY
123+
/**
124+
* Generate the file map by scanning the base directory and its subdirectories.
125+
*
126+
* @return void
127+
*/
128+
private static function generateFileMap()
129+
{
130+
$fileIterator = new RecursiveIteratorIterator(
131+
new RecursiveDirectoryIterator(self::$baseDirectory)
56132
);
57133

58-
// Loop through the iterator
59-
foreach ($iterator as $file) {
60-
// Check if the item is a file and has a PHP extension
134+
foreach ($fileIterator as $file) {
61135
if ($file->isFile() && $file->getExtension() === 'php') {
62-
include_once $file->getPathname();
136+
$filePath = $file->getPathname();
137+
$className = self::getClassName($filePath);
138+
139+
if ($className === null) {
140+
$relativePath = self::getRelativePath($filePath);
141+
self::$fileMap[$relativePath] = self::pathReplacer($filePath);
142+
}
143+
}
144+
}
145+
}
146+
147+
/**
148+
* Get the relative path from the file path.
149+
*
150+
* @param string $filePath The file path.
151+
* @return string The relative path.
152+
*/
153+
private static function getRelativePath($filePath)
154+
{
155+
$relativePath = substr($filePath, strlen(self::$baseDirectory));
156+
return ltrim($relativePath, '/\\');
157+
}
158+
159+
/**
160+
* Get the class name from the file path.
161+
*
162+
* @param string $filePath The file path.
163+
* @return string|null The class name, or null if not found.
164+
*/
165+
private static function getClassName($filePath)
166+
{
167+
$namespace = '';
168+
$content = file_get_contents($filePath);
169+
$tokens = token_get_all($content);
170+
$count = count($tokens);
171+
172+
for ($i = 0; $i < $count; $i++) {
173+
if ($tokens[$i][0] === T_NAMESPACE) {
174+
for ($j = $i + 1; $j < $count; $j++) {
175+
if ($tokens[$j][0] === T_STRING || $tokens[$j][0] === T_NS_SEPARATOR) {
176+
$namespace .= $tokens[$j][1];
177+
} elseif ($tokens[$j] === '{' || $tokens[$j] === ';') {
178+
break;
179+
}
180+
}
181+
}
182+
183+
if ($tokens[$i][0] === T_CLASS || $tokens[$i][0] === T_TRAIT) {
184+
for ($j = $i + 1; $j < $count; $j++) {
185+
if ($tokens[$j] === '{' || $tokens[$j] === 'extends' || $tokens[$j] === 'implements' || $tokens[$j] === 'use') {
186+
break;
187+
} elseif ($tokens[$j][0] === T_STRING) {
188+
return $namespace . '\\' . $tokens[$j][1];
189+
}
190+
}
63191
}
64192
}
193+
return;
65194
}
66195

67196
/**
@@ -71,13 +200,27 @@ static private function register($path_to_folder)
71200
*
72201
* @return string
73202
*/
74-
static private function convertPath($path_to_folder)
203+
private static function getBasePath($path_to_folder)
75204
{
76205
$ormDotEnv = new OrmDotEnv();
206+
return self::pathReplacer($ormDotEnv->getDirectory() . "/{$path_to_folder}");
207+
}
208+
209+
/**
210+
* Replace path with given string
211+
* \ or /
212+
*
213+
* @param string $path
214+
* @param string $replacer
215+
*
216+
* @return string
217+
*/
218+
static private function pathReplacer($path, $replacer = '/')
219+
{
77220
return str_replace(
78-
'/',
79-
'\\',
80-
$ormDotEnv->getDirectory() . "/{$path_to_folder}"
221+
['\\', '/'],
222+
$replacer,
223+
$path
81224
);
82225
}
83226

src/Migrations/Blueprint.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ private function tempMigrationQuery(mixed $query = null)
4747
{
4848
// Start the session has not already been started
4949
if (session_status() == PHP_SESSION_NONE) {
50-
session_start();
50+
@session_start();
5151
}
5252

5353
$_SESSION[$this->session] = json_encode($query);

src/helpers.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,18 @@ function schema()
7272

7373
if (! function_exists('autoload_register')) {
7474
/**
75-
* Autoload All Folder and Sub-Folder files
76-
*
77-
* @param string $path_to_folder
78-
* - Specify the folder to autoload
75+
* Autoload function to load class and files in a given folder
76+
*
77+
* @param string|array $baseDirectory
78+
* - The directory path to load
7979
* - Do not include the root path, as The Application already have a copy of your path
80-
* - e.g [classes] or [app/main]
80+
* - e.g 'classes' or ['app/main', 'includes']
8181
*
8282
* @return void\builder\Database\AutoloadRegister
8383
*/
84-
function autoload_register()
84+
function autoload_register(string|array $directory)
8585
{
86-
return new AutoloadRegister();
86+
return (new AutoloadRegister)::load($directory);
8787
}
8888
}
8989

0 commit comments

Comments
 (0)