- 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>
6.9 KiB
6.9 KiB
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
.htaccessURL rewriting for routing - Template engine (
Tplclass) 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 utilsautoload/class.Tpl.php— template engine (loads/renders PHP template files)autoload/class.Cache.php— session-based cachingautoload/class.Html.php— HTML generation helpersautoload/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:
- HTTP request hits Apache —
.htaccessrewrites URL toindex.phpquery params index.php— initializes autoloader, session, Medoo DB instance, loadsconfig.php\front\controls\Site::check_url_params()— parses?a=(action) and?id=(resource ID)- Language loaded from session (
current-lang), global settings frompp_settings - Page determined from
pp_pagesandpp_layoutstables \front\view\Site::show()— assembles layout HTML- Layout HTML has placeholders (
[MENU:id],[ARTYKULY:id],[KONTENER:id]) replaced at runtime Tpl::view()renders PHP template files into final HTML- Optional: page-level cache stored/served, WebP images generated
Admin Panel Request:
- Request hits
admin/index.php—.htaccessroutes/admin/module/action/ - Session check + optional cookie-based auto-login
\admin\factory\Users::check_privileges()— access control verification- Route parsed: module and action determine which class/method to call
- Factory methods perform DB operations (Medoo queries)
- Grid library or
Tpl::view()renders response
AJAX Request:
ajax.php(frontend) oradmin/ajax.php(admin) receives request?a=actionparameter dispatches to appropriate handler- Returns JSON response
- 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
\Cacheclass
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) overridestemplates/(default) - Layout placeholders:
[MENU:id],[ARTYKULY:id],[KONTENER:id],[BANERY],[NEWSLETTER],[WIDGET_TELEFON],[MAPA]...[/MAPA]
Plugin Hooks:
plugins/special-actions.php— early hooksplugins/special-actions-middle.php— contact forms, file uploads, reCAPTCHAplugins/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/viewsadmin/ajax.php— admin AJAX handler
API:
api/contact_map.php— JSON API for contact/location map datadownload.php— secure file download for article attachmentsget_file.php— PDF/document download wrapper
Error Handling
Strategy: Inconsistent — errors largely suppressed rather than handled
Patterns:
error_reporting(0)inadmin/ajax.php,admin/index.php— all errors silencederror_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
nullor 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
_langscounterpart (e.g.,pp_articles_langs,pp_pages_langs) - Language ID loaded per request from session and
pp_langstable - Language strings managed in
pp_langs_translations
Inline Editing (Developer Mode):
- When
front-develsession is set, pages render withcontenteditable="true" - Saves edits back to
pp_layouts.htmlviaajax.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_privilegesjunction table
Architecture analysis: 2026-05-05 Update when major patterns change