239 lines
11 KiB
Markdown
239 lines
11 KiB
Markdown
# CLAUDE.md
|
||
|
||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||
|
||
## Project Overview
|
||
|
||
shopPRO is a PHP e-commerce platform with an admin panel and customer-facing storefront. It uses Medoo ORM (`$mdb`), Redis caching, and a Domain-Driven Design architecture with Dependency Injection (migration from legacy architecture complete).
|
||
|
||
## Zasady pisania kodu
|
||
- Kod ma być czytelny „dla obcego”: jasne nazwy, mało magii
|
||
- Brak „skrótów na szybko” typu logika w widokach, copy-paste, losowe helpery bez spójności
|
||
- Każda funkcja/klasa ma mieć jedną odpowiedzialność, zwykle do 30–50 linii (jeśli dłuższe – dzielić)
|
||
- max 3 poziomy zagnieżdżeń (if/foreach), reszta do osobnych metod
|
||
- Nazewnictwo:
|
||
- klasy: PascalCase
|
||
- metody/zmienne: camelCase
|
||
- stałe: UPPER_SNAKE_CASE
|
||
- Zero „skrótologii” w nazwach (np. $d, $tmp, $x1) poza pętlami 2–3 linijki
|
||
- medoo + prepared statements bez wyjątków (żadnego sklejania SQL stringiem)
|
||
- XSS: escape w widokach (np. helper e())
|
||
- CSRF dla formularzy, sensowna obsługa sesji
|
||
- Kod ma mieć komentarze tylko tam, gdzie wyjaśniają „dlaczego”, nie „co”
|
||
|
||
## PHP Version Constraint
|
||
|
||
**Production runs PHP < 8.0.** Do NOT use:
|
||
- `match` expressions (use ternary operators or if/else)
|
||
- Named arguments
|
||
- Union types (`int|string`)
|
||
- `str_contains()`, `str_starts_with()`, `str_ends_with()`
|
||
- Other PHP 8.0+ syntax
|
||
|
||
`composer.json` requires `>=7.4`.
|
||
|
||
## Commands
|
||
|
||
### Running Tests
|
||
```bash
|
||
# Full suite (recommended — PowerShell, auto-finds php)
|
||
./test.ps1
|
||
|
||
# Specific file
|
||
./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php
|
||
|
||
# Specific test method
|
||
./test.ps1 --filter testGetQuantityReturnsCorrectValue
|
||
|
||
# Alternative
|
||
composer test
|
||
```
|
||
|
||
PHPUnit 9.6 via `phpunit.phar`. Bootstrap: `tests/bootstrap.php`. Config: `phpunit.xml`.
|
||
|
||
Current suite: **805 tests, 2253 assertions**.
|
||
|
||
### Creating Updates
|
||
See `docs/UPDATE_INSTRUCTIONS.md` for the full procedure. Updates are ZIP packages in `updates/0.XX/`. Never include `*.md` files, `updates/changelog.php`, or root `.htaccess` in update ZIPs.
|
||
|
||
## Architecture
|
||
|
||
### Directory Structure
|
||
```
|
||
shopPRO/
|
||
├── autoload/ # Autoloaded classes (core codebase)
|
||
│ ├── Domain/ # Business logic repositories (\Domain\)
|
||
│ ├── Shared/ # Shared utilities (\Shared\)
|
||
│ │ ├── Cache/ # CacheHandler, RedisConnection
|
||
│ │ ├── Email/ # Email (PHPMailer wrapper)
|
||
│ │ ├── Helpers/ # Helpers (formerly class.S.php)
|
||
│ │ ├── Html/ # Html utility
|
||
│ │ ├── Image/ # ImageManipulator
|
||
│ │ └── Tpl/ # Template engine
|
||
│ ├── api/ # REST API layer (\api\)
|
||
│ │ ├── ApiRouter.php # API router (\api\ApiRouter)
|
||
│ │ └── Controllers/ # API controllers (\api\Controllers\)
|
||
│ ├── admin/ # Admin panel layer
|
||
│ │ ├── App.php # Admin router (\admin\App)
|
||
│ │ ├── Controllers/ # DI controllers (\admin\Controllers\) — 28 controllers
|
||
│ │ ├── Support/ # TableListRequestFactory, Forms/FormRequestHandler, Forms/FormFieldRenderer
|
||
│ │ ├── Validation/ # FormValidator
|
||
│ │ └── ViewModels/ # Forms/ (FormEditViewModel, FormField, FormTab, FormAction, FormFieldType), Common/ (PaginatedTableViewModel)
|
||
│ └── front/ # Frontend layer
|
||
│ ├── App.php # Frontend router (\front\App)
|
||
│ ├── LayoutEngine.php # Layout engine (\front\LayoutEngine)
|
||
│ ├── Controllers/ # DI controllers (\front\Controllers\) — 8 controllers
|
||
│ └── Views/ # Static views (\front\Views\) — 11 view classes
|
||
├── admin/ # Admin panel
|
||
│ ├── templates/ # Admin view templates
|
||
│ └── layout/ # Admin CSS/JS/icons
|
||
├── templates/ # Frontend view templates
|
||
├── libraries/ # Third-party libraries (Medoo, RedBeanPHP, PHPMailer)
|
||
├── tests/ # PHPUnit tests
|
||
│ ├── bootstrap.php
|
||
│ ├── stubs/ # Test stubs (CacheHandler, Helpers, ShopProduct)
|
||
│ └── Unit/
|
||
│ ├── Domain/ # Repository tests
|
||
│ ├── admin/Controllers/ # Controller tests
|
||
│ └── api/ # API tests
|
||
├── updates/ # Update packages for clients
|
||
├── docs/ # Technical documentation
|
||
├── config.php # Database/Redis config (not in repo)
|
||
├── index.php # Frontend entry point
|
||
├── ajax.php # Frontend AJAX handler
|
||
├── admin/index.php # Admin entry point
|
||
├── admin/ajax.php # Admin AJAX handler
|
||
├── cron.php # CRON jobs (Apilo sync)
|
||
└── api.php # REST API (ordersPRO + Ekomi)
|
||
```
|
||
|
||
### Autoloader
|
||
|
||
Custom autoloader in each entry point (not Composer autoload at runtime). Tries two filename conventions:
|
||
1. `autoload/{namespace}/class.{ClassName}.php` (legacy)
|
||
2. `autoload/{namespace}/{ClassName}.php` (PSR-4 style, fallback)
|
||
|
||
### Namespace Conventions (case-sensitive on Linux!)
|
||
- `\Domain\` → `autoload/Domain/` (uppercase D)
|
||
- `\admin\Controllers\` → `autoload/admin/Controllers/` (lowercase a)
|
||
- `\Shared\` → `autoload/Shared/`
|
||
- `\api\` → `autoload/api/`
|
||
- Do NOT use `\Admin\` (uppercase A) — the server directory is `admin/` (lowercase)
|
||
- `\shop\` namespace is **deleted** — all 12 legacy classes migrated to `\Domain\`, `autoload/shop/` directory removed
|
||
|
||
### Domain-Driven Architecture (migration complete)
|
||
|
||
All legacy directories (`admin/controls/`, `admin/factory/`, `admin/view/`, `front/controls/`, `front/view/`, `front/factory/`, `shop/`) have been deleted. All modules now use this pattern:
|
||
|
||
**Domain Layer** (`autoload/Domain/{Module}/`):
|
||
- `{Module}Repository.php` — data access, business logic, Redis caching
|
||
- Constructor DI with `$db` (Medoo instance)
|
||
- Methods serve both admin and frontend (shared Domain, no separate services)
|
||
|
||
**Domain Modules**: Article, Attribute, Banner, Basket, Cache, Category, Client, Coupon, CronJob, Dashboard, Dictionaries, Integrations, Languages, Layouts, Newsletter, Order, Pages, PaymentMethod, Producer, Product, ProductSet, Promotion, Scontainers, Settings, ShopStatus, Transport, Update, User
|
||
|
||
**Admin Controllers** (`autoload/admin/Controllers/`):
|
||
- DI via constructor (repositories injected)
|
||
- Wired in `admin\App::getControllerFactories()`
|
||
|
||
**Frontend Controllers** (`autoload/front/Controllers/`):
|
||
- DI via constructor
|
||
- Wired in `front\App::getControllerFactories()`
|
||
|
||
**Frontend Views** (`autoload/front/Views/`):
|
||
- Static classes, no state, no DI — pure rendering
|
||
|
||
**API Controllers** (`autoload/api/Controllers/`):
|
||
- DI via constructor, stateless (no session)
|
||
- Wired in `api\ApiRouter::getControllerFactories()`
|
||
- Auth: `X-Api-Key` header vs `pp_settings.api_key`
|
||
|
||
### Key Classes
|
||
| Class | Purpose |
|
||
|-------|---------|
|
||
| `\admin\App` | Admin router — maps URL segments to controllers |
|
||
| `\front\App` | Frontend router — `route()`, `checkUrlParams()` |
|
||
| `\front\LayoutEngine` | Frontend layout engine — `show()`, tag replacement |
|
||
| `\Shared\Helpers\Helpers` | Utility methods (SEO, email, cache clearing) |
|
||
| `\Shared\Tpl\Tpl` | Template engine — `render()`, `set()` |
|
||
| `\Shared\Cache\CacheHandler` | Redis cache — `get()`, `set()`, `delete()`, `deletePattern()` |
|
||
| `\api\ApiRouter` | REST API router — auth, routing, response helpers |
|
||
|
||
### Database
|
||
- ORM: Medoo (`$mdb` global variable, injected via DI in new code)
|
||
- Table prefix: `pp_`
|
||
- Key tables: `pp_shop_products`, `pp_shop_orders`, `pp_shop_categories`, `pp_shop_clients`
|
||
- Full schema: `docs/DATABASE_STRUCTURE.md`
|
||
|
||
### Form Edit System
|
||
Universal form system for admin edit views. Docs: `docs/FORM_EDIT_SYSTEM.md`.
|
||
- **ViewModels** (`admin\ViewModels\Forms\`): `FormEditViewModel`, `FormField`, `FormTab`, `FormAction`, `FormFieldType`
|
||
- **Validation**: `admin\Validation\FormValidator`
|
||
- **Rendering**: `admin\Support\Forms\FormFieldRenderer`, `admin\Support\Forms\FormRequestHandler`
|
||
- **Template**: `admin/templates/components/form-edit.php`
|
||
- **Table lists**: `admin\Support\TableListRequestFactory` + `admin\ViewModels\Common\PaginatedTableViewModel`
|
||
|
||
### Caching
|
||
- Redis via `\Shared\Cache\CacheHandler` (singleton `RedisConnection`)
|
||
- Key pattern for products: `shop\product:{id}:{lang}:{permutation_hash}`
|
||
- Clear product cache: `\Shared\Helpers\Helpers::clear_product_cache($id)`
|
||
- Pattern delete: `CacheHandler::deletePattern("shop\\product:{$id}:*")`
|
||
- Default TTL: 86400 (24h)
|
||
- Data is serialized — requires `unserialize()` after `get()`
|
||
- Config: `config.php` (`$config['redis']`)
|
||
|
||
## Code Patterns
|
||
|
||
### New code should follow DI pattern
|
||
```php
|
||
// Repository with constructor DI
|
||
class ExampleRepository {
|
||
private $db;
|
||
public function __construct($db) {
|
||
$this->db = $db;
|
||
}
|
||
public function find(int $id): ?array {
|
||
return $this->db->get('pp_table', '*', ['id' => $id]);
|
||
}
|
||
}
|
||
|
||
// Controller wiring (in admin\App or front\App)
|
||
$repo = new \Domain\Example\ExampleRepository($mdb);
|
||
$controller = new \admin\Controllers\ExampleController($repo);
|
||
```
|
||
|
||
### Medoo ORM pitfalls
|
||
- `$mdb->delete($table, $where)` takes **2 arguments**, NOT 3 — has caused bugs
|
||
- `$mdb->get()` returns `null` when no record, NOT `false`
|
||
- After `$mdb->insert()`, check `$mdb->id()` to confirm success
|
||
|
||
### File naming
|
||
- New classes: `ClassName.php` (no `class.` prefix)
|
||
- Legacy classes: `class.ClassName.php` (leave until migrated)
|
||
|
||
### Test conventions
|
||
- Extend `PHPUnit\Framework\TestCase`
|
||
- Mock Medoo: `$this->createMock(\medoo::class)`
|
||
- AAA pattern: Arrange, Act, Assert
|
||
- Tests mirror source structure: `tests/Unit/Domain/{Module}/{Class}Test.php`
|
||
|
||
## Workflow
|
||
|
||
When user says **"KONIEC PRACY"**, run `/koniec-pracy` (see `.claude/commands/koniec-pracy.md`).
|
||
|
||
Before starting implementation, review current state of docs.
|
||
|
||
## Key Documentation
|
||
- `docs/MEMORY.md` — project memory: known issues, confirmed patterns, ORM pitfalls, caching conventions
|
||
- `docs/PROJECT_STRUCTURE.md` — current architecture, layers, cache, entry points, integrations
|
||
- `docs/DATABASE_STRUCTURE.md` — full database schema
|
||
- `docs/TESTING.md` — test suite guide and structure
|
||
- `docs/FORM_EDIT_SYSTEM.md` — form system architecture
|
||
- `docs/CHANGELOG.md` — version history
|
||
- `api-docs/api-reference.json` — REST API documentation (ordersPRO)
|
||
- `api-docs/index.html` — REST API documentation (ordersPRO)
|
||
- `docs/UPDATE_INSTRUCTIONS.md` — how to build client update packages
|
||
|
||
## Za każdym razem jak próbujesz sprawdzić jakiś plik z logami spróbuj go najpierw pobrać z serwera FTP
|
||
|
||
## Wszystkie pliki które tworzysz jako pomocnicze, np build_0330.ps1 czy build-update.ps1 twórz w folderze temp |