# Core Framework — `core/` Framework internals. **Rarely modified.** Contains the request lifecycle engine. ## Files | File | Purpose | |------|---------| | `Bootstrap.php` | Bootstraps environment, loads config, starts routing | | `Controller.php` | Base controller class — all UI controllers extend this (via `AppController`) | | `View.php` | View renderer — handles `render()`, `PartialView()`, asset injection | | `AltoRouter.php` | URL router used for complex custom routes | --- ## Request Lifecycle ``` Request → public/index.php → config.php (loads .env, defines constants) → core/Bootstrap.php (environment setup, session, autoload) → AltoRouter / auto-routing → ControllerClass::method($param) → $this->view->render(...) → Response (HTML or JSON) ``` Auto-routing maps `/controller/method/param` directly to `ControllerClass::method($param)`. --- ## `Controller` (`core/Controller.php`) Base class. Provides: - `$this->view` — View instance - `$this->JavaScript[]` — array of JS paths to inject - `$this->Styles[]` — array of CSS paths to inject - `redirect($url)` — HTTP redirect helper **Do not modify this file.** App-wide customisation belongs in `app/Controllers/AppController.php`. --- ## `AppController` (`app/Controllers/AppController.php`) Sits between `core/Controller` and all UI page controllers. UI controllers extend `AppController`, not `Controller` directly. **Current responsibilities:** - Injects `$UserProfile` (logged-in user's full profile via `User::profile()`) into every view automatically. **`use` statement scoping rule:** - Namespaces needed on every page → `AppController` - Namespaces needed by one controller → that controller only - Namespaces needed by one method → inline as fully-qualified class name ```php // app/Controllers/AppController.php use App\Components\User; class AppController extends Controller { function __construct() { parent::__construct(); if (!empty($_SESSION['login']['userid'])) { $this->view->UserProfile = User::profile($_SESSION['login']['userid']); } } } ``` --- ## `View` (`core/View.php`) **Properties:** - Any property set on `$this->view` becomes a variable in the rendered template. **Methods:** - `render($viewPath, $wrapper = '', $useWelcome = true)` — render a view - `PartialView($partialName)` — load and return a partial as a string **Render signatures used in practice:** ```php $this->view->render(__CLASS__ . '/' . __FUNCTION__); // default admin wrapper $this->view->render(__CLASS__ . '/' . __FUNCTION__, 'login'); // login wrapper $this->view->render('clients/index', true, 'site'); // legacy style ``` --- ## Routing ### Auto-Routing (default) | URL | Maps to | |-----|---------| | `/clients` | `Clients::index()` | | `/clients/show/123` | `Clients::show(123)` | | `/products/edit/456` | `Products::edit(456)` | ### AltoRouter (complex routes) Define in `public/routes.php` or `api/routes.php`: ```php // Named route with typed parameter $router->map('GET', '/users/[i:id]', 'Users#show', 'user_show'); // Multiple parameters $router->map('GET', '/blog/[i:year]/[i:month]/[*:slug]', 'Blog#show', 'blog_post'); // POST $router->map('POST', '/api/users/create', 'UsersAPI#create', 'api_user_create'); ``` **Match type tokens:** - `[i:id]` — integer - `[a:action]` — alphanumeric (A-Z, a-z, 0-9, -) - `[h:key]` — hex - `[*:trailing]` — catch-all (no slashes) - `[**:path]` — catch-all including slashes ```php // Generate URL from named route echo $router->generate('user_show', ['id' => 5]); // → /users/5 ```