# Struktura Projektu shopPRO

Aktualna architektura po zakonczonej migracji na Domain-Driven Design + Dependency Injection.

## Warstwa domenowa (`autoload/Domain/`)

Kazdy modul zawiera Repository (i opcjonalnie dodatkowe klasy). Konstruktor DI z `$db` (Medoo). Metody sluza zarowno adminowi, jak i frontendowi (wspolna warstwa).

| Modul | Klasy | Uwagi |
|-------|-------|-------|
| Article | ArticleRepository | blog, aktualnosci, galerie, pliki |
| Attribute | AttributeRepository | cechy produktow + wartosci |
| Banner | BannerRepository | banery glowne + boczne, Redis cache |
| Basket | BasketCalculator | summary, count, walidacja stanow |
| Cache | CacheRepository | czyszczenie cache z poziomu admin |
| Category | CategoryRepository | drzewa kategorii, produkty w kategorii, Redis cache |
| Client | ClientRepository | CRUD, auth, adresy, zamowienia |
| Coupon | CouponRepository | kupony rabatowe, walidacja, uzycie |
| Dashboard | DashboardRepository | statystyki admin, Redis cache |
| Dictionaries | DictionariesRepository | slowniki admin |
| Integrations | IntegrationsRepository | Apilo sync, ustawienia |
| Languages | LanguagesRepository | jezyki, tlumaczenia |
| Layouts | LayoutsRepository | layouty stron, 3-level fallback |
| Newsletter | NewsletterRepository, NewsletterPreviewRenderer | subskrypcje, szablony, kolejka wysylki |
| Order | OrderRepository, OrderAdminService | CRUD, Apilo sync, webhooki platnosci, kolejka retry |
| Pages | PagesRepository | strony, menu, drzewa stron |
| PaymentMethod | PaymentMethodRepository | metody platnosci, mapowanie Apilo |
| Producer | ProducerRepository | producenci |
| Product | ProductRepository | CRUD, cache, kombinacje, zdjecia, Google Feed XML |
| ProductSet | ProductSetRepository | zestawy produktow |
| Promotion | PromotionRepository | promocje, 5 typow applyType*, silnik dopasowania |
| Scontainers | ScontainersRepository | kontenery sidebaru |
| Settings | SettingsRepository | ustawienia sklepu |
| ShopStatus | ShopStatusRepository | statusy zamowien, mapowanie Apilo |
| Transport | TransportRepository | transport, koszty, powiazanie z platnosci |
| Update | UpdateRepository | aktualizacje, migracje SQL |
| User | UserRepository | uzytkownicy admin, 2FA, logowanie |

## Warstwa admin (`autoload/admin/`)

### Router: `admin\App`
- `getControllerFactories()` — mapa kontrolerow z DI wiring
- Brak fallbacku na legacy — wszystkie moduly na nowych kontrolerach

### Kontrolery (`admin\Controllers\`) — 28 kontrolerow
ArticlesArchive, Articles, Banner, Dashboard, Dictionaries, Filemanager, Integrations, Languages, Layouts, Newsletter, Pages, ProductArchive, Scontainers, Settings, ShopAttribute, ShopCategory, ShopClients, ShopCoupon, ShopOrder, ShopPaymentMethod, ShopProducer, ShopProduct, ShopProductSets, ShopPromotion, ShopStatuses, ShopTransport, Update, Users

### Support
- `admin\Support\TableListRequestFactory` — paginacja/sortowanie tabel
- `admin\Support\Forms\FormRequestHandler` — obsluga formularzy (persist przy bledach)
- `admin\Support\Forms\FormFieldRenderer` — renderowanie pol formularzy

