# Config Reference (`config.php`) This document explains what each config value is used for at runtime. ## `ADMIN_EMAIL` (your specific question) `ADMIN_EMAIL` is the **fallback** recipient address for internal admin notifications. Primary recipients come from each admin account in `data/admins.json` (`email` field). The fallback is used only when no valid admin account email is available. Notification scope: - New reservation created (`sendReservationEmails()` in `includes/functions.php`) - New backorder created (`sendBackorderEmails()` in `includes/functions.php`) It is **not** used for customer login, admin login, password reset, or contact form logic. ## Constant-by-constant reference | Constant | What it controls | Where it is used | |---|---|---| | `SITE_NAME` | Shop name shown in UI and email subjects/content | `includes/header.php`, `admin/login.php`, mail templates in `includes/functions.php` | | `SITE_URL` | Base path for links/assets (e.g. `/shop`) and order-history cookie path | `includes/header.php`, `includes/footer.php`, `admin/login.php`, `orders.php`, cookie path helper in `includes/functions.php` | | `DISCLAIMER_LINES` | Text lines shown on homepage disclaimer box | `index.php` | | `RESERVATION_EXPIRY_DAYS` | Number of days until a regular reservation expires | Reservation creation/conversion in `includes/functions.php` | | `ORDER_PREFIX` | Prefix for generated order IDs, format `PREFIX-YEAR-SEQ` | ID generation + validation in `includes/functions.php` | | `ORDER_HISTORY_COOKIE_NAME` | Cookie key name for browser-linked order history | `includes/functions.php` | | `ORDER_HISTORY_COOKIE_TTL_DAYS` | Retention time (days) for order-history cookie | `includes/functions.php` | | `ORDER_HISTORY_MAX_IDS` | Max remembered order IDs in history cookie | `includes/functions.php` | | `ORDER_HISTORY_COOKIE_SECRET` | HMAC signing secret for order-history cookie integrity | `includes/functions.php` | | `ADMIN_EMAIL` | Fallback recipient for admin notification emails when no valid per-admin email exists | `includes/functions.php` | | `FROM_EMAIL` | Sender + reply-to email in outgoing mails | `sendEmail()` in `includes/functions.php` | | `FROM_NAME` | Sender display name in outgoing mails | `sendEmail()` in `includes/functions.php` | | `DATA_DIR` | Base directory for JSON data files | Used to compose file constants in `config.php` | | `PRODUCTS_FILE` | Product data JSON path | Product read/write helpers in `includes/functions.php` | | `RESERVATIONS_FILE` | Reservation/backorder JSON path | Reservation read/write helpers in `includes/functions.php` | | `ADMINS_FILE` | Admin account JSON path | Admin account read/write helpers in `includes/functions.php` | | `FAQ_FILE` | FAQ content JSON path (`content` markdown text) | FAQ read/write and markdown rendering helpers in `includes/functions.php`, pages `faq.php` + `admin/faq.php` | ## Backup and update client (`MANAGE_*`) These drive the update and backup client. Defaults for all of them live in `includes/manage.php` behind `if (!defined(...))`, so `config.php` only has to set what differs. Full behaviour: `docs/BACKUP_UPDATE.md`. | Constant | What it controls | Where it is used | |---|---|---| | `MANAGE_SERVER_URL` | Base URL of the Manage server, no trailing slash and no `/api` | `manageClientEndpoint()` in `includes/manage.php` | | `MANAGE_INSTANCE` | Instance id as created on the Manage server | auth header in `manageClientAuthHeaders()` | | `MANAGE_TOKEN` | The instance's secret token, shown once on creation. Empty disables every remote call | auth header in `manageClientAuthHeaders()` | | `MANAGE_HTTP_TIMEOUT` | Seconds for manifest and heartbeat | `manageClientRequest()` | | `MANAGE_HTTP_TIMEOUT_LONG` | Seconds for package download and backup upload | `manageUpdateDownloadPackage()`, `manageBackupUpload()` | | `MANAGE_APP_ROOT` | Root of the shop: update target and base of every relative backup path | `manageClientAppRoot()` | | `MANAGE_VERSION_FILE` | File holding the installed version | `manageClientVersion()` | | `MANAGE_VERSION_CONSTANT` | Constant name inside that file (`APP_VERSION`), or `null` for a plain text file | `manageClientVersion()` | | `MANAGE_DIR` | Base of all client runtime state, `data/manage/` | composes the paths below | | `MANAGE_BACKUP_DIR` | Local backup archives + `backup-index.json` | `includes/manage-backup.php` | | `MANAGE_WORK_DIR` | Update staging, cleared after every run | `manageUpdateApply()` | | `MANAGE_UPDATE_BACKUP_DIR` | Aside copies of files an update overwrote; only the last run is kept | `manageUpdateCopyWithBackup()` | | `MANAGE_LOG_FILE` | JSONL client log, rotated once past 2 MB | `manageClientLog()` | | `MANAGE_HEARTBEAT_STATE` | Timestamp of the last heartbeat, backs the one-per-hour throttle | `manageHeartbeatSendIfDue()` | | `MANAGE_MIGRATIONS_DIR` | Directory with migration scripts; `null` disables them | `includes/manage-update.php` | | `MANAGE_MIGRATIONS_STATE` | Which migrations have already run | `manageMigrationsReadState()` | | `MANAGE_BACKUP_SOURCES` | What goes into an archive: `glob` / `dir` / `file` entries with an optional `as` prefix | `manageBackupCollectSources()` | | `MANAGE_BACKUP_LOCAL_RETENTION` | Local archives kept (minimum 1). Independent of retention on the Manage server | `manageBackupApplyRetention()` | | `MANAGE_BACKUP_AUTO_INTERVAL_SECONDS` | Interval for the dashboard-triggered automatic backup; `0` disables it | `manageBackupIsAutomaticDue()`, called from `admin/index.php` | | `MANAGE_BACKUP_COMPRESS` | Deflate archive entries (needs zlib) | `manageZipCompressionAvailable()` | | `MANAGE_BACKUP_UPLOAD` | Upload every new backup to the Manage server | `manageBackupCreate()` | | `MANAGE_UPDATE_PROTECTED_PATHS` | Paths an update never overwrites, relative to `MANAGE_APP_ROOT`. A trailing slash marks a directory | `manageUpdateShouldSkipPath()` | | `MANAGE_UPDATE_SANITY_PATHS` | A package must contain at least one of these or it is rejected before anything is copied | `manageUpdateExtractPackage()` | | `MANAGE_UPDATE_POST_HOOK` | `['file' => ..., 'callback' => ...]` run after a successful deployment; `null` disables it | `manageUpdateRunPostHookCallback()`, points at `shopAfterUpdate()` in `includes/after-update.php` | ## Important notes - `ORDER_HISTORY_COOKIE_SECRET` should be a long random value; changing it invalidates old browser history cookies. - `SITE_URL` should match the real subpath where the app is served. If wrong, links/assets/cookies may break. - In this codebase, admin login data is read from `data/admins.json` (`ADMINS_FILE`). The `ADMIN_USERS` block is currently a legacy reference in comments/sample config, not active runtime auth. - `MANAGE_TOKEN` is a secret. It lives only in `config.php`, which is gitignored and excluded from release packages. If it leaks, rotate it on the Manage server. - `MANAGE_BACKUP_SOURCES` must not include `config.php`: backup archives are downloadable by anyone with a Manage server login.