mirror of
https://github.com/Vateron-Media/XC_VM.git
synced 2026-10-17 20:03:03 +02:00
145 lines
4.5 KiB
Markdown
145 lines
4.5 KiB
Markdown
# Autoloader — Class Registration
|
|
|
|
XC_VM uses a custom autoloader (`src/autoload.php`) instead of Composer.
|
|
Classes are discovered **automatically** — no manual registration required.
|
|
|
|
---
|
|
|
|
## How It Works
|
|
|
|
```
|
|
Request → autoload.php included
|
|
│
|
|
├── Cache file exists?
|
|
│ YES → load igbinary cache → O(1) lookups
|
|
│ NO → warmCache(): scan all directories via token_get_all()
|
|
│ → build ClassName → filePath map
|
|
│ → persist to tmp/cache/autoload_map
|
|
│
|
|
└── Class requested by PHP
|
|
│
|
|
├── 1. Explicit classMap (addClass())
|
|
├── 2. Resolved cache (from file or previous lookup)
|
|
└── 3. Live directory scan (fallback, cached for next time)
|
|
```
|
|
|
|
## Adding a New Class
|
|
|
|
**Just create the file.** That's it.
|
|
|
|
Place your PHP file in any registered directory (or its subdirectory):
|
|
|
|
| Directory | Purpose |
|
|
|-----------|---------|
|
|
| `src/core/` | Framework core (Database, Cache, Auth, Http, Process, etc.) |
|
|
| `src/domain/` | Business logic (Services, Repositories) |
|
|
| `src/infrastructure/` | External adapters (DatabaseFactory, CacheReader, Redis) |
|
|
| `src/streaming/` | Streaming subsystem (Auth, Delivery, Codec, Health) |
|
|
| `src/modules/` | Optional modules (Plex, Watch, TMDB, Ministra, etc.) |
|
|
| `src/public/` | Controllers and Views |
|
|
|
|
### Example
|
|
|
|
```php
|
|
// src/domain/Billing/InvoiceService.php
|
|
class InvoiceService {
|
|
public static function generate($userId) { ... }
|
|
}
|
|
```
|
|
|
|
After creating the file, **delete the cache** so the autoloader rediscovers classes:
|
|
|
|
```bash
|
|
rm -f /home/xc_vm/tmp/cache/autoload_map
|
|
```
|
|
|
|
On the next request, `warmCache()` runs automatically, finds `InvoiceService`, and caches it.
|
|
|
|
## Cache Invalidation
|
|
|
|
The cache file `tmp/cache/autoload_map` is a binary file (igbinary format).
|
|
It must be deleted whenever:
|
|
|
|
- A new class file is added
|
|
- A class file is renamed or moved
|
|
- A class file is deleted
|
|
|
|
```bash
|
|
# Delete manually
|
|
rm -f /home/xc_vm/tmp/cache/autoload_map
|
|
|
|
# Or via PHP
|
|
XC_Autoloader::clearCache();
|
|
```
|
|
|
|
> **Note:** If a class is requested that isn't in the cache, the autoloader falls back to a live directory scan and caches the result automatically. So the cache only needs to be cleared when files are moved/renamed/deleted — new classes will eventually be found via fallback.
|
|
|
|
## Manual Registration (Rare)
|
|
|
|
For special cases where a file contains multiple classes or the filename doesn't match the class name:
|
|
|
|
```php
|
|
XC_Autoloader::addClass('DropboxClient', '/home/xc_vm/includes/libs/Dropbox.php');
|
|
XC_Autoloader::addClass('DropboxException', '/home/xc_vm/includes/libs/Dropbox.php');
|
|
```
|
|
|
|
This is mainly needed for legacy library files that bundle multiple classes in one file (e.g., `iptables.php`, `m3u.php`).
|
|
|
|
## Adding a New Source Directory
|
|
|
|
Edit `registerDirectories()` in `src/autoload.php`:
|
|
|
|
```php
|
|
private static function registerDirectories() {
|
|
$base = self::$basePath;
|
|
|
|
self::addDirectory($base . 'core');
|
|
self::addDirectory($base . 'domain');
|
|
self::addDirectory($base . 'infrastructure');
|
|
self::addDirectory($base . 'streaming');
|
|
self::addDirectory($base . 'modules');
|
|
self::addDirectory($base . 'public');
|
|
|
|
// Add your new directory here:
|
|
self::addDirectory($base . 'my_new_dir');
|
|
}
|
|
```
|
|
|
|
Then delete the cache.
|
|
|
|
## Naming Rules
|
|
|
|
| Rule | Example |
|
|
|------|---------|
|
|
| File name **must** match class name | `InvoiceService.php` → `class InvoiceService` |
|
|
| One class per file (recommended) | Multi-class files need `addClass()` |
|
|
| PascalCase | `StreamService`, `DatabaseHandler` |
|
|
| No namespaces | `class StreamService { }` — no `namespace` keyword |
|
|
| No `declare(strict_types=1)` | Project convention |
|
|
|
|
## Duplicate Class Names
|
|
|
|
If two files define the same class name, **first-found wins** based on directory scan order. This is fragile — avoid duplicate names. Use prefixed names instead:
|
|
|
|
```
|
|
✗ public/Controllers/Admin/PlexController.php ← conflict
|
|
✗ modules/plex/PlexController.php ← conflict
|
|
|
|
✓ public/Controllers/Admin/AdminPlexController.php ← unique
|
|
✓ modules/plex/PlexController.php ← unique
|
|
```
|
|
|
|
## Debugging
|
|
|
|
```php
|
|
// See all registered directories
|
|
print_r(XC_Autoloader::getDirectories());
|
|
|
|
// See explicit class map
|
|
print_r(XC_Autoloader::getClassMap());
|
|
|
|
// Force full rescan
|
|
XC_Autoloader::clearCache();
|
|
XC_Autoloader::warmCache();
|
|
```
|