# Camagru A web application for creating and sharing photos with superposable overlays. Users can capture images via webcam (or upload), apply overlay effects, and share them in a public gallery with likes and comments. ## Features - **User accounts** — Register, email verification, login, password reset, profile editing - **Photo editor** — Webcam capture or image upload with selectable overlay images (PNG with alpha), server-side compositing - **Gallery** — Public paginated feed of all creations, likes and comments for logged-in users - **Notifications** — Email notification when someone comments on your image (configurable) - **Responsive** — Mobile-friendly layout ## Stack | Component | Technology | |-----------|------------| | Backend | PHP 8.5 (standard library only) | | Frontend | HTML / CSS / JavaScript | | Database | MariaDB 10.11 | | Web server | Nginx 1.27 | | Containers | Docker Compose | ## Getting started ```sh # 1. Clone the repository git clone && cd camagru # 2. Create your environment file cp .env.example .env # Edit .env with your own values # 3. Install dev tools composer install # 4. Build and run docker-compose up --build # 5. Open in browser # http://localhost:8080 ``` ## Host setup (Manjaro) `phpactor` (LSP) requires the `iconv` extension. Install and enable it: ```sh pamac install php85-iconv sudo sed -i 's/;extension=iconv/extension=iconv/' /etc/php/php.ini ``` ## Note on composer.json This project does not use Composer for runtime dependencies — only the PHP standard library is used. The `composer.json` exists to satisfy dev tooling: - `php-cs-fixer` — code style formatting (requires `composer.json` to determine target PHP version) - `php-parallel-lint` — syntax checking (dev dependency) These are development tools only and are not part of the application code. ## Linting ```sh vendor/bin/parallel-lint src/ ``` ## PHP architecture This project follows standard PHP patterns commonly used in framework-less applications: ### Front controller All HTTP requests are routed by Nginx to a single file: `src/public/index.php`. This file bootstraps the app and delegates to the router. No other PHP file is directly accessible from the web. ### Namespaces and autoloading PHP namespaces organize classes into a hierarchy (like directories). `namespace App\Controllers;` means the class lives under `App\Controllers`. The `use` keyword imports a class so you can refer to it by its short name instead of the full path (e.g. `Database` instead of `\App\Database`). The autoloader in `bootstrap.php` uses `spl_autoload_register` to automatically `require` class files when they're first used. It maps the `App\` namespace prefix to the `src/app/` directory, so `App\Controllers\HomeController` loads from `src/app/Controllers/HomeController.php`. ### MVC pattern - **Models** (`src/app/Models/`) — Data access layer, each model wraps a database table and uses prepared statements via PDO - **Views** (`src/app/Views/`) — PHP templates that output HTML. A layout file (`layouts/main.php`) wraps page-specific content via an `include`. View files have variables that appear undefined — this is because they are `include`d by controllers and inherit all variables from the calling scope (e.g. `$dbStatus` defined in `HomeController::index()` is available in the view it includes) - **Controllers** (`src/app/Controllers/`) — Handle requests, call models, and render views ### Request lifecycle 1. Nginx receives request, forwards to `public/index.php` 2. `bootstrap.php` starts the session, loads `.env`, registers the autoloader 3. Routes are defined in `config/routes.php` (mapping URL patterns to controller methods) 4. `Router::dispatch()` matches the URL against registered patterns and calls the matching controller method 5. The controller fetches data via models and renders a view inside the layout ## Image format choices - **Overlays** are PNG (alpha channel required for transparency) - **User input** (webcam captures, uploads) may be JPEG or PNG — GD is compiled with JPEG support to handle both - **Final composited images** are saved as PNG to preserve overlay transparency ## Project structure ``` camagru/ ├── docker-compose.yml ├── .env.example ├── docker/ │ ├── nginx/ # Nginx Dockerfile and config │ ├── php/ # PHP-FPM Dockerfile (GD + PDO) │ └── mariadb/ # Database init script └── src/ ├── public/ # Document root (entry point, CSS, JS, assets) ├── app/ # Application code (Controllers, Models, Views) ├── config/ # Route definitions └── uploads/ # User-generated images ```