Files
centrumcopy.com.pl/.paul/codebase/architecture.md
2026-04-30 21:31:32 +02:00

15 KiB

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) controllersapplication/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 controllersapplication/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:

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:

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:

$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.

$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.
  • 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 /kontaktPage_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.