# Mushila Writes

Online bookstore, blog and reader platform for Mushila Writes, built as a
plain PHP application (no framework, no Composer dependencies).

## Structure

- `app/controllers`, `app/models`, `app/helpers`, `app/middleware`, `app/services` — application logic, loaded directly via `require_once` (no autoloader)
- `config/` — bootstrap (`app.php`), database connection, constants, M-Pesa/Daraja settings
- `includes/` — shared header/footer/navbar/session partials
- Everything else (`books/`, `blog/`, `reader/`, `payment/`, `admin/`, etc.) is file-based routing: each `.php` file under a folder is a real, directly-requested URL

## Local setup

1. Point a PHP 8.4 + MySQL/MariaDB environment at this folder.
2. Configure database credentials in `config/database.php` (and `.env`, though nothing currently loads it automatically — it's reference only).
3. Set real Daraja (M-Pesa) credentials in `config/constants.php` before testing payments; a placeholder `MPESA_CALLBACK_TOKEN` there also needs rotating for production.
4. Set `config/app.php`'s `$app['environment']` to `'production'` before deploying live — this also disables on-screen error display.

## Known gaps

- Subscriptions (`payment.php` → `process-payment.php`) are not yet wired to a real payment handler; only one-off book purchases (`books/purchase.php` → `payment/initiate.php`) use the real M-Pesa integration.
- `admin/categories/edit.php`, `update.php`, `delete.php` and the `admin/members/`, `payments/`, `reports/`, `settings/` sections are unbuilt placeholders.
- `newsletters.php`'s extended signup form (country/frequency fields) isn't wired to a handler; the simpler subscribe forms across the site post to `/newsletter/subscribe.php`, which works.
