# Fix database connection and route navigation ## Context Two unrelated defects are breaking the app on Laragon (Windows, Apache, PHP, MySQL/MariaDB): 1. **Database connection fails.** `config/database.php` reads `MYSQLHOST`/`MYSQLUSER`/`MYSQLPASSWORD`/etc. via `getenv()`. PHP under Apache/CGI on Laragon does **not** expose a project `.env` file to `getenv()` automatically — only the real OS environment. There is no `vlucas/phpdotenv` or `apache_setenv` call. The `.env` file at the project root is therefore ignored, so `getenv("MYSQLHOST")` returns `false`, and the PDO DSN is malformed (`host=;dbname=unimarket;port=3306;…`). 2. **Broken navigation links.** `index.php` links to `/public/customer/products/browse.php` and `/public/owner/dashboard.php`, but the actual folders live at `/customer/…` and `/owner/…` (no `public/` prefix). `includes/sidebar.php` references a `BASE_URL` constant that is never defined anywhere. Header/sidebar links will render as `/owner/products/list.php` (no host) or as the literal text `BASE_URLowner/…`. The `.env` file is otherwise correct: `MYSQLHOST=127.0.0.1`, `MYSQLUSER=root`, `MYSQLPASSWORD=` (empty), `MYSQLPORT=3306`, `MYSQLDATABASE=unimarket`. Database `unimarket` is created by `unimarket.sql`. ## Decisions - **DB fix approach:** Add a small inline parser for `.env` in `config/database.php` (no new dependency). On first call it loads `/path/to/project/.env`, sets values into `$_SERVER`, `$_ENV`, and `putenv()`, then continues to use `getenv()`. This is the minimum change that keeps `getenv()` calls working everywhere else and avoids pulling in Composer. - **Routes approach:** Fix the offending links to use the real paths (`/customer/…`, `/owner/…`, `/admin/…`) and define `BASE_URL` once. Do **not** rename folders or add a `public/` rewrite — that conflicts with the `guide.txt` layout. - `Unimarket/includes/sidebar.php` is a duplicate/stale file; we will not edit it (it is not referenced by any page). It is flagged in the risks so the team can delete it. ## Tasks ### 1. `config/database.php` — load `.env` before reading env vars - Add a function `loadEnv($path)` that: - Returns silently if file missing or unreadable. - Skips blank lines and `#` comments. - For `KEY=value` lines, calls `putenv("$KEY=$value")`, sets `$_ENV[$KEY]`, and `$_SERVER[$KEY]`. - Honors double-quoted values (strips quotes) and leaves empty values as `""`. - Call `loadEnv(__DIR__ . '/../.env')` before the `getenv()` reads. - Keep existing `try/catch` so a real connection failure still shows the message. ### 2. `index.php` — fix two hero buttons - Line 153: `/public/customer/products/browse.php` → `/customer/products/browse.php` - Line 155: `/public/owner/dashboard.php` → `/owner/dashboard.php` ### 3. `includes/sidebar.php` — define `BASE_URL` and fix trailing slashes - At the top of the file (before any output), add a guard that defines `BASE_URL` if not already set: ```php if (!defined('BASE_URL')) { define('BASE_URL', '/'); } ``` - Note: header.php links use absolute paths starting with `/` already, so sidebar is the only place that needs the constant. The current three links render as `/owner/products/list.php` etc., which is what we want. - (Optional but recommended) Remove the third link to `owner/reports.php` because `owner/reports.php` does **not** exist in the repo (see Risks). Decision: keep it for now — out of scope; this task is "fix what is broken", not "remove features". ### 4. `Unimarket/includes/sidebar.php` — flag as stale - Do not edit. List in Open Questions so the team decides whether to delete it. ## Files to change - `config/database.php` — add `loadEnv()` and call it - `index.php` — two href fixes - `includes/sidebar.php` — add `BASE_URL` guard ## Out of scope - `Unimarket/includes/sidebar.php` (duplicate, not referenced anywhere) - Missing `owner/reports.php`, `owner/manage_orders.php`, `admin/reports.php` — those are separate feature gaps, not routing bugs - Composer / phpdotenv adoption - CSRF enforcement gaps and other security items - `.htaccess` or `public/` rewrite ## Validation Manual smoke test on Laragon (`http://unimarket.test` or `http://localhost/Unimarket/`): 1. Hit `/index.php` — page loads, no `Database connection failed` banner. 2. Trending Products section renders up to 6 cards from the `products` table. 3. From a guest session, both header "Login"/"Register" links open the auth pages. 4. Log in as an owner; click "Go to Dashboard" hero button — lands on `/owner/dashboard.php` (not 404). 5. Log in as a customer; click "Browse Products" — lands on `/customer/products/browse.php`. 6. From the owner sidebar, "Products" and "Orders" links open their list pages without "BASE_URL" appearing in the URL or the rendered HTML. 7. Confirm by viewing source of any owner page that no literal string `BASE_URL` appears in `href` attributes. ## Risks / open questions - **Stale duplicate file:** `Unimarket/includes/sidebar.php` mirrors `includes/sidebar.php` and still uses `BASE_URL`. Recommend deleting the entire `Unimarket/` subfolder — confirm with team before doing so. - **Empty `MYSQLPASSWORD`:** Laragon default MySQL root has no password; the `getenv("MYSQLPASSWORD") ?: ''` works once `.env` is loaded. If a teammate's MySQL root *does* have a password, they must set `MYSQLPASSWORD="theirpass"` in `.env`. - **`owner/reports.php` referenced but absent:** clicking the "Reports" sidebar link will 404. Flagged for the team; not fixed here. - **No tests exist** in the repo, so validation is manual only.