# Script-PHP — Management Interface & OOBE Flow

## Overview

The management interface is a self-contained admin panel embedded in the `linguise/` directory. It is triggered by requesting a URL with `?linguise_language=zz-zz` (the value of `LINGUISE_UI_MANAGEMENT_ROOT`).

It is guarded by two PHP constants that templates check before rendering:
- `LINGUISE_MANAGEMENT` — unlocked when any management dispatch starts
- `LINGUISE_AUTHORIZED` — unlocked only when a valid admin session exists

---

## ui-config.php Lifecycle

`ui-config.php` is the state file for the management system. It does not exist on a fresh install.

```
Fresh install
    │
    ▼ (linguise.php detects no ui-config.php)
linguise.php generates ui-config.php with:
    - LINGUISE_OOBE_DONE = false
    - LINGUISE_LOGIN_SECRET = random_bytes(32) hex-encoded
    │
    ▼ (?linguise_language=zz-zz)
OobeManager::oobeRun()    ← renders OOBE wizard
    │
    ▼ (OOBE form submitted + validated)
OobeManager::writeOOBE()  ← rewrites ui-config.php with:
    - LINGUISE_OOBE_DONE = true
    - LINGUISE_OOBE_TOKEN_EXIST = true/false
    - LINGUISE_OOBE_DB_TYPE / _HOST / _NAME / _USER / _PASSWORD / _PREFIX
```

⚠ `ui-config.php` is **never edited manually**. It is regenerated by `OobeManager`.

---

## OOBE Wizard Flow

**File:** `src/OobeManager.php`, **Template:** `src/templates/oobe.php`

The OOBE wizard has two distinct mode paths depending on whether a token is already set in `Configuration.php`:

### Mode A: Without Token (`$token` is empty)

Used for **new customers** or fresh installations.

```
User visits ?linguise_language=zz-zz
    │
    ▼
LINGUISE_OOBE_DONE = false → OobeManager::oobeRun()
    │
    ▼ renders oobe.php with:
    - Password field (sets LINGUISE_LOGIN_SECRET)
    - Database type selector (SQLite / MySQL)
    - MySQL fields (host, name, user, password, prefix) — shown only if MySQL selected
    │
    ▼ POST: linguise_action=test-connection
OobeManager::storeDatabaseConnection()
    - Validates DB credentials (attempts connection)
    - On success: writes LINGUISE_OOBE_DB_* to ui-config.php
    - Sets LINGUISE_OOBE_DONE = true
    - Sets LINGUISE_OOBE_TOKEN_EXIST = false
```

### Mode B: With Token (`$token` is set in Configuration.php)

Used to **migrate older customers** to the new management system.

```
Same entry as Mode A, but oobe.php also shows:
    - Token field (pre-filled from Configuration.php)
    - Used to link the existing domain to the management system
    │
    ▼ POST: linguise_action=test-connection
OobeManager::storeDatabaseConnection()
    - Same DB validation
    - Sets LINGUISE_OOBE_TOKEN_EXIST = true
    - Token is passed to the API to associate the management installation
```

---

## Post-OOBE Admin Panel

**File:** `src/OobeManager.php` (`run()` method), **Template:** `src/templates/management.php`

Once OOBE is complete, visiting `?linguise_language=zz-zz` shows:

```
Unauthenticated:
    OobeManager::run() → renders login.php (password prompt)
    POST: linguise_action=login
        Session::start() → Session::hasSession() sets LINGUISE_AUTHORIZED
        Redirect to ?linguise_language=zz-zz

Authenticated (session valid):
    Define LINGUISE_MANAGEMENT, LINGUISE_AUTHORIZED
    OobeManager::run() → renders:
        header.php
        management.php (tabbed admin panel)
            tpl/main-settings.php   — token, default language, translatable languages
            tpl/advanced.php         — cache settings, debug, excluded URLs
            tpl/help.php             — documentation and support links
        footer.php
```

---

## Admin POST Actions

Dispatched by a `switch` block in `linguise.php`. All actions require CSRF verification via `Session::verifyCsrfToken()`.

| Action | Handler | Description |
|--------|---------|-------------|
| `clear-cache` | `OobeManager::clearCache()` | Deletes all files in `{data_dir}/cache/` |
| `clear-debug` | `OobeManager::clearDebug()` | Deletes `{data_dir}/debug.php` |
| `update-config` | `Management::updateConfig()` | Saves settings to DB, syncs with Linguise API |
| `update-config-iframe` | `Management::updateConfigIframe()` | Same but for the embedded iframe flow |
| `remote-update` | `Management::remoteUpdate()` | Pulls config snapshot from the Linguise API |
| `editor` | `Management::editorRun()` | Renders the live translation editor template |
| `logout` | `OobeManager::logout()` | Destroys the admin session |
| `linguise-update` | `Processor::update()` | Triggers self-update via `Updater` |

---

## Management Interface Access Guard

All templates in `src/templates/` begin with:

```php
defined('LINGUISE_SCRIPT_TRANSLATION') or die();
defined('LINGUISE_MANAGEMENT') or die();
```

Templates that render sensitive content additionally check:

```php
defined('LINGUISE_AUTHORIZED') or die();
```

This means templates cannot be included from any context that hasn't gone through the management dispatch path.

---

## CSRF Protection

CSRF tokens are generated per-session by `Session::generateCsrfToken()` and stored in `$_SESSION`. All POST actions call `Session::verifyCsrfToken($_POST['csrf_token'])` before processing. Failed verification results in a 403 response from `HttpResponse`.
