Files
vidok.com/.paul/codebase/architecture.md
Jacek Pyziak cf1a0adb0b docs: map existing codebase
- stack.md (68 lines) - PHP/MySQL/Apache stack, vendored libraries
- architecture.md (131 lines) - Custom MVC CMS, dual-layer (front/admin)
- structure.md (170 lines) - Directory layout and conventions
- conventions.md (98 lines) - PHP snake_case, SCSS $c/$f prefixes, jQuery patterns
- testing.md (49 lines) - No automated tests detected
- integrations.md (111 lines) - Google Maps, PHPMailer, Pixieset, Facebook
- concerns.md (150 lines) - Critical security issues: hardcoded creds, MD5, unserialize
- db_schema.md (260 lines) - ~32 tables with pp_ prefix, inferred from source
- tech_changelog.md (9 lines) - Initial log entry

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-05 22:02:04 +02:00

169 lines
6.9 KiB
Markdown

# Architecture
**Analysis Date:** 2026-05-05
## Pattern Overview
**Overall:** Custom MVC CMS (Content Management System) — dual-layer monolith
**Key Characteristics:**
- Two distinct application layers: public frontend and admin panel
- Namespace-based class autoloading (no Composer PSR-4, custom autoloader)
- Factory (Model) + Controls (Controller) + View separation per layer
- Medoo ORM for all database operations
- Apache `.htaccess` URL rewriting for routing
- Template engine (`Tpl` class) for view rendering with PHP template files
- Plugin hook system for extensibility without modifying core
## Layers
**Frontend Layer** (`front` namespace):
- Purpose: Serve public website to visitors
- Contains: Route handlers, page rendering, form processing
- Controls: `autoload/front/controls/` — URL parsing, request dispatch
- Factory: `autoload/front/factory/` — database queries, data retrieval
- View: `autoload/front/view/` — HTML generation
- Templates: `templates/`, `templates_user/` (user overrides take precedence)
- Entry: `index.php`
**Admin Panel Layer** (`admin` namespace):
- Purpose: CMS content management interface for editors
- Contains: CRUD operations for all content types, user management
- Controls: `autoload/admin/controls/` — admin action handlers
- Factory: `autoload/admin/factory/` — admin database operations
- View: `autoload/admin/view/` — admin UI rendering
- Templates: `admin/templates/` organized by module (articles, pages, users, etc.)
- Entry: `admin/index.php`
**Core/Shared Layer** (root `autoload/`):
- Purpose: Utilities and helpers shared by both layers
- Key classes:
- `autoload/class.S.php` — static helpers (1328 lines): images, cache, sessions, email, DB utils
- `autoload/class.Tpl.php` — template engine (loads/renders PHP template files)
- `autoload/class.Cache.php` — session-based caching
- `autoload/class.Html.php` — HTML generation helpers
- `autoload/class.Image.php` — image processing (WebP conversion)
**Database Layer:**
- Medoo ORM (`libraries/medoo/medoo.php`) — all DB access
- MySQL with `pp_` prefixed tables (~32 tables)
- Configuration in `config.php`
## Data Flow
**Frontend Page Request:**
1. HTTP request hits Apache — `.htaccess` rewrites URL to `index.php` query params
2. `index.php` — initializes autoloader, session, Medoo DB instance, loads `config.php`
3. `\front\controls\Site::check_url_params()` — parses `?a=` (action) and `?id=` (resource ID)
4. Language loaded from session (`current-lang`), global settings from `pp_settings`
5. Page determined from `pp_pages` and `pp_layouts` tables
6. `\front\view\Site::show()` — assembles layout HTML
7. Layout HTML has placeholders (`[MENU:id]`, `[ARTYKULY:id]`, `[KONTENER:id]`) replaced at runtime
8. `Tpl::view()` renders PHP template files into final HTML
9. Optional: page-level cache stored/served, WebP images generated
**Admin Panel Request:**
1. Request hits `admin/index.php``.htaccess` routes `/admin/module/action/`
2. Session check + optional cookie-based auto-login
3. `\admin\factory\Users::check_privileges()` — access control verification
4. Route parsed: module and action determine which class/method to call
5. Factory methods perform DB operations (Medoo queries)
6. Grid library or `Tpl::view()` renders response
**AJAX Request:**
1. `ajax.php` (frontend) or `admin/ajax.php` (admin) receives request
2. `?a=action` parameter dispatches to appropriate handler
3. Returns JSON response
4. Examples: `contact_form`, `cookie_close`, `inline-edit-save`, `pixieset_*`
**State Management:**
- Session-based: language preference, admin auth, inline-edit mode (`front-devel`)
- Database: all persistent content state
- File cache: WebP images in `cache/` directory
- Session cache: page data via `\Cache` class
## Key Abstractions
**Factory (Model):**
- Purpose: Database operations for a content domain
- Pattern: Static methods on classes (not instantiated)
- Location: `autoload/front/factory/class.*.php`, `autoload/admin/factory/class.*.php`
- Examples: `\admin\factory\Articles`, `\front\factory\Newsletter`
- Methods: `article_details()`, `articles_list()`, `article_save()`, `article_delete()`
**Controls (Controller):**
- Purpose: Handle requests, validate input, call factories, pass to views
- Pattern: Static methods, namespaced by layer
- Location: `autoload/front/controls/class.*.php`, `autoload/admin/controls/class.*.php`
**View:**
- Purpose: Generate HTML for frontend or admin
- Pattern: Static methods that load templates via `Tpl::view()`
- Location: `autoload/front/view/class.*.php`, `autoload/admin/view/class.*.php`
**Template System:**
- `Tpl::view()` — loads PHP template file, passes variables, captures output
- Fallback: `templates_user/` (custom) overrides `templates/` (default)
- Layout placeholders: `[MENU:id]`, `[ARTYKULY:id]`, `[KONTENER:id]`, `[BANERY]`, `[NEWSLETTER]`, `[WIDGET_TELEFON]`, `[MAPA]...[/MAPA]`
**Plugin Hooks:**
- `plugins/special-actions.php` — early hooks
- `plugins/special-actions-middle.php` — contact forms, file uploads, reCAPTCHA
- `plugins/special-actions-end.php` — late hooks
## Entry Points
**Frontend:**
- `index.php` — primary public entry point; bootstraps app, calls `\front\view\Site::show()`
- `ajax.php` — AJAX handler for contact forms, cookie consent, gallery actions, inline editing
**Admin Panel:**
- `admin/index.php` — admin entry; handles auth, routes to admin controls/views
- `admin/ajax.php` — admin AJAX handler
**API:**
- `api/contact_map.php` — JSON API for contact/location map data
- `download.php` — secure file download for article attachments
- `get_file.php` — PDF/document download wrapper
## Error Handling
**Strategy:** Inconsistent — errors largely suppressed rather than handled
**Patterns:**
- `error_reporting(0)` in `admin/ajax.php`, `admin/index.php` — all errors silenced
- `error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT ^ E_WARNING ^ E_DEPRECATED)` in frontend entry points
- No try/catch blocks in most factory methods
- No global exception handler
- Failed DB operations silently return `null` or empty array
## Cross-Cutting Concerns
**Caching:**
- `\Cache::fetch()` / `\Cache::store()` — session-based page data cache
- `\S::delete_cache()` — invalidates cache on content changes
- WebP image generation + file caching in `cache/`
**Multi-language:**
- All content tables have `_langs` counterpart (e.g., `pp_articles_langs`, `pp_pages_langs`)
- Language ID loaded per request from session and `pp_langs` table
- Language strings managed in `pp_langs_translations`
**Inline Editing (Developer Mode):**
- When `front-devel` session is set, pages render with `contenteditable="true"`
- Saves edits back to `pp_layouts.html` via `ajax.php?a=inline-edit-save`
**Authentication:**
- Admin only — no frontend user auth
- Session-based with IP validation
- Cookie-based "remember me" with auto-login
- Privilege system: `pp_users_privileges` junction table
---
*Architecture analysis: 2026-05-05*
*Update when major patterns change*