### ViewModels
- `admin\ViewModels\Forms\` — FormEditViewModel, FormField, FormTab, FormAction, FormFieldType
- `admin\ViewModels\Common\PaginatedTableViewModel`

### Walidacja
- `admin\Validation\FormValidator` — reguly per pole, sekcje jezykowe

## Warstwa frontend (`autoload/front/`)

### Router: `front\App`
- `route()`, `checkUrlParams()`, `getControllerFactories()`

### Layout Engine: `front\LayoutEngine`
- `show()` — zamiana tagow szablonowych (kategorie, produkty, menu, banery, artykuly, kontenery, meta)
- `contact()`, `cookieInformation()`

### Kontrolery (`front\Controllers\`) — 8 kontrolerow
Newsletter, Search, ShopBasket, ShopClient, ShopCoupon, ShopOrder, ShopProducer, ShopProduct

### Widoki (`front\Views\`) — 11 klas statycznych
Articles, Banners, Languages, Menu, Newsletter, Scontainers, ShopCategory, ShopClient, ShopPaymentMethod, ShopProduct, ShopSearch

## Warstwa API (`autoload/api/`)

REST API dla ordersPRO. Entry point: `api.php`. Stateless (bez sesji), autentykacja przez `X-Api-Key` header.

### Router: `api\ApiRouter`
- `handle()` — autentykacja → routing → dispatch
- Helpery statyczne: `sendSuccess()`, `sendError()`, `getJsonBody()`, `requireMethod()`

### Kontrolery (`api\Controllers\`)
- `OrdersApiController` — lista, szczegoly, zmiana statusu, platnosc (5 akcji)
- `ProductsApiController` — lista, szczegoly, tworzenie, aktualizacja produktow (4 akcje)
- `DictionariesApiController` — statusy, transporty, metody platnosci (3 akcje)

Dokumentacja: `docs/API.md`

## Warstwa wspoldzielona (`autoload/Shared/`)

| Klasa | Opis |
|-------|------|
| `Shared\Cache\CacheHandler` | Redis cache: get/set/delete/deletePattern |
| `Shared\Cache\RedisConnection` | Singleton polaczenia Redis |
| `Shared\Email\Email` | Wrapper PHPMailer |
| `Shared\Helpers\Helpers` | SEO, email, cache clearing, shortPrice, utility |
| `Shared\Html\Html` | Helpery HTML |
| `Shared\Image\ImageManipulator` | Obrobka obrazow GD |
| `Shared\Tpl\Tpl` | Silnik szablonow: render(), set() |

## Cache Redis

### Klucze
```
shop\product:{id}:{lang}:{permutation_hash}              — dane produktu (TTL 24h)
ProductRepository::getProductPermutationQuantityOptions:v2:{id}:{perm} — ilosc + komunikaty
ProductRepository::productSetsWhenAddToBasket:{id}       — zestawy "kupowane razem"
```

### Konwencje
- TTL domyslnie 86400 (24h)
- Dane serializowane — `unserialize()` po `get()`
- Czyszczenie: `CacheHandler::deletePattern("shop\\product:{$id}:*")`
- Czyszczenie z poziomu admin: `Shared\Helpers\Helpers::clear_product_cache($id)`
- Przycisk "Wyczysc cache" w admin: `SettingsController::clearCacheAjax()` → `flushAll()` Redis + `temp/` + `thumbs/`

## Entry pointy

| Plik | Rola |
|------|------|
| `index.php` | Frontend — autoload, sesja, DB, routing (`front\App`), layout (`front\LayoutEngine`), DOM post-processing |
| `ajax.php` | Frontend AJAX — koszyk, transport, kontakt |
| `api.php` | REST API (ordersPRO + Ekomi CSV) — router: `\api\ApiRouter`, kontrolery: `\api\Controllers\` |
| `admin/index.php` | Admin — autoload, sesja, DB, routing (`admin\App`) |
| `admin/ajax.php` | Admin AJAX |
| `cron.php` | CRON: Apilo sync (ceny/stany co 10min, cennik co 1h, retry queue) |
| `cron-turstmate.php` | TrustMate integracja |
| `cron/cron-xml.php` | Google Feed XML |
| `download.php` | Pobieranie plikow |

### Autoloader
Kazdy entry point rejestruje `__autoload_my_classes()`:
1. Probuje `autoload/{namespace}/class.{ClassName}.php` (legacy format)
2. Probuje `autoload/{namespace}/{ClassName}.php` (PSR-4 format)

### Routing frontend (index.php)
Przed `front\App::route()`:
1. Sprawdza tabele `pp_redirects` → 301 redirect
2. Sprawdza tabele `pp_routes` → regex pattern → destination

### Newsletter queue
`index.php` wywoluje `$newsletterRepo->sendQueued()` na koncu kazdego requestu frontendowego (limit 1 mail/request).

## Integracje zewnetrzne

### Apilo (cron.php)
- Synchronizacja cen/stanow produktow (co 10 min)
- Synchronizacja cennika (co 1h)
- Kolejka retry: `temp/apilo-sync-queue.json` — `OrderAdminService::processApiloSyncQueue()`
- Mapowanie statusow i platnosci przez tabele `pp_shop_statuses` i `pp_shop_payment_methods`

### Webhooki platnosci (front\Controllers\ShopOrderController)
- tPay, Przelewy24, Hotpay — ujednolicone: `set_as_paid` + `update_status`

## Biblioteki (`libraries/`)

- `medoo/medoo.php` — Medoo ORM (`$mdb`)
- `rb.php` — RedBeanPHP ORM (`\R::`, `$pdo`)
- `phpmailer/` — PHPMailer

## Wzorce architektoniczne

### DI zamiast global
```php
// Kontroler wiring (w admin\App lub front\App)
$repo = new \Domain\Example\ExampleRepository($mdb);
$controller = new \admin\Controllers\ExampleController($repo);
```

### Wspolna warstwa Domain
Metody frontendowe (z Redis cache) dodawane do istniejacych repozytoriow — NIE tworzymy osobnych FrontendService/AdminService.

### Klasy View — statyczne, bezstanowe
`front\Views\*` — nie wymagaja DI. Czyste funkcje: dane wchodza, HTML wychodzi.

### Kontrolery — instancyjne z DI
`Controllers\*` — repozytoria wstrzykiwane przez konstruktor.

### Nazewnictwo plikow
- Nowe: `ClassName.php`
- Legacy (pozostalosci): `class.ClassName.php`
- Autoloader obsluguje oba formaty

### Nazewnictwo katalogow
- Nowe: z duzej litery (`Views/`, `Controllers/`)
- Namespace `\admin\` z malej (bo katalog `admin/` jest z malej na serwerze Linux)
- NIE uzywac `\Admin\` (duze A)
