# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview CityWebShop CMS — a Budapest real estate and accommodation booking platform. Handles property listings (sale/rent), hotel/tourism accommodations, partner dashboards, reservations, and content management. Multi-language (Hungarian/English). ## Tech Stack - **PHP** on a custom lightweight MVC framework (NOT CodeIgniter or Laravel) - **MySQL/MariaDB** with raw SQL queries via mysqli - **Frontend**: Bootstrap, jQuery, Trumbowyg/CKEditor (WYSIWYG), Google Maps - **Libraries**: PHPMailer, TCPDF/DOMPDF (PDF generation), PHPExcel - No Composer at root, no package manager, no build step ## Running the Application This is a traditional PHP app served directly by Apache/Nginx. No build commands or test suite exist. - Entry point: `index.php` - URL rewriting via `.htaccess` (forces HTTPS, rewrites to `index.php`) - Database schema: `sql/openws.sql` - Config (DB credentials, API keys): `application/config/config.php` ## Architecture ### Custom MVC Framework (`system/`) - **`system/pip.php`** — The router. Parses URL segments and dispatches to controllers. Contains complex route mappings for properties, offices, blog, map, events, API, etc. Property URLs include Budapest district normalization (Roman numerals to text). - **`system/controller.php`** — Base controller with `loadModel()`, `loadView()`, `loadHelper()`, `redirect()`. - **`system/model.php`** — Base model extending `mysqli` directly. Methods: `query()`, `execute()`, `escapeString()`, `escapeArray()`, `getLastInsertID()`. No ORM — all queries are raw SQL. - **`system/view.php`** — Template engine using PHP `extract()` and output buffering. Supports partner-specific view overrides via `$_SESSION['realladev']`. ### Application Layer (`application/`) - **Controllers** (`application/controllers/`): ~20 controllers. Key ones: `admin.php` (dashboard/auth), `api.php` (REST endpoints), `property.php` (listings), `map.php` (spatial search), `offices.php`, `auth.php` (user registration). - **Models** (`application/models/`): ~47 models with raw SQL. Largest: `map_model.php` (spatial property search), `api_model.php` (external API integration with cURL), `partners.php` (partner/vendor logic). - **Views** (`application/views/`): ~121 PHP templates. Admin views prefixed `admin_*`. Email templates in `views/mails/`. - **Helpers** (`application/helpers/`): `admin_utils.php` (settings, roles, translations), `common.php` (DB connection, IP validation), `lang.php` (translation lookup), `formatize.php` (currency, favorites cookies). ### Standalone PHP Scripts (project root) - `qrcode.php` — QR code generation - `exportdata.php` — Hotel data CSV export, updates admin dashboard via serialized arrays - `pdf.php`, `pdf_property.php` — TCPDF-based PDF export for properties ### API (`/api/` routes → `api.php` controller → `api_model.php`) External API integration with HopOnTicket (hotels, products, events, reservations). The model uses cURL to proxy calls to `https://hoponticket.com/api/index.php`. Key endpoints: `getGroupsList`, `getProductsList`, `getEventslist`, `initialize` (start transaction), `reservation`, `order`, `paymentstatus`, `validate` (reCAPTCHA v3). ### Authentication & Roles - Session-based admin auth with 15-minute timeout (set in `index.php`) - Access levels in `azonics_roles` table: 11=superadmin, 13=manager, 14=vendor, 1=basic user - Password hashing: RIPEMD160 - Partner-specific dashboards filter data by `$_SESSION['realladev']` ### Database - Table prefix: `azonics_*` (CMS content), `hiper_ingatlan*` (properties), `hiper_munkatars` (agents) - Translation system: `azonics_translations` table with language-keyed lookups - No migration system — schema managed via `sql/openws.sql` ### Routing Patterns URLs are parsed by `system/pip.php` segment-by-segment. Examples: - `/admin/login/` → `admin::login` - `/elado/lakas/budapest-i-kerulet/filter` → `property::search` (with district normalization) - `/api/getgroupslist` → `api::getgroupslist` - `/rockhome-irodak/` → `offices::index` ## Key Conventions - Models return associative arrays from raw SQL; no entity/DTO objects - Views receive data via `$this->view->set('key', $value)` then `$this->view->render('view_name')` - Admin utilities and settings are loaded globally via `admin_utils.php` helper - Static assets live in `static/` (CSS, JS, fonts, plugins, uploads) - Partner view overrides: if a partner-specific view exists in `application/partners/{partner}/`, it's used instead of the default