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>
This commit is contained in:
168
.paul/codebase/architecture.md
Normal file
168
.paul/codebase/architecture.md
Normal file
@@ -0,0 +1,168 @@
|
||||
# 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*
|
||||
188
.paul/codebase/concerns.md
Normal file
188
.paul/codebase/concerns.md
Normal file
@@ -0,0 +1,188 @@
|
||||
# Codebase Concerns
|
||||
|
||||
**Analysis Date:** 2026-05-05
|
||||
|
||||
## Security Considerations
|
||||
|
||||
**Hardcoded database credentials in version control:**
|
||||
- Risk: Database password and host exposed in repository; any repo access = DB access
|
||||
- Files: `config.php` (primary), also required in `ajax.php`, `admin/ajax.php`, `admin/index.php`, `download.php`, `api/contact_map.php`, `index.php`
|
||||
- Current mitigation: None
|
||||
- Fix: Move to `.env` file, add `.env` to `.gitignore`, create `.env.example`
|
||||
|
||||
**Hardcoded Google reCAPTCHA secret key:**
|
||||
- Risk: Secret key `6Lfaovgl...` hardcoded and repeated 8 times in one file
|
||||
- Files: `plugins/special-actions-middle.php` (lines ~242, 296, 453, 531, 602, 679, 745)
|
||||
- Current mitigation: None
|
||||
- Fix: Move to config/settings, extract to single constant or `pp_settings` entry
|
||||
|
||||
**MD5 password hashing:**
|
||||
- Risk: MD5 is cryptographically broken — rainbow table attacks trivial
|
||||
- Files: `autoload/admin/factory/class.Users.php`, `autoload/admin/class.Site.php`
|
||||
- Current mitigation: None
|
||||
- Fix: Replace with `password_hash()` (bcrypt) + `password_verify()`
|
||||
|
||||
**PHP object injection via `unserialize()` on cookie data:**
|
||||
- Risk: Attacker-controlled cookie triggers PHP object injection / RCE
|
||||
- Files: `admin/ajax/pages.php` (`unserialize($_COOKIE['cookie_menus'])`, `unserialize($_COOKIE['cookie_pages'])`)
|
||||
- Also in: `admin/templates/articles/article-edit.php`, `admin/templates/layouts/layout-edit.php`, `admin/templates/pages/pages-list.php`, `admin/templates/pages/pages-browse-list.php`
|
||||
- Current mitigation: None
|
||||
- Fix: Replace with `json_decode()` for cookie state storage
|
||||
|
||||
**Path traversal in file download:**
|
||||
- Risk: Arbitrary file read — attacker can request any file on server
|
||||
- Files: `get_file.php` (no validation on `$_GET['fileUrl']` before `readfile()`)
|
||||
- Current mitigation: None
|
||||
- Fix: Whitelist allowed paths, validate against upload directory only
|
||||
|
||||
**File upload without MIME type validation:**
|
||||
- Risk: Executable files (`.php`) may be uploaded with double extension bypass
|
||||
- Files: `plugins/special-actions-middle.php` (lines ~313-316, `move_uploaded_file()` with unsanitized `$_FILES['files']['name']`)
|
||||
- Current mitigation: Extension check only (bypassable)
|
||||
- Fix: Validate MIME type via `finfo_file()`, restrict upload directory execution, add file size limits
|
||||
|
||||
**SQL injection risk via string concatenation:**
|
||||
- Risk: Direct variable injection into SQL strings (not all queries use Medoo parameterization)
|
||||
- Files:
|
||||
- `autoload/front/factory/class.Languages.php:19` — `domain` parameter in raw SQL
|
||||
- `autoload/admin/factory/class.Pages.php:353` — `lang` variable in raw SQL
|
||||
- `autoload/admin/factory/class.Articles.php:149,163,181` — multiple concatenations
|
||||
- Current mitigation: Medoo handles most queries safely; raw SQL in edge cases
|
||||
- Fix: Replace raw SQL with Medoo parameterized queries throughout
|
||||
|
||||
**User input echoed without `htmlspecialchars()`:**
|
||||
- Risk: XSS (Cross-Site Scripting) in email confirmations and form outputs
|
||||
- Files: `ajax.php:64,82-84`, `plugins/special-actions-middle.php:253-256`
|
||||
- Current mitigation: None
|
||||
- Fix: Apply `htmlspecialchars($value, ENT_QUOTES)` before output
|
||||
|
||||
## Tech Debt
|
||||
|
||||
**No environment configuration separation:**
|
||||
- Issue: Single `config.php` used for dev and production; no `.env` pattern
|
||||
- Files: `config.php` and all entry points that require it
|
||||
- Impact: Credentials hardcoded, can't safely commit config, no staging/prod separation
|
||||
- Fix: Adopt `.env` pattern with `vlucas/phpdotenv` or equivalent
|
||||
|
||||
**God object `class.S.php`:**
|
||||
- Issue: 1328-line class handling images, caching, sessions, email, DB utilities — no single responsibility
|
||||
- Files: `autoload/class.S.php`
|
||||
- Impact: Hard to test, hard to modify, used everywhere so any bug is widespread
|
||||
- Fix: Gradually extract into dedicated service classes (`ImageService`, `CacheService`, `EmailService`)
|
||||
|
||||
**Duplicate reCAPTCHA verification logic:**
|
||||
- Issue: reCAPTCHA verification code copy-pasted 8+ times instead of a shared function
|
||||
- Files: `plugins/special-actions-middle.php` (lines 230-809, repeated blocks)
|
||||
- Impact: Any bug fix requires 8 changes; any key rotation requires 8 updates
|
||||
- Fix: Extract to `verify_recaptcha($response)` function called once per form
|
||||
|
||||
**Error suppression instead of error handling:**
|
||||
- Issue: `error_reporting(0)` silences all errors; no logging to file or monitoring
|
||||
- Files: `admin/ajax.php:2`, `admin/index.php:14`
|
||||
- Impact: Silent failures, impossible to debug production issues
|
||||
- Fix: Implement proper error logging (`error_log()` or PSR-3 logger), use try/catch in DB operations
|
||||
|
||||
**Mixed concerns in templates:**
|
||||
- Issue: Business logic and data manipulation embedded in template PHP files
|
||||
- Files: `admin/templates/articles/article-edit.php` (1143 lines), `admin/templates/pages/page-edit.php`
|
||||
- Impact: Hard to maintain, duplicate logic between templates and factory classes
|
||||
- Fix: Move all logic to controls/factory, pass pre-computed variables to templates
|
||||
|
||||
**Deprecated function usage:**
|
||||
- Issue: `mime_content_type()` deprecated since PHP 5.3
|
||||
- Files: `autoload/class.S.php:37`
|
||||
- Fix: Replace with `finfo_file()`
|
||||
|
||||
## Performance Bottlenecks
|
||||
|
||||
**Large data file loaded at runtime:**
|
||||
- Problem: `wojewodztwa.php` is 6548 lines of PHP arrays — loaded entirely for any request needing province data
|
||||
- Files: `wojewodztwa.php`
|
||||
- Cause: Static data embedded in PHP instead of database or JSON
|
||||
- Fix: Move to `pp_provinces` table or JSON file with lazy loading
|
||||
|
||||
**Template placeholder replacement:**
|
||||
- Problem: Layout HTML scanned for all placeholder patterns on every page request
|
||||
- Files: `autoload/front/view/class.Site.php`
|
||||
- Cause: String replacement for `[MENU:id]`, `[ARTYKULY:id]`, etc. on each render
|
||||
- Improvement: Page caching (already implemented as opt-in, ensure enabled for high-traffic pages)
|
||||
|
||||
**WebP image generation:**
|
||||
- Problem: WebP conversion happens on-demand per request (not pre-generated)
|
||||
- Files: `autoload/class.Image.php`, `autoload/class.S.php`
|
||||
- Cause: No background job system for image processing
|
||||
- Impact: First request for each image is slow; cache/ fills over time
|
||||
- Improvement: Pre-generate WebP on upload
|
||||
|
||||
## Fragile Areas
|
||||
|
||||
**Plugin hook file `special-actions-middle.php`:**
|
||||
- Files: `plugins/special-actions-middle.php` (very large file with 8+ contact form handlers)
|
||||
- Why fragile: Monolithic — all contact forms, reCAPTCHA, file uploads in one file; no shared validation
|
||||
- Common failures: Adding a new form variant requires duplicating entire handler block
|
||||
- Safe modification: Extract shared validation/email logic before adding new variants
|
||||
|
||||
**Template override system:**
|
||||
- Files: `autoload/class.Tpl.php`, `templates/`, `templates_user/`
|
||||
- Why fragile: Silent fallback from `templates_user/` to `templates/` — easy to edit wrong file
|
||||
- Common failures: Edit `templates/` file thinking it's active, but `templates_user/` override takes precedence
|
||||
- Safe modification: Always check both directories; `templates_user/` takes precedence
|
||||
|
||||
**Admin session / cookie auto-login:**
|
||||
- Files: `admin/index.php` (lines 36-84)
|
||||
- Why fragile: IP-based session validation can lock out admin on IP change; cookie auto-login not encrypted
|
||||
- Common failures: Admin locked out after ISP IP change
|
||||
- Safe modification: Test login flow after any changes to session handling
|
||||
|
||||
## Dependencies at Risk
|
||||
|
||||
**jQuery 1.11.1 (admin panel):**
|
||||
- Risk: EOL since 2016; known XSS vulnerabilities
|
||||
- Impact: Admin panel DOM manipulation, CKEditor compatibility
|
||||
- Files: `admin/templates/site/main-layout.php`
|
||||
- Migration: Upgrade to jQuery 3.x (breaking changes in `.live()`, `.size()` etc.)
|
||||
|
||||
**CKEditor (version unknown):**
|
||||
- Risk: Older CKEditor 4.x versions have known XSS vulnerabilities
|
||||
- Files: `libraries/ckeditor/`
|
||||
- Migration: Audit version, update to latest CKEditor 4 LTS or migrate to CKEditor 5
|
||||
|
||||
**Medoo (version unknown, likely 1.x):**
|
||||
- Risk: Medoo 1.x API differs significantly from 2.x; unmaintained in 1.x branch
|
||||
- Files: `libraries/medoo/medoo.php`
|
||||
- Migration: Audit API usage before upgrading to Medoo 2.x
|
||||
|
||||
## Missing Critical Features
|
||||
|
||||
**No environment configuration:**
|
||||
- Problem: No way to run app locally without overwriting production credentials
|
||||
- Blocks: Safe local development, CI/CD setup, multi-developer workflow
|
||||
- Complexity: Low — add `.env` loading at top of `config.php`
|
||||
|
||||
**No error logging / monitoring:**
|
||||
- Problem: Production errors are silently swallowed
|
||||
- Blocks: Debugging production issues, alerting on failures
|
||||
- Complexity: Low — configure `error_log()` to file + optional email alert
|
||||
|
||||
**No CSRF protection:**
|
||||
- Problem: All forms lack CSRF token validation
|
||||
- Blocks: Prevents CSRF attacks on contact/newsletter/admin forms
|
||||
- Complexity: Medium — add token generation + validation middleware
|
||||
|
||||
**No automated tests:**
|
||||
- Problem: Zero test coverage — no regression safety net for changes
|
||||
- Blocks: Refactoring, safe dependency upgrades, CI/CD
|
||||
- Complexity: High — requires setting up PHPUnit, test DB, writing tests from scratch
|
||||
|
||||
## Test Coverage Gaps
|
||||
|
||||
**Entire codebase:**
|
||||
- What's not tested: Everything — factory methods, controls, views, AJAX handlers
|
||||
- Risk: Any change could break functionality silently
|
||||
- Priority: High for security-sensitive paths (auth, file uploads, SQL queries)
|
||||
- Difficulty: High — no test infrastructure exists; factory methods use static Medoo instance
|
||||
|
||||
---
|
||||
|
||||
*Concerns audit: 2026-05-05*
|
||||
*Update as issues are fixed or new ones discovered*
|
||||
127
.paul/codebase/conventions.md
Normal file
127
.paul/codebase/conventions.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# Coding Conventions
|
||||
|
||||
**Analysis Date:** 2026-05-05
|
||||
|
||||
## Naming Patterns
|
||||
|
||||
**PHP Class Files:**
|
||||
- Pattern: `class.ClassName.php` (PascalCase class name)
|
||||
- Examples: `class.Articles.php`, `class.Authors.php`, `class.Users.php`
|
||||
- Namespace mirrors directory path: `autoload/admin/factory/class.Articles.php` → `namespace admin\factory;`
|
||||
|
||||
**PHP Functions & Variables:**
|
||||
- Functions: `snake_case` exclusively (`duplicate_article()`, `gallery_order_save()`, `article_save()`)
|
||||
- Variables: `snake_case` (`$article_id`, `$image_id`, `$output_file`, `$file_type`)
|
||||
- Class properties: `snake_case` (`$this->article['languages']`)
|
||||
|
||||
**CSS/HTML:**
|
||||
- CSS classes: `kebab-case` (`.sidebar-menu`, `.menu-left`, `.google-title`)
|
||||
- No BEM methodology — flat class names with some nesting
|
||||
|
||||
**SCSS Variables:**
|
||||
- Colors: `$c` prefix + PascalCase (`$cWhite`, `$cBlack`, `$cGrayDarkBg`, `$cYellow`)
|
||||
- Fonts: `$f` prefix (`$font1`, `$font2`, `$font3`, `$fLeagueSpartan`)
|
||||
- Defined in: `layout/style-scss/_variables.scss`
|
||||
|
||||
**JavaScript:**
|
||||
- Variables: camelCase
|
||||
- Functions: camelCase
|
||||
- jQuery patterns throughout: `$(document).ready()`, `$('body').on(event, selector, handler)`
|
||||
|
||||
**Templates:**
|
||||
- PHP templates: `kebab-case` in directory/feature structure
|
||||
- Examples: `article-edit.php`, `articles-browse-list.php`, `page-contact-v5.php`
|
||||
|
||||
**Database Tables:**
|
||||
- Prefix: `pp_` on all tables
|
||||
- Pattern: `pp_[module]` and `pp_[module]_[subresource]`
|
||||
- Examples: `pp_articles`, `pp_articles_langs`, `pp_articles_images`
|
||||
|
||||
## Code Style
|
||||
|
||||
**PHP:**
|
||||
- Indentation: 2 spaces
|
||||
- Braces: opening brace on same line as control structure/function
|
||||
- Spaces: around operators (`=`, `==`, `!=`), within array parentheses
|
||||
- PHP tags: short tags `<?` and `?>` used in templates (not `<?php`)
|
||||
- Array formatting: multi-line with aligned assignment operators
|
||||
|
||||
**SCSS:**
|
||||
- Indentation: 2 spaces
|
||||
- Compilation directive at file top: `// out: ../style-css/style.css, compress: true, sourceMap: true`
|
||||
- Responsive mixins in `layout/style-scss/_mixins.scss` (breakpoints: xxs, xs, sm, md, lg, xl, xxl, xxxl)
|
||||
- Vendor prefixes included manually (`-webkit-`, `-moz-`)
|
||||
|
||||
**JavaScript:**
|
||||
- jQuery as primary library (not vanilla JS for DOM)
|
||||
- ES6 template literals used (`#${boxHref}`)
|
||||
- No module system — all global scope
|
||||
|
||||
**Linting:**
|
||||
- No ESLint configured
|
||||
- No Prettier configured
|
||||
- No PHP CodeSniffer
|
||||
- No StyleLint
|
||||
- Code style enforced only by convention/habit
|
||||
|
||||
## Architecture Conventions
|
||||
|
||||
**MVC Layer Separation:**
|
||||
- Controls handle requests and call factories — no direct DB queries in controls
|
||||
- Factories contain all DB queries (Medoo) — static methods
|
||||
- Views generate HTML and call `Tpl::view()` — no DB queries
|
||||
- Templates are pure HTML+PHP interpolation — minimal logic
|
||||
|
||||
**Namespace Usage:**
|
||||
- `namespace admin\controls;` / `namespace admin\factory;` / `namespace admin\view;`
|
||||
- `namespace front\controls;` / `namespace front\factory;` / `namespace front\view;`
|
||||
- Cross-layer calls use fully qualified names: `\admin\factory\Articles::duplicate_article()`
|
||||
|
||||
**Global Helpers:**
|
||||
- `\S::get()` — parameter retrieval with optional sanitization
|
||||
- `\S::alert()` — admin notification system
|
||||
- `\Html::` — HTML generation utilities
|
||||
|
||||
## Comments & Documentation
|
||||
|
||||
**Comment style:**
|
||||
- Line comments: `// comment` (mix of Polish and English)
|
||||
- Block markers: `/* sekcja */` used to label code sections
|
||||
- Examples from `autoload/admin/factory/class.Articles.php`:
|
||||
- `/* tłumaczenia */` (translations section)
|
||||
- `/* parametry bez wersji językowych */` (params without language versions)
|
||||
- `/* pliki */` (files section)
|
||||
|
||||
**Documentation:**
|
||||
- No PHPDoc blocks
|
||||
- No `@param` / `@return` / `@throws` annotations
|
||||
- No type hints in function signatures
|
||||
- Comments describe sections, not individual functions
|
||||
|
||||
## Import / Include Patterns
|
||||
|
||||
**PHP:**
|
||||
- Classes auto-loaded via custom autoloader (not Composer)
|
||||
- Libraries included directly in entry points: `require 'libraries/medoo/medoo.php'`
|
||||
- No `use` statements for namespaced imports — always fully qualified calls
|
||||
|
||||
**JavaScript:**
|
||||
- All libraries loaded via `<script>` tags in templates
|
||||
- No import/require (no module bundler)
|
||||
- Load order defined in `admin/templates/site/main-layout.php`
|
||||
|
||||
## Function Design
|
||||
|
||||
**PHP Factory methods:**
|
||||
- Static methods named after the operation: `article_save()`, `article_delete()`
|
||||
- No return type declarations
|
||||
- Return: Medoo result (array), `true`/`false`, or void
|
||||
|
||||
**AJAX Handlers:**
|
||||
- `$_POST` / `$_GET` retrieved via `\S::get()` at top of handler
|
||||
- JSON response at end: `echo json_encode($output)` and `die()`
|
||||
|
||||
---
|
||||
|
||||
*Convention analysis: 2026-05-05*
|
||||
*Update when patterns change*
|
||||
318
.paul/codebase/db_schema.md
Normal file
318
.paul/codebase/db_schema.md
Normal file
@@ -0,0 +1,318 @@
|
||||
# Database Schema
|
||||
|
||||
**Updated:** 2026-05-05 | **Total tables:** ~32 | **Engine:** MySQL InnoDB | **Prefix:** `pp_`
|
||||
|
||||
Schema inferred from Medoo ORM queries in PHP source files. No migration files found — schema managed manually.
|
||||
|
||||
---
|
||||
|
||||
## Content — Articles
|
||||
|
||||
**`pp_articles`** — Main article/content records
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `hash` | VARCHAR | Unique identifier for external reference |
|
||||
| `status` | TINYINT | Published/draft/archived |
|
||||
| `date_add` | DATETIME | Creation timestamp |
|
||||
| `views` | INT | View counter |
|
||||
| `password` | VARCHAR | Optional password protection |
|
||||
| `pixieset` | VARCHAR | Pixieset gallery identifier |
|
||||
|
||||
**`pp_articles_langs`** — Language-specific article content
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `article_id` | INT | FK → `pp_articles.id` |
|
||||
| `lang_id` | INT | FK → `pp_langs.id` |
|
||||
| `title` | VARCHAR | Article title |
|
||||
| `content` | LONGTEXT | Rich text content |
|
||||
| `seo_link` | VARCHAR | URL slug |
|
||||
| `noindex` | TINYINT | SEO noindex flag |
|
||||
|
||||
**`pp_articles_images`** — Article gallery images
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `article_id` | INT | FK → `pp_articles.id` |
|
||||
| `src` | VARCHAR | Image filename/path |
|
||||
| `o` | INT | Sort order |
|
||||
| `favorite` | TINYINT | Flagged as favorite |
|
||||
| `to_delete` | TINYINT | Soft-delete flag |
|
||||
|
||||
**`pp_articles_files`** — Downloadable file attachments
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `article_id` | INT | FK → `pp_articles.id` |
|
||||
| `src` | VARCHAR | File path |
|
||||
| `name` | VARCHAR | Display name |
|
||||
| `to_delete` | TINYINT | Soft-delete flag |
|
||||
|
||||
**`pp_articles_pages`** — Article-to-Page assignments
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `article_id` | INT | FK → `pp_articles.id` |
|
||||
| `page_id` | INT | FK → `pp_pages.id` |
|
||||
| `o` | INT | Sort order on page |
|
||||
| `status` | TINYINT | Visibility on this page |
|
||||
|
||||
**`pp_articles_tags`** — Many-to-many: Articles ↔ Tags
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `article_id` | INT | FK → `pp_articles.id` |
|
||||
| `tag_id` | INT | FK → `pp_tags.id` |
|
||||
|
||||
**`pp_articles_additional_params`** — Custom field definitions per article
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `article_id` | INT | FK → `pp_articles.id` |
|
||||
| `name` | VARCHAR | Field name |
|
||||
| `language` | VARCHAR | Language code |
|
||||
| `status` | TINYINT | Active/inactive |
|
||||
|
||||
**`pp_articles_additional_values`** — Custom field values
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `param_id` | INT | FK → `pp_articles_additional_params.id` |
|
||||
| `article_id` | INT | FK → `pp_articles.id` |
|
||||
| `value` | TEXT | Field value |
|
||||
| `language_id` | INT | FK → `pp_langs.id` |
|
||||
|
||||
---
|
||||
|
||||
## Content — Pages & Layouts
|
||||
|
||||
**`pp_pages`** — Website page hierarchy
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `menu_id` | INT | FK → `pp_menus.id` |
|
||||
| `parent_id` | INT | Self-referencing for nested pages |
|
||||
| `page_type` | VARCHAR | Type identifier |
|
||||
| `sort_type` | VARCHAR | Article sort order |
|
||||
| `status` | TINYINT | Published/hidden |
|
||||
| `start` | TINYINT | Homepage flag |
|
||||
| `o` | INT | Sort order in navigation |
|
||||
| `cache` | TINYINT | Page-level cache toggle |
|
||||
|
||||
**`pp_pages_langs`** — Page language translations
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `page_id` | INT | FK → `pp_pages.id` |
|
||||
| `lang_id` | INT | FK → `pp_langs.id` |
|
||||
| `title` | VARCHAR | Page title |
|
||||
| `seo_link` | VARCHAR | URL slug |
|
||||
|
||||
**`pp_layouts`** — Template layout containers
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `layout_id` | INT | Parent layout reference |
|
||||
| `name` | VARCHAR | Layout name |
|
||||
| `html` | LONGTEXT | Desktop HTML with `[PLACEHOLDER:id]` tags |
|
||||
| `m_html` | LONGTEXT | Mobile HTML |
|
||||
| `css` | TEXT | Inline CSS |
|
||||
| `m_css` | TEXT | Mobile inline CSS |
|
||||
| `js` | TEXT | Inline JS |
|
||||
| `m_js` | TEXT | Mobile inline JS |
|
||||
| `status` | TINYINT | Active/inactive |
|
||||
|
||||
**`pp_layouts_pages`** — Layout-to-page assignments
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `layout_id` | INT | FK → `pp_layouts.id` |
|
||||
| `page_id` | INT | FK → `pp_pages.id` |
|
||||
|
||||
---
|
||||
|
||||
## Content — Static Containers & Banners
|
||||
|
||||
**`pp_scontainers`** — Reusable static content blocks
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `status` | TINYINT | Active/inactive |
|
||||
|
||||
**`pp_scontainers_langs`** — Static container translations
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `scontainer_id` | INT | FK → `pp_scontainers.id` |
|
||||
| `lang_id` | INT | FK → `pp_langs.id` |
|
||||
| `html` | LONGTEXT | Content HTML |
|
||||
|
||||
**`pp_banners`** — Promotional banners
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `name` | VARCHAR | Banner name |
|
||||
| `status` | TINYINT | Active/inactive |
|
||||
|
||||
**`pp_banners_langs`** — Banner language versions
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `id_banner` | INT | FK → `pp_banners.id` |
|
||||
| `id_lang` | INT | FK → `pp_langs.id` |
|
||||
| `title` | VARCHAR | Banner title |
|
||||
| `content` | TEXT | Banner content/HTML |
|
||||
|
||||
---
|
||||
|
||||
## Navigation & Taxonomy
|
||||
|
||||
**`pp_menus`** — Navigation menu definitions
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `name` | VARCHAR | Menu name |
|
||||
|
||||
**`pp_tags`** — Article tags/categories
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `name` | VARCHAR | Tag name |
|
||||
|
||||
**`pp_authors`** — Article author profiles
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
|
||||
**`pp_authors_langs`** — Author translations
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `author_id` | INT | FK → `pp_authors.id` |
|
||||
| `lang_id` | INT | FK → `pp_langs.id` |
|
||||
|
||||
---
|
||||
|
||||
## Users & Access Control
|
||||
|
||||
**`pp_users`** — Admin panel users
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `login` | VARCHAR | Username |
|
||||
| `password` | VARCHAR | MD5 hash (security concern — see concerns.md) |
|
||||
| `status` | TINYINT | Active/inactive |
|
||||
| `active_to` | DATE | Account expiry date |
|
||||
| `admin` | TINYINT | Super-admin flag |
|
||||
| `error_logged_count` | INT | Failed login counter |
|
||||
|
||||
**`pp_users_privileges`** — User permission assignments
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id_user` | INT | FK → `pp_users.id` |
|
||||
| `name` | VARCHAR | Privilege name (string key) |
|
||||
|
||||
---
|
||||
|
||||
## Multi-language
|
||||
|
||||
**`pp_langs`** — Available language configurations
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `start` | TINYINT | Default language flag |
|
||||
| `domain` | VARCHAR | Domain for this language |
|
||||
| `main_domain` | VARCHAR | Primary domain |
|
||||
| `o` | INT | Sort order |
|
||||
| `status` | TINYINT | Active/inactive |
|
||||
|
||||
**`pp_langs_translations`** — UI string translations
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| Dynamic columns per language ID | VARCHAR | Translation strings |
|
||||
|
||||
---
|
||||
|
||||
## Newsletter
|
||||
|
||||
**`pp_newsletter`** — Email subscribers
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `email` | VARCHAR | Subscriber email |
|
||||
| `status` | TINYINT | Active/unsubscribed |
|
||||
|
||||
**`pp_newsletter_send`** — Sent campaign log
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `email_template_id` | INT | FK → `pp_newsletter_templates.id` |
|
||||
|
||||
**`pp_newsletter_templates`** — Email campaign templates
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
| `name` | VARCHAR | Template name |
|
||||
| `subject` | VARCHAR | Email subject |
|
||||
| `html` | LONGTEXT | Email HTML body |
|
||||
|
||||
---
|
||||
|
||||
## Contacts & Locations
|
||||
|
||||
**`pp_contacts_maps`** — Location/contact point entries
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `id` | INT | PK, AUTO_INCREMENT |
|
||||
|
||||
**`pp_contacts_maps_products`** — Product associations for locations
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `map_id` | INT | FK → `pp_contacts_maps.id` |
|
||||
| `product_id` | INT | Product reference |
|
||||
|
||||
**`pp_contacts_maps_provinces`** — Province associations for locations
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `map_id` | INT | FK → `pp_contacts_maps.id` |
|
||||
| `province_id` | INT | Province reference |
|
||||
|
||||
**`pp_contact_emails`** — Contact form submissions
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `email` | VARCHAR | Sender email |
|
||||
| `phone` | VARCHAR | Sender phone |
|
||||
| `title` | VARCHAR | Subject |
|
||||
| `mail` | TEXT | Message body |
|
||||
| `add_date` | DATETIME | Submission timestamp |
|
||||
|
||||
---
|
||||
|
||||
## SEO & Settings
|
||||
|
||||
**`pp_seo_additional`** — Per-article SEO metadata
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `article_id` | INT | FK → `pp_articles.id` |
|
||||
| `lang_id` | INT | FK → `pp_langs.id` |
|
||||
|
||||
**`pp_settings`** — Global CMS configuration (key-value store)
|
||||
| Column | Type | Notes |
|
||||
|--------|------|-------|
|
||||
| `param` | VARCHAR | Setting key (e.g., `google_map_key`, `email_host`) |
|
||||
| `value` | TEXT | Setting value |
|
||||
|
||||
---
|
||||
|
||||
## Schema Characteristics
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Engine | MySQL InnoDB |
|
||||
| Table prefix | `pp_` |
|
||||
| Soft deletes | `to_delete` column on `pp_articles_images`, `pp_articles_files` |
|
||||
| Multi-language | All content tables have `_langs` counterpart |
|
||||
| Migrations | None — schema managed manually |
|
||||
| Timestamps | `date_add` on articles; not standardized across all tables |
|
||||
|
||||
## Key Relationships
|
||||
|
||||
- **1:N** — `pp_articles` → `pp_articles_images`, `pp_articles_files`, `pp_articles_langs`
|
||||
- **N:N** — `pp_articles` ↔ `pp_tags` (via `pp_articles_tags`)
|
||||
- **N:N** — `pp_articles` ↔ `pp_pages` (via `pp_articles_pages`)
|
||||
- **Hierarchical** — `pp_pages.parent_id` self-reference for nested page tree
|
||||
- **Language join** — all content tables join `pp_langs` on `lang_id` for translation
|
||||
144
.paul/codebase/integrations.md
Normal file
144
.paul/codebase/integrations.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# External Integrations
|
||||
|
||||
**Analysis Date:** 2026-05-05
|
||||
|
||||
## APIs & External Services
|
||||
|
||||
**Maps & Geolocation:**
|
||||
- Google Maps API — interactive contact/location maps on frontend
|
||||
- Integration: JavaScript API via `https://maps.googleapis.com/maps/api/js?key=<key>`
|
||||
- Auth: API key stored in `pp_settings` table as `google_map_key`
|
||||
- Toggle: `google_maps` setting in admin settings
|
||||
- Files: `templates/site/contact.php`, `admin/templates/settings/settings.php`
|
||||
|
||||
- geoPlugin IP Geolocation — visitor IP-to-location lookup with currency detection
|
||||
- Service URL: `http://www.geoplugin.net/php.gp?ip={IP}&base_currency={CURRENCY}`
|
||||
- Library: `autoload/class.geoplugin.php`
|
||||
- No API key required (free service)
|
||||
|
||||
**Fonts & CDN Resources:**
|
||||
- Google Fonts — `https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700`
|
||||
- File: `admin/templates/site/main-layout.php`
|
||||
- Google AJAX CDN — jQuery loaded from `//ajax.googleapis.com/ajax/libs/jquery/2.1.4/`
|
||||
- File: `admin/templates/site/unlogged-layout.php`
|
||||
|
||||
**Social Media:**
|
||||
- Facebook Likebox widget — fixed sidebar widget showing Facebook feed
|
||||
- App ID: `194295077275888` (hardcoded in iframe)
|
||||
- File: `templates/site/facebook.php`
|
||||
|
||||
**Gallery:**
|
||||
- Pixieset — external photo gallery service integration
|
||||
- Features: ZIP download of gallery images, mark favorites
|
||||
- AJAX endpoints: `ajax.php?a=pixieset_*`
|
||||
- Files: `templates/articles/article-gallery.php`, `ajax.php`
|
||||
|
||||
## Data Storage
|
||||
|
||||
**Databases:**
|
||||
- MySQL 5.7+ — primary data store for all CMS content
|
||||
- Connection: credentials hardcoded in `config.php` (host, user, password, dbname)
|
||||
- Client: Medoo ORM (`libraries/medoo/medoo.php`)
|
||||
- Table prefix: `pp_` (~32 tables)
|
||||
- Migrations: None detected — schema managed manually
|
||||
|
||||
**File Storage:**
|
||||
- Local filesystem — all user uploads stored on server
|
||||
- Images: `images/` directory
|
||||
- Uploads: `upload/` directory
|
||||
- Temp files: `admin/temp/`
|
||||
- Cache/WebP: `cache/` directory
|
||||
- No cloud storage (no AWS S3, no CDN)
|
||||
|
||||
**Caching:**
|
||||
- Session-based cache via `\Cache` class (`autoload/class.Cache.php`)
|
||||
- Keys pattern: `page_details:lang:id`
|
||||
- File-based WebP image cache: `cache/` directory
|
||||
|
||||
## Authentication & Identity
|
||||
|
||||
**Auth Provider:**
|
||||
- Custom session-based authentication — no OAuth provider
|
||||
- Implementation: `admin/index.php` (session check + cookie auto-login)
|
||||
- Password storage: MD5 hashing (insecure — see concerns.md)
|
||||
- Session security: IP address validation stored in `$_SESSION`
|
||||
- Files: `autoload/admin/factory/class.Users.php`, `autoload/admin/class.Site.php`
|
||||
|
||||
**OAuth Integrations:**
|
||||
- None detected
|
||||
|
||||
## Email & Messaging
|
||||
|
||||
**SMTP Mail:**
|
||||
- PHPMailer — SMTP-based transactional email
|
||||
- Library: `libraries/phpmailer/class.phpmailer.php`, `libraries/phpmailer/class.smtp.php`
|
||||
- Config: host, port, login, password stored in `pp_settings` table
|
||||
- Settings keys: `email_host`, `email_port`, `email_login`, `email_password`
|
||||
- Function: `\S::send_email()` in `autoload/class.S.php`
|
||||
- Used for: contact forms, newsletter delivery
|
||||
|
||||
**Newsletter:**
|
||||
- Custom database-driven newsletter system (no Mailchimp/SendGrid)
|
||||
- Templates: `pp_newsletter_templates` table
|
||||
- Subscribers: `pp_newsletter` table
|
||||
- Send log: `pp_newsletter_send` table
|
||||
- Files: `autoload/front/factory/class.Newsletter.php`
|
||||
|
||||
## Analytics & Tracking
|
||||
|
||||
**Analytics:**
|
||||
- Custom code injection — third-party analytics configured via admin settings
|
||||
- Setting key: `statistic_code` (stored in `pp_settings`)
|
||||
- Injection point: before `</head>` in `index.php`
|
||||
- Supports: Google Analytics, Matomo, or any snippet
|
||||
|
||||
**Error Tracking:**
|
||||
- None detected — no Sentry, Rollbar, or similar
|
||||
|
||||
## Security
|
||||
|
||||
**CAPTCHA:**
|
||||
- Custom JavaScript captcha for contact forms
|
||||
- Library: `libraries/jquery/captcha.js`, `libraries/jquery/captcha.css`
|
||||
- Toggle: `contact_form_captcha` setting
|
||||
- File: `templates/site/contact.php`
|
||||
|
||||
- Google reCAPTCHA — used in some contact form variants
|
||||
- Secret key hardcoded in `plugins/special-actions-middle.php` (8 locations — see concerns.md)
|
||||
|
||||
## CI/CD & Deployment
|
||||
|
||||
**Hosting:**
|
||||
- Shared hosting at `serwer1574995.home.pl`
|
||||
- Deployment: FTP via VS Code extension (`.vscode/sftp.json`, `.vscode/ftp-kr.json`)
|
||||
- No automated deployment pipeline
|
||||
|
||||
**CI Pipeline:**
|
||||
- None detected — no GitHub Actions, no CI configuration
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
**Development:**
|
||||
- Required config: Database credentials in `config.php`
|
||||
- No `.env` or `.env.example` — all config hardcoded
|
||||
- FTP settings: `.vscode/sftp.json`
|
||||
|
||||
**Production:**
|
||||
- Same `config.php` used for production (no environment separation)
|
||||
- No staging environment detected
|
||||
|
||||
## Not Detected
|
||||
|
||||
- ❌ Payment gateways (Stripe, PayPal, Przelewy24)
|
||||
- ❌ SMS services (Twilio, SMSAPI)
|
||||
- ❌ Cloud storage (AWS S3, Google Cloud Storage)
|
||||
- ❌ Error tracking (Sentry, Rollbar)
|
||||
- ❌ OAuth / SSO providers
|
||||
- ❌ Redis / Memcached
|
||||
- ❌ CDN (no Cloudflare, no CloudFront)
|
||||
- ❌ Webhooks (incoming or outgoing)
|
||||
|
||||
---
|
||||
|
||||
*Integration audit: 2026-05-05*
|
||||
*Update when adding/removing external services*
|
||||
91
.paul/codebase/stack.md
Normal file
91
.paul/codebase/stack.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Technology Stack
|
||||
|
||||
**Analysis Date:** 2026-05-05
|
||||
|
||||
## Languages
|
||||
|
||||
**Primary:**
|
||||
- PHP 7.4+ - All backend logic, templates, AJAX handlers
|
||||
- HTML (via PHP templates) - Page rendering, admin UI
|
||||
|
||||
**Secondary:**
|
||||
- JavaScript / jQuery - Frontend interactivity
|
||||
- SCSS - Admin and frontend styling (compiled to CSS)
|
||||
- CSS - Compiled output + Bootstrap overrides
|
||||
|
||||
## Runtime
|
||||
|
||||
**Environment:**
|
||||
- PHP 7.4+ on Apache web server
|
||||
- Apache with `mod_rewrite` enabled (required for URL routing via `.htaccess`)
|
||||
- MySQL 5.7+ - Primary database
|
||||
|
||||
**Package Manager:**
|
||||
- None — all dependencies manually vendored in `libraries/` and `plugins/` directories
|
||||
- No Composer, npm, or yarn
|
||||
|
||||
## Frameworks
|
||||
|
||||
**Core:**
|
||||
- Custom CMS framework (cmsPro) — no external PHP framework (no Laravel, Symfony, etc.)
|
||||
- Medoo ORM 1.x — database abstraction layer (`libraries/medoo/medoo.php`)
|
||||
- Bootstrap 4.1.3 (`libraries/bootstrap-4.1.3/`) and Bootstrap 5.0 (`libraries/bootstrap-5.0/`)
|
||||
|
||||
**Testing:**
|
||||
- None detected — no PHPUnit, Jest, or any test runner configured
|
||||
|
||||
**Build/Dev:**
|
||||
- Live Sass Compiler (VS Code extension) — compiles SCSS to CSS
|
||||
- No webpack, Vite, or build pipeline
|
||||
- SCSS output directive at top of files: `// out: ../style-css/style.css, compress: true`
|
||||
|
||||
## Key Dependencies
|
||||
|
||||
**Critical:**
|
||||
- Medoo ORM — all database operations (`libraries/medoo/medoo.php`)
|
||||
- PHPMailer — SMTP email sending (`libraries/phpmailer/class.phpmailer.php`, `class.smtp.php`)
|
||||
- jQuery 1.11.1 (admin) / 2.1.4 (login page CDN) — frontend interactivity
|
||||
- CKEditor — rich text editing in admin panel (`libraries/ckeditor/`)
|
||||
|
||||
**Admin UI Libraries:**
|
||||
- Grid library (gdb) — data table component (`libraries/grid/`)
|
||||
- Select2 — enhanced dropdowns (`plugins/select2/`)
|
||||
- FancyBox — lightbox (`plugins/fancybox/`)
|
||||
- File Uploader — file upload UI (`plugins/fileuploader/`)
|
||||
- Swiper — carousels (`libraries/swiper/`)
|
||||
|
||||
**Frontend Libraries:**
|
||||
- Font Awesome 6.1.1 — icons (`libraries/font-awesome-6.1.1/`)
|
||||
- Lozad — lazy image loading (`libraries/jquery/lozad.js`)
|
||||
- jsCloudimage360 — 360° image viewer (`libraries/jsCloudimage360/`)
|
||||
- Moment.js — date formatting (`libraries/framework/vendor/plugins/moment/`)
|
||||
- DateRangePicker — date inputs (`libraries/framework/vendor/plugins/daterange/`)
|
||||
|
||||
## Configuration
|
||||
|
||||
**Environment:**
|
||||
- No `.env` files — configuration hardcoded in `config.php`
|
||||
- `config.php` — database host, user, password, database name (credentials in plain text)
|
||||
- `admin/ip.conf` — optional IP whitelist for admin panel access
|
||||
- Global site settings stored in `pp_settings` database table
|
||||
|
||||
**Build:**
|
||||
- `.vscode/settings.json` — VS Code Live Sass Compiler config
|
||||
- No tsconfig, no webpack.config, no vite.config
|
||||
|
||||
## Platform Requirements
|
||||
|
||||
**Development:**
|
||||
- Apache + PHP 7.4+ + MySQL 5.7+
|
||||
- VS Code with Live Sass Compiler extension for SCSS editing
|
||||
- FTP access configured in `.vscode/sftp.json` / `.vscode/ftp-kr.json`
|
||||
|
||||
**Production:**
|
||||
- Shared hosting at `serwer1574995.home.pl` (inferred from `config.php`)
|
||||
- Apache `.htaccess` URL rewriting
|
||||
- No Docker, no CI/CD pipeline detected
|
||||
|
||||
---
|
||||
|
||||
*Stack analysis: 2026-05-05*
|
||||
*Update after major dependency changes*
|
||||
203
.paul/codebase/structure.md
Normal file
203
.paul/codebase/structure.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# Codebase Structure
|
||||
|
||||
**Analysis Date:** 2026-05-05
|
||||
|
||||
## Directory Layout
|
||||
|
||||
```
|
||||
vidok.com/
|
||||
├── index.php # Frontend entry point
|
||||
├── ajax.php # Frontend AJAX handler
|
||||
├── config.php # Database credentials (hardcoded)
|
||||
├── download.php # Secure file download handler
|
||||
├── get_file.php # PDF/document download wrapper
|
||||
├── api/ # JSON API endpoints
|
||||
├── admin/ # Admin panel application
|
||||
│ ├── index.php # Admin entry point
|
||||
│ ├── ajax.php # Admin AJAX handler
|
||||
│ ├── css/ # Admin SCSS source files
|
||||
│ ├── style-css/ # Compiled admin CSS
|
||||
│ └── templates/ # Admin UI PHP templates
|
||||
├── autoload/ # Core PHP classes (MVC layers)
|
||||
│ ├── class.S.php # Global static helpers
|
||||
│ ├── class.Tpl.php # Template engine
|
||||
│ ├── class.Cache.php # Session cache
|
||||
│ ├── class.Html.php # HTML generation helpers
|
||||
│ ├── class.Image.php # Image processing
|
||||
│ ├── front/ # Frontend MVC classes
|
||||
│ │ ├── controls/ # Frontend controllers
|
||||
│ │ ├── factory/ # Frontend models (DB queries)
|
||||
│ │ └── view/ # Frontend HTML generators
|
||||
│ └── admin/ # Admin MVC classes
|
||||
│ ├── controls/ # Admin controllers
|
||||
│ ├── factory/ # Admin models (DB queries)
|
||||
│ └── view/ # Admin HTML generators
|
||||
├── templates/ # Default frontend PHP templates
|
||||
│ ├── articles/ # Article display templates
|
||||
│ ├── pages/ # Page display templates
|
||||
│ ├── site/ # Layout partials (header, footer, etc.)
|
||||
│ ├── newsletter/ # Newsletter form templates
|
||||
│ └── widgets/ # Widget templates
|
||||
├── templates_user/ # Custom frontend templates (override defaults)
|
||||
├── layout/ # Frontend CSS, JS, fonts
|
||||
│ ├── style-scss/ # SCSS source files
|
||||
│ │ ├── _variables.scss # Color/font variables
|
||||
│ │ ├── _mixins.scss # Responsive breakpoints, mixins
|
||||
│ │ └── style.scss # Main SCSS entry point
|
||||
│ ├── style-css/ # Compiled frontend CSS
|
||||
│ └── js/ # Frontend JavaScript
|
||||
│ ├── main.js # Main frontend JS
|
||||
│ └── custom.js # Custom frontend JS
|
||||
├── libraries/ # Vendored PHP/JS libraries
|
||||
│ ├── medoo/ # Medoo ORM
|
||||
│ ├── phpmailer/ # PHPMailer for email
|
||||
│ ├── ckeditor/ # Rich text editor
|
||||
│ ├── grid/ # Admin data grid component
|
||||
│ ├── bootstrap-4.1.3/ # Bootstrap 4
|
||||
│ ├── bootstrap-5.0/ # Bootstrap 5
|
||||
│ ├── font-awesome-6.1.1/ # Icon library
|
||||
│ ├── swiper/ # Carousel library
|
||||
│ ├── framework/ # Date pickers, moment.js
|
||||
│ └── jquery/ # jQuery utilities (lozad, captcha)
|
||||
├── plugins/ # Hook files for extensibility
|
||||
│ ├── special-actions.php # Early hooks
|
||||
│ ├── special-actions-middle.php # Contact forms, file uploads
|
||||
│ └── special-actions-end.php # Late hooks
|
||||
├── images/ # User-uploaded images
|
||||
├── upload/ # User-uploaded files
|
||||
├── cache/ # Runtime cache + generated WebP images
|
||||
├── stopki/ # Footer content fragments
|
||||
├── .paul/ # PAUL project management files
|
||||
├── .vscode/ # VS Code settings (SCSS compile, SFTP)
|
||||
└── .htaccess # Apache URL rewriting rules
|
||||
```
|
||||
|
||||
## Directory Purposes
|
||||
|
||||
**`autoload/`:**
|
||||
- Purpose: All PHP application classes — the core of the CMS
|
||||
- Pattern: `class.ClassName.php` naming
|
||||
- Namespaced: `front\controls\`, `front\factory\`, `front\view\`, `admin\controls\`, `admin\factory\`, `admin\view\`
|
||||
- Key files: `class.S.php` (global helpers), `class.Tpl.php` (templating), `class.Image.php`
|
||||
|
||||
**`admin/templates/`:**
|
||||
- Purpose: PHP template files for admin panel UI
|
||||
- Organized by module: `articles/`, `pages/`, `users/`, `newsletter/`, `layouts/`, `scontainers/`, `html/`
|
||||
- Key files: `articles/article-edit.php`, `pages/page-edit.php`, `site/main-layout.php`
|
||||
|
||||
**`templates/` and `templates_user/`:**
|
||||
- Purpose: Frontend page templates
|
||||
- `templates/` — default templates (shipped with CMS)
|
||||
- `templates_user/` — project-specific overrides (take precedence over defaults)
|
||||
- `Tpl::view()` checks `templates_user/` first, falls back to `templates/`
|
||||
|
||||
**`layout/`:**
|
||||
- Purpose: All frontend CSS, JS, fonts
|
||||
- SCSS source in `layout/style-scss/`, compiled output in `layout/style-css/`
|
||||
- JS in `layout/js/`
|
||||
|
||||
**`libraries/`:**
|
||||
- Purpose: All vendored third-party libraries (no package manager)
|
||||
- PHP libraries: Medoo, PHPMailer, Grid
|
||||
- JS libraries: CKEditor, Bootstrap, Swiper, DatePickers
|
||||
|
||||
**`plugins/`:**
|
||||
- Purpose: Extension hooks called from `index.php` at different lifecycle stages
|
||||
- `special-actions-middle.php` is the main plugin — contains all contact form handlers and reCAPTCHA
|
||||
|
||||
**`cache/`:**
|
||||
- Purpose: Runtime-generated files (WebP images)
|
||||
- Auto-created by `\Image` class during first request
|
||||
- Not committed to git (runtime data)
|
||||
|
||||
## Key File Locations
|
||||
|
||||
**Entry Points:**
|
||||
- `index.php` — public frontend entry
|
||||
- `ajax.php` — frontend AJAX
|
||||
- `admin/index.php` — admin panel entry
|
||||
- `admin/ajax.php` — admin AJAX
|
||||
- `api/contact_map.php` — contacts/locations JSON API
|
||||
|
||||
**Configuration:**
|
||||
- `config.php` — database credentials (single config file, no .env)
|
||||
- `admin/ip.conf` — optional IP whitelist for admin panel
|
||||
- `.vscode/settings.json` — SCSS compile settings
|
||||
|
||||
**Core Logic:**
|
||||
- `autoload/class.S.php` — global helpers (images, cache, email, sessions)
|
||||
- `autoload/class.Tpl.php` — template engine
|
||||
- `autoload/front/view/class.Site.php` — main frontend page renderer
|
||||
- `autoload/admin/view/class.Page.php` — main admin page renderer
|
||||
- `libraries/medoo/medoo.php` — database ORM
|
||||
|
||||
**Templates (Frontend):**
|
||||
- `templates/articles/` — article display patterns
|
||||
- `templates/site/` — header, footer, contact, Facebook widget
|
||||
- `templates_user/page-contact-v*.php` — custom contact page variants
|
||||
|
||||
## Naming Conventions
|
||||
|
||||
**PHP Class Files:**
|
||||
- Pattern: `class.ClassName.php` (e.g., `class.Articles.php`, `class.Users.php`)
|
||||
- Namespace mirrors directory: `admin\factory\` = `autoload/admin/factory/class.*.php`
|
||||
|
||||
**PHP Templates:**
|
||||
- Pattern: `feature-type.php` in kebab-case (e.g., `article-edit.php`, `articles-browse-list.php`)
|
||||
|
||||
**SCSS/CSS:**
|
||||
- Helper files: `_variables.scss`, `_mixins.scss` (underscore prefix)
|
||||
- Feature files: kebab-case (e.g., `drzwi-wejsciowe-aluminiowe.scss`)
|
||||
- Compiled output in `style-css/` mirroring `style-scss/`
|
||||
|
||||
**Directories:**
|
||||
- Feature groupings in kebab-case
|
||||
- Plural for collections: `articles/`, `templates/`, `controls/`
|
||||
|
||||
## Where to Add New Code
|
||||
|
||||
**New Content Module (e.g., "Events"):**
|
||||
- Admin factory: `autoload/admin/factory/class.Events.php`
|
||||
- Admin controls: `autoload/admin/controls/class.Events.php`
|
||||
- Admin view: `autoload/admin/view/class.Events.php`
|
||||
- Admin templates: `admin/templates/events/`
|
||||
- Frontend factory: `autoload/front/factory/class.Events.php`
|
||||
- Frontend templates: `templates_user/events/` or `templates/events/`
|
||||
|
||||
**New Frontend Page Template:**
|
||||
- Custom: `templates_user/page-[name].php`
|
||||
- Default: `templates/pages/page-[type].php`
|
||||
|
||||
**New Contact Form Variant:**
|
||||
- Add handler to `plugins/special-actions-middle.php`
|
||||
|
||||
**New AJAX Action:**
|
||||
- Frontend: add `case` in `ajax.php`
|
||||
- Admin: add `case` in `admin/ajax.php`
|
||||
|
||||
**New JS/CSS:**
|
||||
- Frontend JS: `layout/js/custom.js` or new file in `layout/js/`
|
||||
- Frontend SCSS: `layout/style-scss/` (compiled by Live Sass Compiler)
|
||||
- Admin SCSS: `admin/css/custom.scss`
|
||||
|
||||
## Special Directories
|
||||
|
||||
**`cache/`:**
|
||||
- Purpose: Runtime-generated WebP images and temporary cache
|
||||
- Source: Auto-generated by `\Image` class and `\Cache` class
|
||||
- Committed: No (runtime data, not in git)
|
||||
|
||||
**`admin/temp/`:**
|
||||
- Purpose: Temporary file uploads during admin operations
|
||||
- Source: File upload handlers
|
||||
- Committed: Should not be committed
|
||||
|
||||
**`templates_user/`:**
|
||||
- Purpose: Project-specific template overrides
|
||||
- Source: Manual creation — customizations live here
|
||||
- Committed: Yes (project-specific content)
|
||||
|
||||
---
|
||||
|
||||
*Structure analysis: 2026-05-05*
|
||||
*Update when directory structure changes*
|
||||
14
.paul/codebase/tech_changelog.md
Normal file
14
.paul/codebase/tech_changelog.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Technical Changelog
|
||||
|
||||
> Chronological log of technical changes — what and why.
|
||||
|
||||
## 2026-05-05 — Codebase Mapping
|
||||
|
||||
**Co zrobiono / What changed:**
|
||||
- Initial codebase map created in `.paul/codebase/` (9 documents)
|
||||
- Analyzed stack, architecture, structure, conventions, integrations, concerns, DB schema
|
||||
|
||||
**Dlaczego / Why:**
|
||||
- First-time PAUL project setup — baseline documentation for future planning
|
||||
|
||||
---
|
||||
71
.paul/codebase/testing.md
Normal file
71
.paul/codebase/testing.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Testing Patterns
|
||||
|
||||
**Analysis Date:** 2026-05-05
|
||||
|
||||
## Test Framework
|
||||
|
||||
**Runner:**
|
||||
- None detected — no test runner configured
|
||||
|
||||
**Assertion Library:**
|
||||
- None
|
||||
|
||||
**Run Commands:**
|
||||
- No test commands available in project
|
||||
|
||||
## Test File Organization
|
||||
|
||||
**Location:**
|
||||
- No test files found in codebase (searched for `*.test.js`, `*.spec.js`, `*Test.php`, `__tests__/`)
|
||||
|
||||
**Naming:**
|
||||
- No test naming convention (no tests exist)
|
||||
|
||||
## Test Infrastructure
|
||||
|
||||
**PHPUnit:**
|
||||
- Not installed — no `phpunit.xml`, no `vendor/phpunit`
|
||||
|
||||
**Jest / Vitest:**
|
||||
- Not installed — no `package.json`, no test config
|
||||
|
||||
**Coverage Tools:**
|
||||
- None configured
|
||||
|
||||
**Linting/Static Analysis:**
|
||||
- No ESLint (no `.eslintrc`)
|
||||
- No Prettier (no `.prettierrc`)
|
||||
- No PHP CodeSniffer (no `phpcs.xml`)
|
||||
- No StyleLint
|
||||
|
||||
## Testing Approach
|
||||
|
||||
**Current state:**
|
||||
- Manual testing only — no automated test infrastructure
|
||||
- No CI/CD pipeline to run tests
|
||||
- No test directories anywhere in the project
|
||||
|
||||
**Quality assurance:**
|
||||
- Live Sass Compiler (`admin/css/custom.scss`) — validates SCSS syntax at compile time
|
||||
- FTP deployment via VS Code extension — direct push to production/staging server
|
||||
- Browser-based manual verification
|
||||
|
||||
## Recommendations (if implementing tests)
|
||||
|
||||
**PHP — PHPUnit:**
|
||||
- Target the factory layer: `autoload/admin/factory/class.*.php`, `autoload/front/factory/class.*.php`
|
||||
- These are static methods — use PHPUnit with Medoo mocking
|
||||
|
||||
**JavaScript — Jest or Playwright:**
|
||||
- Frontend forms and gallery interactions
|
||||
- Admin grid operations
|
||||
|
||||
**Priority areas to test first (given security concerns):**
|
||||
1. Input sanitization in `autoload/class.S.php` (the `get()` method)
|
||||
2. File upload validation in `plugins/special-actions-middle.php`
|
||||
3. Authentication flow in `admin/index.php`
|
||||
|
||||
---
|
||||
|
||||
*Testing analysis: 2026-05-05*
|
||||
*Update when test patterns are introduced*
|
||||
Reference in New Issue
Block a user