update
This commit is contained in:
351
.paul/codebase/architecture.md
Normal file
351
.paul/codebase/architecture.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# Architecture & Structure
|
||||
|
||||
**Analysis Date:** 2026-04-30
|
||||
|
||||
---
|
||||
|
||||
## Directory Layout
|
||||
|
||||
```
|
||||
centrumcopy.com.pl/ # Docroot / front controller
|
||||
├── index.php # Front controller (entry point)
|
||||
├── robots.txt
|
||||
├── application/ # Application code (APPPATH)
|
||||
│ ├── cache/ # Kohana internal cache (file-based)
|
||||
│ ├── config/ # All configuration files
|
||||
│ ├── controllers/ # MVC Controllers
|
||||
│ │ ├── base_admin.php # Abstract base for admin controllers
|
||||
│ │ ├── base_front.php # Abstract base for front controllers
|
||||
│ │ ├── install.php # Installation controller
|
||||
│ │ ├── admin/ # Admin panel controllers
|
||||
│ │ └── front/ # Public-facing controllers
|
||||
│ ├── helpers/ # (empty — helpers live in libraries/drivers)
|
||||
│ ├── i18n/pl_PL/ # Polish locale strings
|
||||
│ ├── libraries/ # Extended/custom libraries
|
||||
│ │ └── drivers/ # Driver extensions
|
||||
│ ├── logs/ # Error/application logs
|
||||
│ ├── models/ # ORM models
|
||||
│ └── views/ # PHP view templates
|
||||
│ ├── admin/ # Admin panel partial views
|
||||
│ ├── front/ # Public partial views
|
||||
│ ├── gmaps/ # Google Maps JS view
|
||||
│ ├── pagination/ # Pagination style templates
|
||||
│ ├── admin_layout.php # Admin full-page layout
|
||||
│ ├── admin_login.php # Admin login page
|
||||
│ └── default_layout.php # Public full-page layout
|
||||
├── modules/ # Kohana modules (MODPATH)
|
||||
│ ├── gmaps/ # Google Maps integration module
|
||||
│ └── debug_toolbar/ # Debug toolbar module
|
||||
├── system/ # Kohana framework core (SYSPATH)
|
||||
│ └── core/ # Bootstrap, Event, Kohana, Benchmark
|
||||
├── css/ # Public stylesheets
|
||||
├── js/ # Public JavaScript (jQuery, TinyMCE, etc.)
|
||||
├── images/ # Public images
|
||||
├── flash/ # Flash banner assets
|
||||
├── uploads/ # User-uploaded files
|
||||
└── stara/ # Legacy static HTML site (archived)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## MVC Structure
|
||||
|
||||
### Controllers
|
||||
|
||||
**Location:** `application/controllers/`
|
||||
|
||||
Controllers use Kohana 2.x naming: `{Name}_Controller` extends a base class. File name is lowercase, class name is `PascalCase_Controller`.
|
||||
|
||||
**Base classes (abstract):**
|
||||
|
||||
| File | Class | Extends | Role |
|
||||
|------|-------|---------|------|
|
||||
| `application/controllers/base_front.php` | `Base_Front_Controller` | `Controller` | Sets up front layout (`default_layout`), session, menu, SEO metadata |
|
||||
| `application/controllers/base_admin.php` | `Base_Admin_Controller` | `Controller` | Sets up admin layout (`admin_layout`), enforces auth guard, manages flash messages |
|
||||
|
||||
**Front (public) controllers** — `application/controllers/front/`:
|
||||
|
||||
| File | Class | Handles |
|
||||
|------|-------|---------|
|
||||
| `front/page.php` | `Page_Controller` | Static CMS pages, homepage redirect, contact page with Google Maps |
|
||||
| `front/welcome.php` | `Welcome_Controller` | (unused/fallback) |
|
||||
|
||||
**Admin controllers** — `application/controllers/admin/`:
|
||||
|
||||
| File | Class | Handles |
|
||||
|------|-------|---------|
|
||||
| `admin/page.php` | `Page_Controller` | Edit CMS page content via TinyMCE |
|
||||
| `admin/user.php` | `User_Controller` | Login, logout, password change |
|
||||
| `admin/welcome.php` | `Welcome_Controller` | Admin dashboard index |
|
||||
|
||||
Note: Both `front/page.php` and `admin/page.php` define `Page_Controller` — they are isolated by directory scoping during routing.
|
||||
|
||||
**Auth guard pattern in `Base_Admin_Controller`:**
|
||||
```php
|
||||
if (!$this->session->get('admin') && Router::$method != 'login' && Router::$method != 'logout') {
|
||||
url::redirect('admin/login');
|
||||
}
|
||||
```
|
||||
|
||||
**`__call` magic method** is used in `Page_Controller` (front) to route any unknown URL segment to `show($name)`, enabling slug-based page lookup.
|
||||
|
||||
### Models
|
||||
|
||||
**Location:** `application/models/`
|
||||
|
||||
All models extend `ORM` (Kohana's ActiveRecord-style ORM). Model file name is lowercase; class name is `{Name}_Model`.
|
||||
|
||||
| File | Class | Table | Notes |
|
||||
|------|-------|-------|-------|
|
||||
| `models/page.php` | `Page_Model` | `page` | Singular table name; supports lookup by `name` slug |
|
||||
| `models/user.php` | `User_Model` | `user` | Primary val = `username`; SHA1+salt password hashing |
|
||||
| `models/news.php` | `News_Model` | `news` | Singular; sorted by `created_at DESC` |
|
||||
| `models/gallery.php` | `Gallery_Model` | `gallery` | Has many `gallery_images`; sorted `created_at ASC` |
|
||||
| `models/gallery_image.php` | `Gallery_Image_Model` | `gallery_image` | Belongs to `gallery`; sorted by `id ASC` |
|
||||
|
||||
**ORM lookup pattern:**
|
||||
```php
|
||||
ORM::factory('page')->where('name', $slug)->find();
|
||||
if (!$page->loaded) { return $this->error404(); }
|
||||
```
|
||||
|
||||
### Views
|
||||
|
||||
**Location:** `application/views/`
|
||||
|
||||
Views are plain PHP templates. Layout views are full HTML documents; partial views are HTML fragments assigned to `$content`.
|
||||
|
||||
**Layout views (full pages):**
|
||||
|
||||
| File | Used by |
|
||||
|------|---------|
|
||||
| `views/default_layout.php` | All front controllers via `Base_Front_Controller` |
|
||||
| `views/admin_layout.php` | All admin controllers via `Base_Admin_Controller` |
|
||||
| `views/admin_login.php` | `User_Controller::login()` |
|
||||
|
||||
**Partial views — front:** `views/front/`
|
||||
|
||||
| File | Rendered by |
|
||||
|------|-------------|
|
||||
| `front/page_show.php` | `Page_Controller::show()` |
|
||||
| `front/page_contact.php` | `Page_Controller::contact()` |
|
||||
| `front/error404.php` | `Base_Front_Controller::error404()` |
|
||||
|
||||
**Partial views — admin:** `views/admin/`
|
||||
|
||||
| File | Rendered by |
|
||||
|------|-------------|
|
||||
| `admin/page_edit.php` | `admin/Page_Controller::edit()` |
|
||||
| `admin/password.php` | `User_Controller::password()` |
|
||||
| `admin/welcome.php` | `admin/Welcome_Controller::index()` |
|
||||
| `admin/error404.php` | `Base_Admin_Controller::error404()` |
|
||||
|
||||
**View rendering pattern:**
|
||||
```php
|
||||
$page_view = new View('front/page_show');
|
||||
$page_view->page = $page; // assign data to partial
|
||||
$this->view->content = $page_view; // embed partial in layout
|
||||
$this->view->render(true); // output full layout
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Routing
|
||||
|
||||
**Config file:** `application/config/routes.php`
|
||||
|
||||
Kohana 2.x routing maps URL patterns (regex) to `directory/controller/method` targets. Routes are evaluated top-to-bottom; first match wins.
|
||||
|
||||
```php
|
||||
$config['_default'] = 'front/page/homepage'; // / → Front\Page::homepage()
|
||||
|
||||
// Admin routes
|
||||
$config['admin'] = 'admin/welcome/'; // /admin
|
||||
$config['admin/login'] = 'admin/user/login'; // /admin/login
|
||||
$config['admin/logout'] = 'admin/user/logout'; // /admin/logout
|
||||
$config['admin/password'] = 'admin/user/password'; // /admin/password
|
||||
$config['admin/page/(.*)'] = 'admin/page/edit/$1'; // /admin/page/{slug}
|
||||
$config['admin/(.*)'] = 'admin/$1'; // /admin/...
|
||||
|
||||
// Front routes
|
||||
$config['kontakt'] = 'front/page/contact'; // /kontakt
|
||||
$config['galeria/?(.*)'] = 'front/gallery/$1'; // /galeria/...
|
||||
$config['aktualnosci/?(.*)'] = 'front/news/$1'; // /aktualnosci/...
|
||||
$config['(.+)'] = 'front/page/$1'; // /{any-slug} → Page::show()
|
||||
```
|
||||
|
||||
**Slug routing:** The catch-all `(.+)` route passes the URL slug to `front/page/`. `Page_Controller::show($name)` then queries the database for a page with `name = $slug`. This means all CMS pages live in a flat namespace matched against the `page.name` column.
|
||||
|
||||
**URL rewriting:** `index_page` is commented out in `application/config/config.php`, meaning clean URLs (no `index.php` in path) require Apache `mod_rewrite` or equivalent.
|
||||
|
||||
---
|
||||
|
||||
## Module System
|
||||
|
||||
**Module path:** `modules/` (MODPATH)
|
||||
|
||||
Modules are configured in `application/config/config.php` under `$config['modules']`. Kohana merges module paths into the file search cascade (controllers, views, libraries, etc. from a module are auto-discoverable).
|
||||
|
||||
**Active modules:**
|
||||
|
||||
| Module | Path | Purpose |
|
||||
|--------|------|---------|
|
||||
| `gmaps` | `modules/gmaps/` | Google Maps v2 API wrapper — `Gmap` library, marker helpers, JS view |
|
||||
|
||||
**Available but disabled modules** (commented out in config):
|
||||
- `auth`, `forge`, `kodoc`, `media`, `archive`, `payment`, `unit_test`, `object_db`
|
||||
|
||||
**`debug_toolbar` module** exists at `modules/debug_toolbar/` but is **not loaded** in config.
|
||||
|
||||
**Module internal structure** (gmaps example):
|
||||
```
|
||||
modules/gmaps/
|
||||
├── config/ # Module config
|
||||
├── controllers/ # Module controllers (if any)
|
||||
├── i18n/
|
||||
├── libraries/ # Gmap, Gmap_Marker libraries
|
||||
├── models/
|
||||
└── views/ # gmaps/javascript.php
|
||||
```
|
||||
|
||||
**Custom application-level extensions** (not modules — override framework classes):
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `application/libraries/MY_Database.php` | Extends `Database_Core` — fixes `COUNT()` column escaping with table prefix |
|
||||
| `application/libraries/MY_Gmap_Marker.php` | Extends Gmap marker from the gmaps module |
|
||||
| `application/libraries/drivers/Database.php` | Custom database driver wrapper |
|
||||
| `application/libraries/drivers/MY_form.php` | Extended form helper |
|
||||
| `application/libraries/drivers/MY_html.php` | Extended html helper (adds `span_class()`, etc.) |
|
||||
| `application/libraries/drivers/MY_valid.php` | Extended validation rules |
|
||||
| `application/libraries/drivers/categories.php` | Category tree helper |
|
||||
| `application/libraries/drivers/javascript.php` | JavaScript generation helper |
|
||||
|
||||
---
|
||||
|
||||
## Business Domains
|
||||
|
||||
This is a **B2B product catalogue + CMS** for a photocopier/office equipment distributor (Centrum Copy Rzeszów).
|
||||
|
||||
### CMS / Static Pages
|
||||
- **Primary domain.** All content pages are rows in the `page` table, looked up by a URL `name` slug.
|
||||
- Pages have: `title`, `header`, `content` (HTML via TinyMCE), `meta_description`, `meta_keywords`.
|
||||
- Admin edits pages via WYSIWYG at `/admin/page/{slug}`.
|
||||
- Menu structure is **hardcoded** in `application/config/application.php` under `$config['menu_nav']` — changing the menu requires a code deploy.
|
||||
- Content domains visible in admin menu: O firmie, Powielacze cyfrowe RISO, Pełnokolorowe urządzenia Inkjet RISO ComColor, Urządzenia biurowe (kolorowe/monochromatyczne A4/A3), Plotery i skanery, Finansowanie, Serwis, Usługi, Kontakt, Szybki kontakt.
|
||||
|
||||
### Gallery
|
||||
- Model: `Gallery_Model` (has_many `Gallery_Image_Model`)
|
||||
- Route: `/galeria/...` → `front/gallery` controller
|
||||
- Note: `application/controllers/front/gallery.php` does not exist as a file — gallery controller is **missing or not committed**.
|
||||
|
||||
### News / Aktualności
|
||||
- Model: `News_Model`
|
||||
- Route: `/aktualnosci/...` → `front/news` controller
|
||||
- Note: `application/controllers/front/news.php` does not exist — news controller is **missing or not committed**.
|
||||
|
||||
### Contact Page
|
||||
- Route `/kontakt` → `Page_Controller::contact()`
|
||||
- Renders Google Maps v2 marker at configured lat/lon (`application/config/application.php` → `$config['gmaps']`).
|
||||
- Google Maps centre: `50.0491231, 21.9869502` (Rzeszów, ul. Okulickiego 9).
|
||||
|
||||
### Admin Panel
|
||||
- Session-based authentication. Credentials: SHA1(salt + password) stored in `user` table.
|
||||
- Single-user admin — no roles enforced beyond session presence.
|
||||
- Admin navigates to hardcoded page slugs from the sidebar in `admin_layout.php`.
|
||||
- Features: edit page content, change admin password, logout.
|
||||
|
||||
---
|
||||
|
||||
## Request Lifecycle
|
||||
|
||||
```
|
||||
Browser Request
|
||||
|
|
||||
v
|
||||
index.php (front controller)
|
||||
- defines DOCROOT, APPPATH, MODPATH, SYSPATH
|
||||
- sets IN_PRODUCTION = false
|
||||
- requires system/core/Bootstrap.php
|
||||
|
|
||||
v
|
||||
system/core/Bootstrap.php
|
||||
- loads Benchmark, utf8, Event, Kohana
|
||||
- Kohana::setup() (loads config, modules, sets error handlers)
|
||||
|
|
||||
v
|
||||
Event::run('system.ready') (hooks, if enabled — currently disabled)
|
||||
|
|
||||
v
|
||||
Event::run('system.routing')
|
||||
- Router matches URI against application/config/routes.php
|
||||
- Determines: directory, controller, method, arguments
|
||||
|
|
||||
v
|
||||
Event::run('system.execute')
|
||||
- Instantiates controller: new {Name}_Controller()
|
||||
- __construct() runs:
|
||||
- parent::__construct() (Kohana base Controller)
|
||||
- Base_Front/Admin_Controller::__construct()
|
||||
- Creates View object for layout
|
||||
- Starts Session
|
||||
- Loads config (title, meta, menu_nav, etc.)
|
||||
- [Admin only] Auth guard → redirect to login if not authed
|
||||
- Calls controller method (e.g., show(), edit(), login())
|
||||
- Method queries ORM models
|
||||
- Creates partial View, assigns data
|
||||
- Assigns partial to $this->view->content
|
||||
- $this->view->render(true) → outputs full HTML
|
||||
|
|
||||
v
|
||||
Event::run('system.shutdown') (cleanup)
|
||||
|
|
||||
v
|
||||
Response sent to browser
|
||||
```
|
||||
|
||||
**Session:** Native PHP sessions, 30-minute expiration, validated by `user_agent`. Session name: `Frisson_session`.
|
||||
|
||||
**Database:** MySQLi driver, single `default` connection, no table prefix, UTF-8 charset, query benchmarking enabled.
|
||||
|
||||
**Output compression:** gzip enabled (`$config['output_compression'] = TRUE`).
|
||||
|
||||
**Error handling:** Errors logged to `application/logs/` at threshold 1 (errors + exceptions). `display_errors` is off in production.
|
||||
|
||||
---
|
||||
|
||||
## Configuration Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `application/config/application.php` | Site title, email, Google Maps coords, navigation menu, Google Analytics |
|
||||
| `application/config/config.php` | Kohana core settings: domain, modules list, cache, compression, hooks |
|
||||
| `application/config/database.php` | MySQLi connection credentials |
|
||||
| `application/config/routes.php` | URL routing rules |
|
||||
| `application/config/session.php` | Session driver, name, expiration |
|
||||
| `application/config/pagination.php` | Pagination defaults (5 items/page, segment 3) |
|
||||
| `application/config/email.php` | Email settings |
|
||||
| `application/config/cookie.php` | Cookie settings |
|
||||
| `application/config/tiny_mce.php` | TinyMCE upload paths for admin editor |
|
||||
| `application/config/upload.php` | File upload settings |
|
||||
| `application/config/locale.php` | Locale/timezone |
|
||||
| `application/config/gmaps.php` | Google Maps module config |
|
||||
| `application/config/debug_toolbar.php` | Debug toolbar settings |
|
||||
|
||||
---
|
||||
|
||||
## Key Observations & Gaps
|
||||
|
||||
1. **Missing controllers:** `application/controllers/front/gallery.php` and `application/controllers/front/news.php` are referenced in routes but absent. Routes for `/galeria/` and `/aktualnosci/` will 404.
|
||||
|
||||
2. **Hardcoded navigation:** `$config['menu_nav']` in `application/config/application.php` defines the entire site menu statically. Adding/removing menu items requires editing this config file and redeploying.
|
||||
|
||||
3. **Admin menu also hardcoded:** `application/views/admin_layout.php` contains inline HTML listing every editable page slug. Must be manually updated to match `page` table contents.
|
||||
|
||||
4. **IN_PRODUCTION = false:** Set in `index.php`. Must be changed to `true` before deploying to live server to enable Google Analytics and suppress demo controllers.
|
||||
|
||||
5. **Kohana version:** 2.3.4 (codename "buteo regalis") — very old, unmaintained framework. No Composer, no autoloading beyond Kohana's own file cascade.
|
||||
|
||||
6. **Auth security:** `User_Controller::login()` contains `print_r($_POST)` debug statement (line 29). This leaks credentials in the HTTP response. Remove before any production use.
|
||||
|
||||
7. **No test runner configured.** No test files detected.
|
||||
Reference in New Issue
Block a user