aboutsummaryrefslogtreecommitdiffstats
path: root/README.md
blob: 4bea6c54c1faf3ed5e256def013e08db4a88e3f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# 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 <repo-url> && 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
```