141 lines
5.5 KiB
Markdown
141 lines
5.5 KiB
Markdown
# Architecture
|
|
|
|
**Analysis Date:** 2026-04-27
|
|
|
|
## Pattern Overview
|
|
|
|
**Overall:** Custom PHP MVC Monolith (dual frontend — public + admin)
|
|
|
|
**Key Characteristics:**
|
|
- Single shared `core/` layer powering both public and admin frontends
|
|
- Front Controller routing via Apache rewrite → `index.php` → Router → Controller
|
|
- All templating via Smarty (no JSON API, no SPA)
|
|
- Session-based admin auth; anonymous public form with reCAPTCHA
|
|
|
|
## Layers
|
|
|
|
**Router / Front Controller:**
|
|
- Purpose: Parse URL, select controller and action
|
|
- Contains: `Router.class.php`, `index.php` entry points
|
|
- Location: `_rejestracja/index.php`, `_rejestracja/Admin/index.php`
|
|
- Depends on: Core class loader
|
|
- Used by: Nothing (entry point)
|
|
|
|
**Controller Layer:**
|
|
- Purpose: Handle request lifecycle — auth, business logic dispatch, template assignment
|
|
- Contains: `*Controller.php` files; each has `preDispatch`, `{Name}Action`, `postDispatch`
|
|
- Location: `_rejestracja/controller/` (public), `_rejestracja/Admin/controller/`
|
|
- Depends on: DAL layer, Smarty, SessionProxy, Request
|
|
- Used by: Router
|
|
|
|
**DAL Layer (Data Access):**
|
|
- Purpose: Typed database access; maps rows to model objects
|
|
- Contains: `Mf{Entity}DAL.class.php` files, `DefaultDAL.class.php` base
|
|
- Location: `_rejestracja/core/model/`
|
|
- Depends on: MySQL connection, `DalData` query config objects, `DataObject` base model
|
|
- Used by: Controllers
|
|
|
|
**Model Layer:**
|
|
- Purpose: Typed domain objects with getters/setters
|
|
- Contains: `Mf{Entity}.class.php` with `$fields` array mapping DB columns to properties
|
|
- Location: `_rejestracja/core/model/`
|
|
- Depends on: `DataObject.class.php` base
|
|
- Used by: DAL (hydration), Controllers, Templates (via Smarty assigns)
|
|
|
|
**Template Layer:**
|
|
- Purpose: HTML rendering via Smarty
|
|
- Contains: `.tpl` files, Smarty plugins (`{translate}`, `{formField}`, `{url}`, `{dropDownContainer}`)
|
|
- Location: `_rejestracja/template/`, `_rejestracja/Admin/template/`
|
|
- Depends on: Variables assigned in controller (`$this->smarty->assign(...)`)
|
|
- Used by: Nothing (output layer)
|
|
|
|
## Data Flow
|
|
|
|
**Public Registration Request:**
|
|
|
|
1. Browser `POST /_rejestracja/index` → Apache rewrite → `_rejestracja/index.php`
|
|
2. `Router` parses URL → selects `IndexController`
|
|
3. `IndexController::preDispatch()` sets up shared context (Smarty, layout)
|
|
4. `IndexController::IndexAction()` runs:
|
|
- Validates reCAPTCHA
|
|
- Reads POST via `Request::GetPost()`
|
|
- Hydrates `MfParticipant` model
|
|
- Calls `MfParticipantDAL::Save($obj)` → INSERT/UPDATE
|
|
- Sends confirmation email via PHPMailer
|
|
- `$this->smarty->assign(...)` + Smarty renders confirmation template
|
|
5. HTML response returned to browser
|
|
|
|
**Admin Registration List Request:**
|
|
|
|
1. Browser `GET /_rejestracja/Admin/Calc/Reg` → `Admin/index.php` → Router
|
|
2. `CalcController::preDispatch()` — calls `RunShared('Auth', $param)` (session check)
|
|
3. `CalcController::RegAction()`:
|
|
- `MfParticipantDAL::GetResult($dalData)` with sort DESC
|
|
- `$this->smarty->assign('arrayObj', $arrayObjReg)`
|
|
4. Smarty renders `Admin/template/partial/Calc/Reg.tpl`
|
|
|
|
**State Management:**
|
|
- PHP sessions via `SessionProxy` for admin auth and transient UI state
|
|
- No in-memory cache; every request hits MySQL
|
|
|
|
## Key Abstractions
|
|
|
|
**DataObject / Model:**
|
|
- Purpose: Typed domain objects with `$fields` array auto-mapping DB↔PHP
|
|
- Examples: `MfParticipant`, `MfParameters`, `MfDictionary`
|
|
- Pattern: Active-record-lite; `$fields = ['db_col' => 'PropName']`, auto-generates getters/setters via `__get`/`__set` or explicit methods
|
|
|
|
**DefaultDAL / DalData:**
|
|
- Purpose: Generic CRUD over MySQL; `DalData` is a query config object (conditions, sort, limit)
|
|
- Examples: `MfParticipantDAL`, `MfParametersDAL`, `MfDictionaryDAL`
|
|
- Pattern: `GetDalDataObj()` → configure → `GetResult()` / `GetById()` / `Save()` / `Delete()`
|
|
|
|
**Smarty Plugin Suite:**
|
|
- Purpose: Template-level abstractions for common patterns
|
|
- Key plugins: `{translate word='key'}` (dictionary lookup), `{formField name="" type=""}` (form inputs — text/hidden only), `{url label=X}` (router-aware URL generation), `{dropDownContainer}` (collapsible admin sections)
|
|
- Pattern: Custom Smarty plugins registered in `_rejestracja/core/`
|
|
|
|
## Entry Points
|
|
|
|
**Public Frontend:**
|
|
- Location: `_rejestracja/index.php`
|
|
- Triggers: HTTP request to `/_rejestracja/`
|
|
- Responsibilities: Bootstrap core, invoke Router → Controller
|
|
|
|
**Admin Frontend:**
|
|
- Location: `_rejestracja/Admin/index.php`
|
|
- Triggers: HTTP request to `/_rejestracja/Admin/`
|
|
- Responsibilities: Same bootstrap + admin-specific auth via `RunShared('Auth')`
|
|
|
|
## Error Handling
|
|
|
|
**Strategy:** Mostly unhandled — exceptions catch in isolated blocks, errors logged to PHP error_log
|
|
|
|
**Patterns:**
|
|
- `try/catch` in `RegDeleteAction` (DAL delete errors logged but swallowed)
|
|
- `Validator` class collects field errors and returns them to template via `$out` array
|
|
- No global exception handler observed
|
|
|
|
## Cross-Cutting Concerns
|
|
|
|
**Logging:**
|
|
- PHP `error_log` only; `Utils::ArrayDisplay()` for dev debug (should be removed pre-deploy)
|
|
|
|
**Validation:**
|
|
- `Validator` class at controller level for required-field checks
|
|
- reCAPTCHA for bot protection on public form
|
|
- No input sanitization layer beyond Smarty auto-escaping in templates
|
|
|
|
**Authentication:**
|
|
- Admin: `RunShared('Auth', $param)` in every admin controller `preDispatch`
|
|
- Public: None (anonymous registration form)
|
|
|
|
**Internationalization:**
|
|
- `{translate word='key'}` Smarty plugin reads from `mf_dictionary` table
|
|
- All visible strings for the registration form are dictionary-backed
|
|
|
|
---
|
|
|
|
*Architecture analysis: 2026-04-27*
|
|
*Update when major patterns change*
|