7 dokumentów w .paul/codebase/ — overview, stack, architecture, conventions, testing, integrations, concerns (CRITICAL→LOW). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.1 KiB
6.1 KiB
Architecture
Generated: 2026-04-26
Overview
cmsPRO uses a 3-layer architecture with clean admin/frontend separation:
Request
↓
Controls (admin\controls\ or front\controls\) ← request handling
↓
Factories (admin\factory\ or front\factory\) ← DEPRECATED wrappers → will be removed
↓
Domain Repositories (Domain\*\*Repository) ← data access (new pattern)
↓
Medoo ORM → MySQL
Views are rendered through admin\view\* / front\view\* → Shared\Tpl\Tpl → Savant3 templates.
Directory Map
autoload/
├── autoloader.php Hybrid PSR-4 + legacy autoloader
├── class.S.php Global helper facade (deprecated wrapper)
├── class.Article.php Legacy entity (ArrayAccess)
├── class.Page.php Legacy entity
├── class.Scontainer.php Legacy entity
├── class.Cache.php / class.Cron.php / class.Image.php / class.Html.php
│
├── Domain/ NEW — Repository pattern, DDD
│ ├── Articles/ArticlesRepository.php (648 lines)
│ ├── Authors/AuthorsRepository.php (156 lines)
│ ├── Banners/BannersRepository.php (148 lines)
│ ├── Languages/LanguagesRepository.php (213 lines)
│ ├── Layouts/LayoutsRepository.php (123 lines)
│ ├── Newsletter/NewsletterRepository.php (281 lines)
│ ├── Pages/PagesRepository.php (451 lines)
│ ├── Scontainers/ScontainersRepository.php (110 lines)
│ ├── Settings/SettingsRepository.php (73 lines)
│ └── User/UserRepository.php (235 lines)
│
├── Shared/ Cross-cutting services
│ ├── Helpers/Helpers.php God class — 1220 lines (⚠ needs splitting)
│ ├── Tpl/Tpl.php Template renderer (checks templates_user/ first)
│ ├── Email/Email.php Email service (wraps PHPMailer)
│ ├── Cache/CacheHandler.php File-based cache (gzdeflate, TTL)
│ ├── Security/CsrfToken.php CSRF token generation + validation
│ ├── Html/Html.php HTML form element builder
│ └── Image/ImageManipulator.php Image processing
│
├── admin/
│ ├── class.Site.php Admin routing + 2FA
│ ├── controls/class.*.php 18 request handler classes (static methods)
│ ├── factory/class.*.php 18 @deprecated wrappers
│ └── view/class.*.php 14 template renderer classes
│
└── front/
├── controls/class.Site.php Main frontend router
├── controls/class.*.php 4 frontend controllers
├── factory/class.*.php 17 frontend factories
└── view/class.*.php View renderers
admin/
├── index.php Admin entry point (IP check, session, routing)
├── ajax.php Admin AJAX dispatcher → admin/ajax/*.php
└── templates/ Admin Savant3 templates (per module)
templates/ Frontend Savant3 templates
templates_user/ User-overridable template overrides
plugins/
├── special-actions.php Hook: pre-routing
├── special-actions-middle.php Hook: mid-request
└── special-actions-end.php Hook: post-rendering
Namespace Convention
| Namespace | Path | Convention |
|---|---|---|
admin\controls\ |
autoload/admin/controls/class.*.php |
Legacy lowercase |
admin\factory\ |
autoload/admin/factory/class.*.php |
Legacy, @deprecated |
admin\view\ |
autoload/admin/view/class.*.php |
Legacy lowercase |
front\controls\ |
autoload/front/controls/class.*.php |
Legacy lowercase |
front\factory\ |
autoload/front/factory/class.*.php |
Legacy lowercase |
Domain\*\ |
autoload/Domain/*/ClassName.php |
PSR-4 PascalCase |
Shared\*\ |
autoload/Shared/*/ClassName.php |
PSR-4 PascalCase |
Key Patterns
Repository Pattern (Domain layer)
class ArticlesRepository {
public function __construct($db) { $this->db = $db; }
public function find(int $id): ?array { ... }
public function save(...): int { ... }
}
Factory Wrapper (deprecated bridge)
/** @deprecated Używaj Domain\Articles\ArticlesRepository przez DI */
class Articles {
private static function repo(): ArticlesRepository {
global $mdb;
return new ArticlesRepository($mdb);
}
public static function article_delete($id): bool {
return self::repo()->deleteArticle($id);
}
}
Controls (request handler)
class Articles {
public static function article_delete() {
global $user;
if (!admin\factory\Users::check_privileges('articles', $user['id']))
return \S::alert('Brak uprawnień');
// delegate to factory → repository
}
}
Global Helper Facade
// class.S.php — calls Shared\Helpers\Helpers via __callStatic
\S::get('param') // → Helpers::get()
\S::delete_cache() // → Helpers::delete_cache()
Admin Routing
GET /admin/?a=articles&action=view_list → admin\controls\Articles::view_list()
Routing in admin/index.php: reads $_GET['a'] → dynamically loads control class → calls action method.
Frontend Routing
index.php → front\controls\Site::route() — checks \S::get('search'), \S::get('tag'), \S::get('article'), then falls through to page rendering by page_type.
Caching Strategy
| Cache Type | Location | Engine |
|---|---|---|
| Page cache | cache/ |
Full HTML output |
| Object cache | temp/md5[0]/md5[1]/ |
gzdeflate + serialize, TTL |
| WebP images | cache/ |
Filesystem |
| Language strings | $_SESSION |
PHP session |
Plugin System
3 hook points in frontend lifecycle (files in plugins/ directory, included if they exist):
special-actions.php— after language init, before routingspecial-actions-middle.php— before cache checkspecial-actions-end.php— before final output