all repos — weimar @ cf03eeda27ccb78fc82bbbb91a92e2b30bd2eb18

Unnamed repository; edit this file 'description' to name the repository.

docs/CHEVERE.md (view raw)

  1# Chevereto V4 Architecture Reference
  2
  3> Repository: `github.com/chevereto/chevereto` (branch `4.5`)
  4> Latest release: **4.5.2** (Apr 21, 2026)
  5> License: AGPL-3.0 (Free edition) / Commercial proprietary (Lite/Pro)
  6> Author: Rodolfo Berrios (rodolfo@chevereto.com)
  7
  8---
  9
 10## 1. Overview
 11
 12Chevereto is a **self-hosted media-sharing platform** (like Flickr/Imgur) that allows users to run their own image/video hosting website. It has been in development since 2007 and is currently on V4. The codebase is primarily PHP (83.7%) with JavaScript (10.4%) and CSS (5.6%).
 13
 14The project has **921+ stars**, **72+ forks**, and **4 contributors**. It supports multi-tenancy, multi-user, multi-language (30+ languages), and multiple storage backends.
 15
 16---
 17
 18## 2. Tech Stack
 19
 20| Category | Technologies |
 21|----------|-------------|
 22| **Language** | PHP 8.2+ |
 23| **Framework** | Chevere (custom PSR-7/PSR-15 framework by same author) |
 24| **Frontend** | Vanilla JavaScript, CSS |
 25| **Database** | MySQL / MariaDB (PDO) |
 26| **Cache** | Redis (primary), file-based fallback (PSR-16) |
 27| **Image Processing** | Imagick, Intervention Image (`intervention/image` ^2.6) |
 28| **Video Processing** | php-ffmpeg (`php-ffmpeg/php-ffmpeg` ^1.2) |
 29| **Router** | Chevere Router (`chevere/router` ^0.9.1) |
 30| **HTTP** | Chevere HTTP (`chevere/http` ^0.7.1), Guzzle PSR-7 |
 31| **Auth** | Firebase JWT (`firebase/php-jwt` ^7.0), Google2FA |
 32| **Mail** | Symfony Mailer with 15+ transport integrations |
 33| **Storage** | AWS SDK S3 (`aws/aws-sdk-php` ^3.336.15), local filesystem |
 34| **EXIF** | php-exif, XMP Metadata Extractor |
 35| **QR Codes** | chillerlan/php-qrcode, Google2FA QR Code |
 36| **Encryption** | phpseclib/phpseclib ^3.0 |
 37| **Testing** | PHPUnit ^9.2, PHPStan ^1.11, Easy Coding Standard ^12.2 |
 38| **Refactoring** | Rector |
 39| **Debug** | PsySH ^0.11, XRdebug, Chevere var-dump |
 40
 41---
 42
 43## 3. Directory Structure
 44
 45```
 46chevereto/
 47├── index.php                          # Entry point → delegates to app/
 48├── .htaccess                          # Apache rewrite rules
 49├── LICENSE                            # AGPL-3.0
 50 51├── app/                               # Application root
 52│   ├── composer.json                  # PHP dependencies
 53│   ├── composer.lock
 54│   ├── env-default.php                # 100+ default env vars
 55│   ├── configurator.php               # Config processor
 56│   ├── upgrading.php                  # Upgrade screen handler
 57│   ├── phpstan.neon                   # PHPStan configuration
 58│   ├── phpstan-bootstrap.php
 59│   ├── rector.php                     # Rector configuration
 60│   │
 61│   ├── src/                           # Modern PSR-4 code (Chevereto\ namespace)
 62│   │   ├── Config/                    # Config singleton
 63│   │   ├── Encryption/                # Encrypt/decrypt functions
 64│   │   │   └── functions.php
 65│   │   ├── Http/                      # HTTP layer
 66│   │   │   ├── Controllers/Api/V4/    # API V4 controllers (13+)
 67│   │   │   └── Middlewares/           # IP restrict, API key auth, signed req
 68│   │   ├── Legacy/                    # Legacy systems (modern namespace)
 69│   │   │   ├── Classes/              # ~40 core domain classes
 70│   │   │   ├── G/                    # Global helpers, Gettext, Handler
 71│   │   │   ├── functions.php
 72│   │   │   └── functions-render.php
 73│   │   ├── Tenants/                   # Multi-tenant system
 74│   │   ├── Traits/Instance/           # Singleton trait
 75│   │   ├── Vars/                      # Immutable superglobal wrappers
 76│   │   └── PCRE.php                   # PCRE regex enum
 77│   │
 78│   ├── routes/                        # Modern route definitions
 79│   │   ├── api-v4.php                 # Main API v4 routes
 80│   │   ├── api-v4-admin.php           # Admin API routes
 81│   │   ├── api-v4-manager.php         # Manager API routes
 82│   │   └── tenants-internal-api-v4.php # Internal tenant API
 83│   │
 84│   ├── legacy/                        # Legacy boot & app code
 85│   │   ├── entrypoints/
 86│   │   │   └── index.php             # Web entry point
 87│   │   ├── load/                     # Bootstrap files
 88│   │   │   ├── php-boot.php
 89│   │   │   ├── app.php
 90│   │   │   ├── l10n.php
 91│   │   │   └── integrity-check.php
 92│   │   ├── routes/                   # 30+ legacy route handlers
 93│   │   ├── commands/                 # 19 CLI commands
 94│   │   └── install/                  # Installer
 95│   │
 96│   ├── schemas/                       # Database schemas
 97│   │   ├── mysql-5/
 98│   │   └── mysql-8/
 99│   │
100│   ├── languages/                     # 30+ i18n translation files
101│   ├── bin/                           # CLI entry points
102│   │   ├── cli, legacy, repl, tenants
103│   ├── tests/                         # PHPUnit tests
104│   ├── .cache/
105│   └── .psysh/
106107├── content/                           # Web-accessible assets
108│   ├── images/
109│   ├── legacy/
110│   └── pages/
111112├── images/                            # Default media
113├── importing/                         # Bulk import scripts
114├── sdk/                               # Client-side SDK
115│   ├── pup.js                         # Upload widget (full)
116│   └── pup.min.js                     # Upload widget (minified)
117118├── .github/                           # GitHub Actions, templates
119├── .package/                          # Docker packaging
120├── .ecs/                              # Easy Coding Standard config
121├── .vscode/                           # Editor settings
122└── .tinkerwell/                       # Tinkerwell snippets
123```
124
125---
126
127## 4. Architecture & Design Patterns
128
129### 4.1 Dual Codebase (Legacy + Modern Migration)
130
131The application is in active transition from legacy procedural code to modern PSR-4 namespaced code:
132
133- **Modern**: `app/src/` uses `Chevereto\` namespace, PSR-4 autoloading, proper DI via constructor injection, PHP 8 attributes
134- **Legacy**: `app/legacy/` and `app/src/Legacy/` contain older procedural code being progressively migrated
135- Both coexist via Composer autoload and a custom boot sequence
136
137The autoload configuration explicitly loads function files to bridge the two worlds:
138
139```json
140"autoload": {
141    "files": [
142        "src/Encryption/functions.php",
143        "src/Vars/functions.php",
144        "src/Legacy/functions.php",
145        "src/Legacy/functions-render.php",
146        "src/Legacy/G/functions.php",
147        "src/Legacy/G/functions-render.php",
148        "legacy/load/integrity-check.php",
149        "legacy/load/app.php",
150        "legacy/load/l10n.php"
151    ],
152    "psr-4": {
153        "Chevereto\\": "src/"
154    }
155}
156```
157
158### 4.2 Request Lifecycle
159
160```
161index.php
162  └─→ app/legacy/entrypoints/index.php
163        ├─ Defines ACCESS = 'web'
164        ├─ Requires php-boot.php (framework bootstrap)
165        ├─ Parses URL path from REQUEST_URI
166        ├─ Checks for /upgrading route
167        └─ Calls loaderHandler() → bootstraps app
168              ├─ Loads environment config
169              ├─ Initializes database connection
170              ├─ Sets up cache
171              ├─ Boots routing system
172              └─ Dispatches to appropriate route handler
173```
174
175### 4.3 Environment Configuration
176
177All configuration is driven by `CHEVERETO_*` environment variables. Defaults are defined in `app/env-default.php` which returns an associative array of 100+ settings:
178
179- **Database**: `CHEVERETO_DB_*` (driver, host, name, user, pass, port, prefix, PDO attrs)
180- **Cache**: `CHEVERETO_CACHE_*` (driver, host, port, password, key prefix, TTL, stampede)
181- **Feature Flags**: `CHEVERETO_ENABLE_*` (~50 boolean toggles for features)
182- **Limits**: `CHEVERETO_MAX_*` (file size, upload size, users, albums, tags, etc.)
183- **Storage**: Local and S3-compatible
184- **Encryption**: `CHEVERETO_ENCRYPTION_KEY`
185- **Multi-tenant**: `CHEVERETO_ENABLE_TENANTS`, `CHEVERETO_TENANT_*`
186- **External Services**: Akismet, ModerateContent, ProjectArachnid, StopForumSpam
187- **Binary paths**: exiftool, exiftran, ffmpeg, ffprobe
188- **Traefik/Proxy**: `CHEVERETO_HOSTNAME`, `CHEVERETO_SERVICE_NAME`, `CHEVERETO_SERVICE_PORT`, `CHEVERETO_PROXY_ENTRYPOINT`
189- **Debug/Dev**: `CHEVERETO_DEBUG_LEVEL`, `CHEVERETO_ENABLE_DEBUG`, XRdebug integration
190
191### 4.4 Routing
192
193**Two routing systems coexist:**
194
195#### Modern (Chevere Router) — `app/routes/`
196
197Routes are defined using the Chevere Router DSL with middleware chains:
198
199```php
200use function Chevere\Router\route;
201use function Chevere\Router\routes;
202
203return routes(
204    route(
205        '/_/api/4/config/traefik',
206        GET: TenantsConfigTraefikGet::class,
207    ),
208)->withAppendMiddleware(
209    RestrictIpAccess::with(allowList: '127.0.0.1,::1,172.16.0.0/12'),
210    TenantsApiKeyAuthorization::class,
211);
212```
213
214Route files:
215| File | Prefix | Purpose |
216|------|--------|---------|
217| `api-v4.php` | `/api/4/` | Main public API v4 |
218| `api-v4-admin.php` | `/api/4/` | Admin endpoints (storages) |
219| `api-v4-manager.php` | `/api/4/` | Manager endpoints (ban users) |
220| `tenants-internal-api-v4.php` | `/_/api/4/` | Internal tenant management |
221
222#### Legacy Routing — `app/legacy/routes/`
223
224Uses `Chevereto\Legacy\G\Handler` class with path-based matching. Configurable route slugs are stored in the database settings:
225
226```
227Settings constants:
228  ROUTING_REGEX      = '([\w_-]+)'
229  ROUTING_REGEX_PATH = '([\w\/_-]+)'
230```
231
232Configurable routes: `route_user` (→ `user`), `route_image` (→ `image`), `route_album` (→ `album`), `route_video` (→ `video`), `root_route` (→ `user`).
233
234Legacy routes support **virtual routing** — e.g., the video route maps to the image handler:
235
236```php
237// app/legacy/routes/video.php
238$route = 'image';
239virtualRouteHandleRedirect($route, ..., 'video');
240$handler->mapRoute($route);
241```
242
24330+ legacy route handler files: account, album, api, api-v1, captcha-verify, category, connect, dashboard, explore, following, image, importer-jobs, index, install, json, login, logout, moderate, oembed, page, plugin, redirect, search, settings, signup, tag, tag-autocomplete, update, upload, user, user-albums, video, webmanifest.
244
245### 4.5 Attribute-based Controllers (PHP 8 Attributes)
246
247Controllers use PHP 8 attributes for HTTP metadata:
248
249```php
250#[Response(
251    new Status(200),
252    new Header('Content-Type', 'application/json'),
253)]
254class TenantsGet extends Controller
255{
256    public function __construct(
257        private Tenants $tenants,
258    ) {}
259
260    public function __invoke(): array
261    {
262        return $this->tenants->getTenants();
263    }
264}
265```
266
267### 4.6 HTTP Middleware Layer
268
269Located in `app/src/Http/Middlewares/`:
270
271- **`RestrictIpAccess.php`** — IP allow/deny list enforcement (used on internal tenant API)
272- **`SignedRequest.php`** — Validates signed request headers for internal communication
273- **`TenantsApiKeyAuthorization.php`** — API key-based authorization for tenant management
274- **`Cors.php`** — CORS header handling
275
276Middlewares can be applied per-route-group via the Router's `withAppendMiddleware()` method.
277
278### 4.7 Multi-Tenant System
279
280Enabled via `CHEVERETO_ENABLE_TENANTS`. Built for SaaS deployment with first-class support:
281
282#### Core Classes (`app/src/Tenants/`)
283| Class | Purpose |
284|-------|---------|
285| `Tenant.php` | Single tenant entity (hostname, limits, service config) |
286| `Tenants.php` | Repository/collection — fetches tenants from DB |
287| `TenantsConfig.php` | Generates **Traefik** reverse proxy config dynamically |
288| `TenantsApiKey.php` | API key model for tenant auth |
289| `TenantPlan.php` | Tenant plan (pricing tier with limits) |
290
291#### Traefik Integration
292The system dynamically generates Traefik configuration so each tenant gets its own virtual host:
293
294```php
295// TenantsConfig generates:
296[
297    'http' => [
298        'routers' => [
299            'tenant-{id}' => [
300                'rule' => "Host(`{hostname}`)",
301                'service' => '{service}',
302                'entryPoints' => ['{entryPoint}'],
303                'middlewares' => [...],
304            ],
305        ],
306        'services' => [
307            '{service}' => [
308                'loadBalancer' => [
309                    'servers' => [['url' => "http://{service}:{port}"]],
310                    'passHostHeader' => true,
311                ],
312            ],
313        ],
314    ],
315]
316```
317
318#### Tenant API Endpoints
319All under `Chevereto\Http\Controllers\Api\V4\`:
320
321| Endpoint | Method | Purpose |
322|----------|--------|---------|
323| `/_/api/4/config/traefik` | GET | Generate Traefik proxy config |
324| `/_/api/4/tenants` | GET | List all tenants |
325| `/_/api/4/tenants` | POST | Create tenant |
326| `/_/api/4/tenants/{id}` | GET | Get single tenant |
327| `/_/api/4/tenants/{id}` | PATCH | Update tenant |
328| `/_/api/4/tenants/{id}` | DELETE | Delete tenant |
329| `/_/api/4/tenants/plans` | GET | List all plans |
330| `/_/api/4/tenants/plans` | POST | Create plan |
331| `/_/api/4/tenants/plans/{id}` | GET | Get plan |
332| `/_/api/4/tenants/plans/{id}` | PATCH | Update plan |
333| `/_/api/4/tenants/plans/{id}` | DELETE | Delete plan |
334| `/_/api/4/tenants/auth/verify` | POST | Verify tenant auth |
335| `/_/api/4/tenants/{id}/user/{id}/password` | PATCH | Reset user password |
336
337### 4.8 Immutable Superglobal Wrappers (Vars namespace)
338
339Superglobals are wrapped as **immutable value objects** using an `ImmutableMapTrait`:
340
341| Class | Source | Mutable? |
342|-------|--------|----------|
343| `EnvVar` | `$_ENV` | Immutable |
344| `GetVar` | `$_GET` | Immutable |
345| `PostVar` | `$_POST` | Immutable |
346| `FilesVar` | `$_FILES` | Immutable |
347| `CookieVar` | `$_COOKIE` | Mutable (for setting cookies) |
348
349Backed by helper functions in `app/src/Vars/functions.php` (e.g., `env()`).
350
351### 4.9 Config Singleton
352
353`Chevereto\Config\Config` uses the `AssertStaticInstanceTrait` to enforce a single application configuration instance. Loaded from environment variables via `app/configurator.php` and `app/env-default.php`.
354
355### 4.10 Website Modes: Community vs Personal
356
357- **Community mode** (multi-user, default): Full social features — followers, likes, signups, guest uploads, user routing
358- **Personal mode** (single profile): Disables followers, likes, signups, guest uploads, user routing; maps a single user to a custom route path
359
360---
361
362## 5. Legacy Domain Classes
363
364Located in `app/src/Legacy/Classes/` — ~40 classes forming the core domain model:
365
366| Class | Purpose |
367|-------|---------|
368| `Album.php` | Album CRUD and management |
369| `ApiKey.php` | API key authentication |
370| `AssetStorage.php` | Storage for CSS/JS/images with S3 settings |
371| `Cache.php` | Cache abstraction layer |
372| `Categories.php` / `Category.php` | Category CRUD |
373| `Confirmation.php` | Email/account confirmations |
374| `DB.php` | Database abstraction (PDO wrapper) |
375| `ExecutableBinary.php` | Checks binary paths/config |
376| `ExifTool.php` / `ExifTran.php` | EXIF processing via external tools |
377| `Follow.php` | User follow relationships |
378| `Image.php` | Image CRUD and metadata |
379| `ImageConvert.php` / `ImageResize.php` | Image format conversion and resizing |
380| `Import.php` / `ImporterFilterIterator.php` | Bulk importing from filesystem |
381| `IpBan.php` | IP ban list enforcement |
382| `KeyValue.php` / `KeyValueInterface.php` / `KeyValueNull.php` | Key-value store (Null Object pattern) |
383| `L10n.php` | Locale and localization handling |
384| `Listing.php` | Paginated data listings |
385| `LocalStorage.php` / `Storage.php` / `StorageApis.php` | Storage backend abstraction |
386| `Lock.php` | Mutex/locking mechanism |
387| `Login.php` | Authentication handling |
388| `Notification.php` | Notification system |
389| `Page.php` | Custom pages |
390| `Palettes.php` | Color palette extraction from images |
391| `ProjectArachnid.php` | CSAM detection via Project Arachnid |
392| `Queue.php` | Background job queue |
393| `RequestLog.php` | Request logging |
394| `Search.php` | Search functionality |
395| `Settings.php` | Application settings (DB-persisted) |
396| `Stat.php` | Statistics tracking |
397| `Tag.php` / `Tags.php` | Tag CRUD |
398| `TwoFactor.php` | 2FA authentication |
399| `Upload.php` / `Uploads.php` | Upload handling and processing |
400| `User.php` | User CRUD |
401| `Variable.php` | Variable handling |
402| `XmpMetadataExtractor.php` | XMP metadata extraction |
403
404---
405
406## 6. Global Helper Functions
407
408`app/src/Legacy/G/` provides globally-available functions loaded via Composer's `files` autoload:
409
410- **`functions.php`** — Sanitization, formatting, routing helpers, URL building (`get_base_url()`, `get_sorted_url()`), date formatting, string manipulation
411- **`functions-render.php`** — Template rendering helpers, HTML generation
412- **`Gettext.php`** — Gettext i18n wrapper class
413- **`Handler.php`** — Legacy request handler (route dispatch, settings, user context)
414
415---
416
417## 7. Database Schema
418
419Schemas stored as SQL files in `app/schemas/`:
420- `mysql-5/` — MySQL 5.x compatible
421- `mysql-8/` — MySQL 8.x compatible (with newer features)
422
423Database migration is handled via CLI command `database-migrate.php`.
424
425**Table prefix**: Configurable via `CHEVERETO_DB_TABLE_PREFIX` (default: `chv_`).
426
427Key domain tables (inferred from classes and schema): users, images, albums, categories, tags, storage_apis, api_keys, pages, notifications, stats, ip_bans, follows, queues, request_log, settings, confirmations, tenants, tenant_plans.
428
429---
430
431## 8. Image & Video Processing Pipeline
432
433**Image formats supported**: AVIF, JPEG, PNG, BMP, GIF, WEBP
434
435**Processing flow**:
4361. Upload received → validated (size, type, flood/rate check)
4372. EXIF data extracted (ExifTool or PHP exif via `lychee-org/php-exif`)
4383. XMP metadata extracted (via `XmpMetadataExtractor`)
4394. Image converted/resized as needed (Intervention Image + Imagick)
4405. Color palette extracted (`Palettes` class)
4416. Watermark applied (if `CHEVERETO_ENABLE_UPLOAD_WATERMARK` is enabled)
4427. Thumbnails generated (multiple sizes)
4438. Stored to configured storage backend (local or S3)
4449. Metadata saved to database
445
446**External binary dependencies** (configurable paths): exiftool, exiftran, ffmpeg, ffprobe
447
448---
449
450## 9. Storage Backends
451
452### Architecture
453Strategy pattern with three main classes:
454
455- **`Storage`** (`Chevereto\Legacy\Classes\Storage`) — Main abstraction with static methods for upload/delete
456- **`AssetStorage`** — Asset-specific storage (CSS, JS) with S3-compatible settings
457- **`LocalStorage`** — Local filesystem storage
458
459### Backend Types
4601. **Local filesystem** — default, stores in `PATH_PUBLIC`
4612. **AWS S3** — via `aws/aws-sdk-php ^3.336.15` (configurable: region, bucket, key, secret, endpoint, `use_path_style_endpoint`)
4623. **S3-compatible** — Any S3 API provider (DigitalOcean Spaces, MinIO, etc.)
463
464### Storage Settings (DB-persisted)
465Per-storage config: `account_id`, `account_name`, `api_id`, `bucket`, `key`, `region`, `secret`, `server`, `service`, `url`, `use_path_style_endpoint`, `is_https`, `is_active`.
466
467### CDN Support
468CDN delivery via external URLs, toggled by `CHEVERETO_ENABLE_CDN`.
469
470---
471
472## 10. Cache Architecture
473
474- **Primary driver**: Redis (via `CHEVERETO_CACHE_DRIVER`)
475- **Fallback**: File-based cache (Scrapbook library)
476- **PSR compliance**: PSR-16 (cache via `chevere/cache`)
477- **Configuration**: Host, port, password, key prefix (`chv:` default), TTL (max 86400s), stampede protection
478- **CLI commands**: `cache-flush.php`, `cache-view.php`
479
480---
481
482## 11. Security & Authentication
483
484| Layer | Implementation |
485|-------|----------------|
486| **Password hashing** | PHP native `password_hash()` / `password_verify()` |
487| **2FA** | Google2FA (`pragmarx/google2fa`) with QR codes |
488| **JWT** | Firebase php-jwt (`firebase/php-jwt ^7.0`) for API auth |
489| **API Keys** | Database-backed API key authentication |
490| **IP Bans** | IP-based access control (`IpBan` class + middleware) |
491| **Rate limiting** | Upload flood protection |
492| **Signed requests** | For internal/tenant API communication |
493| **Router secret** | Internal routing verification |
494| **External anti-abuse** | Akismet (spam), ProjectArachnid (CSAM), StopForumSpam, ModerateContent |
495| **CORS** | Via middleware |
496
497---
498
499## 12. Mail System
500
501Uses Symfony Mailer with DSN-based transport switching. 15+ integrations all configured via `CHEVERETO_MAILER_DSN` environment variable:
502
503| Supported Transports |
504|----------------------|
505| Amazon SES, AhaSend, Azure, Brevo, Infobip, Mailgun, Mailjet, Mailomat, MailPace, MailerSend, Mailtrap, Mailchimp, Microsoft Graph, Postal, Postmark, Resend, Scaleway, SendGrid, Sweego |
506
507---
508
509## 13. Encryption System
510
511Located in `app/src/Encryption/` (`Chevereto\Encryption\Key` namespace):
512
513- Encrypts/decrypts sensitive settings (secrets) before persisting to DB
514- `CHEVERETO_ENCRYPTION_KEY` env var provides the master key
515- CLI commands: `encrypt-secrets.php`, `decrypt-secrets.php`
516- Uses `phpseclib/phpseclib ^3.0` for cryptography primitives
517
518---
519
520## 14. CLI System
521
522Three CLI entry points in `app/bin/`:
523- **`cli`** — Modern CLI interface (tenant-aware)
524- **`legacy`** — Legacy CLI interface
525- **`repl`** — PsySH interactive shell
526- **`tenants`** — Tenant management CLI
527
528### CLI Commands (`app/legacy/commands/`) — 19 commands:
529
530| Command | Purpose |
531|---------|---------|
532| `bulk-importer.php` | Import images from filesystem |
533| `cache-flush.php` | Flush all cache |
534| `cache-view.php` | View cache contents |
535| `cipher.php` | Encryption/decryption tool |
536| `cron.php` | Scheduled tasks runner |
537| `database-migrate.php` | Run database migrations |
538| `decrypt-secrets.php` | Decrypt sensitive settings |
539| `encrypt-secrets.php` | Encrypt sensitive settings |
540| `htaccess-checksum.php` | Verify .htaccess integrity |
541| `htaccess-enforce.php` | Enforce .htaccess rules |
542| `install.php` | Initial installation |
543| `js.php` | JavaScript asset management |
544| `langs.php` | Language file management |
545| `password-reset.php` | Reset user password |
546| `setting-get.php` | Get a setting value |
547| `setting-update.php` | Update a setting |
548| `stats.php` | View statistics |
549| `stats-rebuild.php` | Rebuild statistics |
550| `version.php` | Show version |
551| `version-installed.php` | Show installed version |
552
553---
554
555## 15. Feature Flags (Key Toggles)
556
557From `env-default.php`:
558
559| Variable | Default | Purpose |
560|----------|---------|---------|
561| `CHEVERETO_ENABLE_API_GUEST` | `false` | Anonymous API access |
562| `CHEVERETO_ENABLE_API_USER` | `true` | User API access |
563| `CHEVERETO_ENABLE_BANNERS` | `false` | Advertising banners |
564| `CHEVERETO_ENABLE_BULK_IMPORTER` | `false` | Bulk import tool |
565| `CHEVERETO_ENABLE_CAPTCHA` | `true` | CAPTCHA protection |
566| `CHEVERETO_ENABLE_CDN` | `false` | CDN content delivery |
567| `CHEVERETO_ENABLE_COOKIE_COMPLIANCE` | `false` | GDPR cookie notice |
568| `CHEVERETO_ENABLE_FOLLOWERS` | `true` | User follow system |
569| `CHEVERETO_ENABLE_LIKES` | `true` | Like system |
570| `CHEVERETO_ENABLE_MODERATION` | `false` | Content moderation |
571| `CHEVERETO_ENABLE_NOTIFICATIONS` | `true` | Notification system |
572| `CHEVERETO_ENABLE_TENANTS` | `false` | Multi-tenant mode |
573| `CHEVERETO_ENABLE_USERS` | `true` | User registration/login |
574| `CHEVERETO_ENABLE_UPLOAD_URL` | `false` | URL-based uploads |
575| `CHEVERETO_ENABLE_UPLOAD_WATERMARK` | `false` | Image watermarking |
576
577---
578
579## 16. Editions (Licensing)
580
581- **Free** (AGPL-3.0): Core features, community support
582- **Lite**: Additional features, paid license
583- **Pro**: All features, commercial license
584
585Feature gating in the dashboard UI uses helpers like `badgePaid('lite')` and `inputDisabledPaid('lite')` to conditionally show/hide or disable premium features. Edition tracking lives in `app/.editions`.
586
587---
588
589## 17. Dev Tools & Quality
590
591| Tool | Purpose | Config |
592|------|---------|--------|
593| **PHPStan** | Static analysis (level 5+) | `app/phpstan.neon` |
594| **ECS (Easy Coding Standard)** | Code style | `.ecs/` directory |
595| **Rector** | Automated refactoring | `app/rector.php` |
596| **PHPUnit** | Unit/integration tests | `app/phpunit-report.xml` |
597| **XRdebug** | Debug toolbar | `CHEVERETO_XRDEBUG_*` env vars |
598| **PsySH** | Interactive debug shell | `app/.psysh/` |
599| **Tinkerwell** | Code snippets | `.tinkerwell/` |
600
601---
602
603## 18. Docker & Deployment
604
605- **Docker packaging** in `.package/` directory
606- **Docker image** via GitHub Packages (`ghcr.io/chevereto/chevereto`)
607- **Multi-arch**: x86_64 and arm64
608- **Docker Compose** via [chevereto/docker](https://github.com/chevereto/docker) repo
609- **Deployment options**: Pure Docker, Chevereto Docker, VPS, cPanel, Plesk, Installatron, Softaculous, SwiftWave, Cloudron
610
611---
612
613## 19. API Architecture Summary
614
615### API V4 (Modern)
616
617| Route Group | Path Prefix | Auth | Routes File |
618|-------------|-------------|------|-------------|
619| User API | `/api/4/` | JWT/API Key | `api-v4.php` |
620| Admin API | `/api/4/` | JWT + admin role | `api-v4-admin.php` |
621| Manager API | `/api/4/` | JWT + manager role | `api-v4-manager.php` |
622| Internal Tenant | `/_/api/4/` | IP allow + API Key | `tenants-internal-api-v4.php` |
623
624### Legacy API
625- Legacy JSON endpoint accessible via `get_base_url('json')`
626- Used by admin dashboard for CRUD operations on storages
627
628---
629
630## 20. Key Architecture Decisions
631
6321. **Env-var driven config**: All settings via environment variables, no config files to edit
6332. **Feature flags everywhere**: Toggle any capability on/off without code changes
6343. **Dual routing**: Modern Chevere Router for API V4, legacy routing for web pages
6354. **Progressive migration**: Old code lives in `Legacy/` namespaces, being gradually refactored to modern PSR-4
6365. **PSR compliance**: PSR-4 (autoload), PSR-7 (HTTP messages), PSR-15 (HTTP handlers), PSR-16 (cache)
6376. **Multi-tenant by design**: From database schema to API layer to reverse proxy config
6387. **Storage abstraction**: Strategy pattern for local vs S3 vs S3-compatible backends
6398. **Mailer abstraction**: Symfony Mailer with DSN-based transport switching
6409. **Security layers**: JWT + 2FA + API keys + IP bans + signed requests + rate limiting
64110. **Chevere framework**: Custom PHP framework by same author — attribute-based controllers, immutable superglobal wrappers, router with middleware chains
64211. **Singleton pattern** for application config (`Config` class)
64312. **Null Object pattern** for optional caching (`KeyValueNull`)
64413. **Adaptor pattern** for reverse proxy config generation (`TenantsConfig` → Traefik)
64514. **Immutable value objects** for superglobals (`EnvVar`, `GetVar`, `PostVar`, etc.)