# Routing

## Frontend routing

Frontend routing goes through `cms/router.php` (PHP dev server) or `.htaccess` (Apache). Both provide clean URLs.

### PHP dev server

Start the server with:

```bash
php -S localhost:8080 cms/router.php
```

`cms/router.php` serves:
- Clean URLs: `/nl/page` → `public/index.php?page=page&lang=nl`
- `themes/` assets
- `admin/assets/` assets
- `plugins/` assets

### Apache (live server)

`public/.htaccess` rewrites URLs to `public/index.php`. Asset URLs (`/themes/`, `/admin/assets/`, `/plugins/`) are forwarded to `public/asset.php`.

`public/asset.php` serves files from the correct folders with the correct MIME type:
- `/themes/<name>/assets/...` → `themes/<name>/assets/...`
- `/admin/assets/...` → `admin/theme/default/assets/...`
- `/plugins/<name>/assets/...` → `plugins/<name>/assets/...`

## Admin routing

Admin routing goes through `public/admin.php` with clean URLs:

```
/admin/dashboard   → ?route=dashboard
/admin/content     → ?route=content
/admin/plugins     → ?route=plugins
```

`cms/router.php` or `.htaccess` converts `/admin/<route>` to `?route=<route>`.

### Route access control (RBAC)

Each route is checked via `AdminAuth::hasPermission($route)`:
- The `admin` role has wildcard `*` access
- Other roles have an explicit list of allowed routes in `ROLE_PERMISSIONS`
- Unauthorized routes return a **403 error**

## Plugin admin routing

System plugins can register admin routes. These are handled by `PluginManager::handleAdminRoute($route)`:

1. The system plugin registers routes via `getAdminRoutes()`
2. `PluginManager::getAdminMenuItems()` collects admin menu items via `getAdminMenu()`
3. On an admin request `PluginManager::handleAdminRoute($route)` finds a plugin that handles the route
4. The plugin method `handleAdminRoute($route)` renders the page content

```php
// PluginManager calls this for /admin/my-system
$plugin->handleAdminRoute('my-system');
```