# 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*