# Script-PHP — Environment & Configuration

## Overview

Script-PHP uses a **three-layer configuration system** with no `.env` files in production. All configuration lives in PHP constants and static class properties.

```
Configuration.php       (user edits this)
    +
ConfigurationLocal.php  (optional local override, same structure)
    │
    ▼
src/Configuration.php   (internal runtime singleton — never edit directly)
    +
ui-config.php           (generated by OobeManager — never edit manually)
```

---

## Layer 1: User-Editable Configuration

**File:** `Configuration.php` (root)

This is the only file site owners should edit. It declares a class `\Linguise\Script\Configuration` with `public static` properties.

### Key Properties

| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `$token` | `string` | `''` | Linguise API token for this domain |
| `$cms` | `string` | `'auto'` | CMS type (`wordpress`, `joomla`, `prestashop`, `opencart`, `zencart`, `magento`, `laravel`, `auto`) |
| `$cache_enabled` | `bool` | `true` | Whether to cache translated responses |
| `$cache_max_size` | `int` | `500` | Max cache folder size in MB before eviction |
| `$cache_time_check` | `int` | `3600` | Cache entry TTL in seconds |
| `$debug` | `int` | `0` | Debug verbosity (0 = off, 1–5 = increasing detail) |
| `$debug_ip` | `string` | `''` | Restrict debug logging to this IP (empty = all IPs) |
| `$server_ip` | `string` | `''` | Override translation server IP |
| `$server_port` | `int` | `443` | Override translation server port |

### Hook Methods (on* prefix)

Methods prefixed `on` are registered as `Hook` callbacks and called at specific pipeline stages:

| Method | Trigger |
|--------|---------|
| `onBeforeMakeRequest` | Before curl proxy to origin server |
| `onAfterMakeRequest` | After curl proxy returns |
| `onBeforeTranslationRequest` | Before sending HTML to translation server |
| `onAfterTranslationRequest` | After translation server responds |

**ConfigurationLocal.php** has the same structure and is loaded after `Configuration.php`. It overrides any properties it declares (useful for dev/staging environments, or customer specific configuration).

---

## Layer 2: Internal Runtime Singleton

**File:** `src/Configuration.php`

All values are stored as private properties with strict defaults. Values are written via `set($key, $value)`. Direct external access is via `get($key)` or typed getters. This file must not be edited without Plan Mode — see `memory-bank/planModeFiles.md`.

---

## Layer 3: Generated ui-config.php

**File:** `ui-config.php` (root, generated by `OobeManager`)

⚠ **Never edit this file manually.** It is regenerated by the OOBE wizard on first install, and updated by `OobeManager::writeOOBE()`. It defines PHP constants consumed at boot time.

### Constants Defined in ui-config.php

| Constant | Type | Set by | Description |
|----------|------|--------|-------------|
| `LINGUISE_OOBE_DONE` | `bool` | OobeManager | `true` after first-run setup is complete |
| `LINGUISE_LOGIN_SECRET` | `string` | OobeManager (random 64-char hex) | Admin session signing secret |
| `LINGUISE_OOBE_TOKEN_EXIST` | `bool` | OobeManager | `true` if a token was present during OOBE |
| `LINGUISE_OOBE_DB_TYPE` | `string` | OobeManager | Database type from OOBE (`sqlite` or `mysql`) |
| `LINGUISE_OOBE_DB_HOST` | `string` | OobeManager | MySQL host (if MySQL selected) |
| `LINGUISE_OOBE_DB_NAME` | `string` | OobeManager | MySQL database name |
| `LINGUISE_OOBE_DB_USER` | `string` | OobeManager | MySQL username |
| `LINGUISE_OOBE_DB_PASSWORD` | `string` | OobeManager | MySQL password |
| `LINGUISE_OOBE_DB_PREFIX` | `string` | OobeManager | Table prefix |

---

## Runtime Constants (Defined in Code)

These constants are defined by `linguise.php` or `Helper.php` at boot time, not in config files.

| Constant | Defined in | Description |
|----------|-----------|-------------|
| `LINGUISE_SCRIPT_TRANSLATION` | `linguise.php` | Access guard; all `src/` files require this to be defined |
| `LINGUISE_SCRIPT_TRANSLATION_VERSION` | `linguise.php` | Current script version string (e.g., `1.3.46`) |
| `LINGUISE_BASE_DIR` | `linguise.php` | Absolute filesystem path to the `linguise/` folder |
| `LINGUISE_BASE_URL` | `linguise.php` | URL to the `linguise/` folder |
| `LINGUISE_MANAGEMENT` | `OobeManager` / templates | Unlocks template rendering (all templates guard with `defined('LINGUISE_MANAGEMENT') or die()`) |
| `LINGUISE_AUTHORIZED` | `OobeManager` | Defined when a valid admin session exists (`defined('LINGUISE_AUTHORIZED') or die()`) |
| `LINGUISE_UI_MANAGEMENT_ONLY` | Caller (WP/Joomla plugin) | Forces management-only mode; skips translation proxy |
| `LINGUISE_UI_MANAGEMENT_ROOT` | `linguise.php` | Language code that triggers the management UI (default: `zz-zz`) |

---

## PHPUnit Test Environment Variables

These are injected by `phpunit.xml` during tests:

| Variable | Default value | Purpose |
|----------|---------------|---------|
| `DB_HOST` | `localhost` | MySQL host for integration tests |
| `DB_NAME` | `linguise_tests` | MySQL database name |
| `DB_USER` | `root` | MySQL username |
| `DB_PASSWORD` | `password` | MySQL password |
| `DB_DBNAME` | `testing` | Alternative DB name |

---

## Data Directory

The data directory (`{data_dir}`) is token-scoped to prevent cross-domain leakage. It contains:

```
{data_dir}/
├── cache/          # Translated page cache files
├── linguise.sqlite # SQLite database (if SQLite driver)
└── debug.php       # Debug log (if debug > 0)
```

The path is computed by `Helper::getDataDir()` using the token as a subdirectory segment.
