# 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
```
