- Add cached frontend methods to existing Domain repositories (allSettings, getSingleValue, defaultLanguage, activeLanguages, translations) - Convert front\factory\Settings and Languages to facades delegating to Domain repositories - Fix get_single_settings_value() - was hardcoded to 'firm_name', now uses $param correctly - Add CacheHandler stub methods (get/set/exists) to test bootstrap - Establish architectural rule: Domain classes are shared between admin and frontend Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
479 lines
20 KiB
Markdown
479 lines
20 KiB
Markdown
# Plan refaktoryzacji frontendu shopPRO
|
||
|
||
## Kontekst
|
||
|
||
Panel administratora (33 moduły) został w pełni zmigrowany na architekturę Domain + DI + Controllers (ver. 0.237–0.277). Teraz kolej na frontend: klasy `front/`, `shop/`, `cms/`, klasy utility z `autoload/` oraz szablony `templates/`.
|
||
|
||
**Cel:** przenieść logikę biznesową z warstwy frontendowej do warstwy domenowej (`Domain/`), zachowując kompatybilność wsteczną przez fasady. Zastosować te same wzorce co w adminie (DI, repozytoria/serwisy, testy PHPUnit).
|
||
|
||
---
|
||
|
||
## Inwentaryzacja — co istnieje
|
||
|
||
### front/controls/ (8 klas — handlery requestów)
|
||
| Klasa | Status | Logika biznesowa |
|
||
|-------|--------|-----------------|
|
||
| Site | Router główny | route(), check_url_params(), title() |
|
||
| ShopBasket | MIXED | Operacje koszyka, add/remove/quantity, checkout |
|
||
| ShopClient | Fasada | Deleguje do factory |
|
||
| ShopOrder | KRYTYCZNY | Webhooki płatności (tPay, Przelewy24, Hotpay) — bezpośrednie operacje DB |
|
||
| ShopProduct | Fasada | lazy_loading, warehouse_message, draw_product_attributes |
|
||
| ShopProducer | Fasada | list(), products() |
|
||
| ShopCoupon | Fasada | use_coupon(), delete_coupon() |
|
||
| Newsletter | Fasada | signin(), confirm(), unsubscribe() |
|
||
|
||
### front/factory/ (20 klas — pobieranie danych + logika)
|
||
| Klasa | Status | Priorytet migracji |
|
||
|-------|--------|--------------------|
|
||
| ShopProduct | ORYGINALNA LOGIKA (~370 linii) | KRYTYCZNY — product_details(), promoted/top/new products |
|
||
| ShopOrder | ORYGINALNA LOGIKA (~180 linii) | KRYTYCZNY — basket_save() tworzy zamówienie |
|
||
| ShopClient | ORYGINALNA LOGIKA | KRYTYCZNY — login (BUG: hardcoded bypass 'Legia1916'), signup, recover |
|
||
| ShopCategory | ORYGINALNA LOGIKA | WYSOKI — złożone SQL z language fallback |
|
||
| Articles | ORYGINALNA LOGIKA | WYSOKI — złożone SQL z language fallback |
|
||
| ShopPromotion | ORYGINALNA LOGIKA | WYSOKI — silnik promocji (5 typów) |
|
||
| ShopBasket | Fasada | ŚREDNI — summary_price, count |
|
||
| ShopTransport | CZĘŚCIOWO zmigrowana | ŚREDNI — transport_methods z filtrowaniem |
|
||
| ShopPaymentMethod | ZMIGROWANA (Domain) | — |
|
||
| ShopStatuses | ZMIGROWANA (Domain) | — |
|
||
| Scontainers | ZMIGROWANA (Domain) | — |
|
||
| Newsletter | CZĘŚCIOWO zmigrowana | ŚREDNI |
|
||
| Settings | Fasada (BUG: get_single_settings_value ignoruje $param) | NISKI |
|
||
| Languages | Fasada | NISKI |
|
||
| Layouts | Fasada | NISKI |
|
||
| Banners | Fasada | NISKI |
|
||
| Menu | Fasada | NISKI |
|
||
| Pages | Fasada | NISKI |
|
||
| ShopAttribute | Fasada | NISKI |
|
||
| ShopCoupon | Model danych | NISKI |
|
||
|
||
### front/view/ (12 klas — renderowanie)
|
||
| Klasa | Status |
|
||
|-------|--------|
|
||
| Site | KRYTYCZNY — show() ~600 linii, pattern substitution engine |
|
||
| ShopCategory | VIEW z logiką routingu (infinite scroll vs pagination) |
|
||
| Articles, Banners, Languages, Menu, Newsletter, Scontainers | Czyste VIEW |
|
||
| ShopClient, ShopOrder, ShopPaymentMethod | Czyste VIEW |
|
||
| ShopTransport | PUSTA klasa (placeholder) |
|
||
|
||
### shop/ (14 klas — encje biznesowe)
|
||
| Klasa | Linii | Status | Priorytet |
|
||
|-------|-------|--------|-----------|
|
||
| Product | ~950 | KRYTYCZNY — pricing, atrybuty, search, cache, permutacje | KRYTYCZNY |
|
||
| Order | ~500+ | KRYTYCZNY — statusy, Apilo sync, emaile, webhooki | KRYTYCZNY |
|
||
| Promotion | ~200 | WYSOKI — matching aktywnych promocji + delegacja do factory | WYSOKI |
|
||
| Basket | ~80 | ŚREDNI — walidacja stanów magazynowych | ŚREDNI |
|
||
| Category | ~60 | NISKI — proste zapytania, pusty konstruktor | NISKI |
|
||
| Search | ~80 | NISKI — wrapper na szablony | NISKI |
|
||
| Coupon | ~60 | NISKI — niekompletne metody | NISKI |
|
||
| Transport | ~30 | NISKI — transport_list() | NISKI |
|
||
| PaymentMethod | — | ZMIGROWANA (fasada do Domain) | — |
|
||
| Producer | — | ZMIGROWANA (fasada do Domain) | — |
|
||
| ProductSet | — | ZMIGROWANA (fasada do Domain) | — |
|
||
| ProductAttribute | ~100 | OK — dobry caching | — |
|
||
| ProductCustomField | ~50 | OK — Redis caching | — |
|
||
| Shop | ~30 | OK — utility do cen | — |
|
||
|
||
### autoload/ root (klasy utility)
|
||
| Klasa | Linii | Status |
|
||
|-------|-------|--------|
|
||
| S | ~1130 | htacces() ~500 linii — generowanie .htaccess; reszta to utility |
|
||
| Tpl | ~90 | OK — silnik szablonów, bez zmian |
|
||
| CacheHandler | ~50 | OK — Redis wrapper |
|
||
| RedisConnection | ~40 | OK — singleton |
|
||
| Email | ~100 | OK — PHPMailer wrapper (drobne poprawki) |
|
||
| Log | ~20 | OK — audit logging |
|
||
| DbModel | ~60 | OK — base ORM |
|
||
| Cache | ~50 | LEGACY — file-based cache, rozważyć usunięcie |
|
||
| Html | ~80 | OK — form helpers |
|
||
| Image | ~100 | OK — GD wrapper |
|
||
| Mobile_Detect | — | Third-party, bez zmian |
|
||
|
||
### cms/ (1 klasa)
|
||
| Klasa | Status |
|
||
|-------|--------|
|
||
| Layout | BUG w __get() — referuje $this->data które nie istnieje |
|
||
|
||
### templates/ (75 plików w 15 modułach)
|
||
articles(8), banner(2), controls(1), menu(4), newsletter(2), scontainers(1), shop-basket(9), shop-category(6), shop-client(8), shop-coupon(1), shop-order(3), shop-producer(3), shop-product(12), shop-search(3), site(11)
|
||
|
||
### Entry points
|
||
- `index.php` — główny frontend (autoload, sesja, DB, routing, DOM post-processing)
|
||
- `ajax.php` — AJAX handler (koszyk, transport, kontakt)
|
||
- `api.php` — REST API (Ekomi CSV export)
|
||
- `download.php` — pobieranie plików
|
||
- `cron-turstmate.php` — TrustMate integracja
|
||
|
||
---
|
||
|
||
## Znane bugi do naprawy podczas refaktoringu
|
||
|
||
1. **KRYTYCZNY** `front\factory\ShopClient::login()` — hardcoded password bypass `'Legia1916'`
|
||
2. `front\factory\Settings::get_single_settings_value()` — ignoruje `$param`, zawsze zwraca `firm_name`
|
||
3. `front\factory\Newsletter::newsletter_unsubscribe()` — błędna składnia SQL w delete
|
||
4. `cms\Layout::__get()` — referuje nieistniejące `$this->data`
|
||
5. `shop\Search` — typo w use: `shop\Produt` (brak 'c')
|
||
|
||
---
|
||
|
||
## Kolejność migracji (graf zależności)
|
||
|
||
```
|
||
Settings, Languages (liście — brak zależności)
|
||
↓
|
||
Banners, Menu, Pages, Articles, Layouts (zależą od Languages)
|
||
↓
|
||
Category (zależy od Languages)
|
||
↓
|
||
Promotion (zależy od Category — rozbicie circular dep)
|
||
↓
|
||
Product Frontend (zależy od Category, Promotion, Languages)
|
||
↓
|
||
Client/Auth (standalone + security fix)
|
||
↓
|
||
Transport, Payment, Coupon (frontend serwisy)
|
||
↓
|
||
Basket (zależy od Product, Promotion, Transport, Coupon)
|
||
↓
|
||
Order Creation (zależy od Basket, Product, Transport, Payment)
|
||
↓
|
||
Payment Webhooks (zależy od Order)
|
||
↓
|
||
shop\Order instance + Apilo (zależy od Order Operations)
|
||
↓
|
||
shop\Product instance + cache (zależy od ProductFrontendService)
|
||
↓
|
||
Frontend App + Controllers (nowa warstwa DI)
|
||
↓
|
||
Site Layout Engine (zależy od wszystkiego)
|
||
↓
|
||
Entry Point Unification (index.php, ajax.php)
|
||
↓
|
||
Legacy Cleanup
|
||
```
|
||
|
||
---
|
||
|
||
## Etapy migracji
|
||
|
||
### Etap: Settings + Languages — ZREALIZOWANY
|
||
|
||
**Cel:** Dodac metody frontendowe (z cache Redis) do istniejacych repozytoriow Domain.
|
||
|
||
**DODANE METODY (do istniejacych klas):**
|
||
- `Domain/Settings/SettingsRepository` — `allSettings($skipCache)`, `getSingleValue($param)` (FIX: uzywa poprawnie $param)
|
||
- `Domain/Languages/LanguagesRepository` — `defaultLanguage()`, `activeLanguages()`, `translations($lang)`
|
||
- Testy: dopisane do `SettingsRepositoryTest` (6 testow), `LanguagesRepositoryTest` (7 testow)
|
||
|
||
**ZMIANA:**
|
||
- `front/factory/Settings` → fasada delegujaca do `SettingsRepository`
|
||
- `front/factory/Languages` → fasada delegujaca do `LanguagesRepository`
|
||
- `tests/bootstrap.php` — uzupelniony stub CacheHandler o `get()`/`set()`/`exists()`
|
||
|
||
**BUG FIX:** `get_single_settings_value()` — zmiana `['param' => 'firm_name']` na `['param' => $param]`
|
||
|
||
---
|
||
|
||
### Etap: Category Frontend Service
|
||
|
||
**Cel:** Migracja `front\factory\ShopCategory` do Domain.
|
||
|
||
**NOWE:**
|
||
- `Domain/Category/CategoryFrontendService.php` — `getCategorySort()`, `categoryName()`, `categoryUrl()`, `blogCategoryProducts()`, `categoryProducts()`, `productsId()` (złożone SQL z sortowaniem/language fallback/paginacją), `categoryDetails()`, `categoriesDetails()` (rekurencyjne), `categoryProductsCount()`
|
||
- Testy: `CategoryFrontendServiceTest`
|
||
|
||
**ZMIANA:**
|
||
- `front/factory/ShopCategory` → fasada
|
||
- `front/factory/ShopProduct::product_categories()` → deleguje do `CategoryFrontendService`
|
||
|
||
---
|
||
|
||
### Etap: Banners, Menu, Pages, Articles, Layouts Frontend Services
|
||
|
||
**Cel:** Migracja pozostałych fabryk "liściowych".
|
||
|
||
**NOWE:**
|
||
- `Domain/Banner/BannerFrontendService.php` — `mainBanner()`, `banners()` (filtrowanie po datach)
|
||
- `Domain/Menu/MenuFrontendService.php` — `menuDetails()`, `menuPages()` (rekurencja)
|
||
- `Domain/Pages/PagesFrontendService.php` — `pageDetails()`, `mainPageId()`, `langUrl()`, `pageSort()`
|
||
- `Domain/Article/ArticleFrontendService.php` — `articleDetails()`, `news()`, `pageArticles()`, `pageArticlesCount()`, `generateTableOfContents()`, `generateHeadersIds()`
|
||
- `Domain/Layouts/LayoutsFrontendService.php` — `activeLayout()`, `articleLayout()`, `productLayout()`, `categoryLayout()`, `defaultLayout()`, `categoryDefaultLayout()`
|
||
- Testy: 5 plików testowych
|
||
|
||
**ZMIANA:**
|
||
- `front/factory/Banners`, `Menu`, `Pages`, `Articles`, `Layouts` → fasady
|
||
|
||
**BUG FIX:** `cms\Layout::__get()` — poprawka referencji do `$this->data`
|
||
|
||
---
|
||
|
||
### Etap: Promotion Engine (rozbicie circular dependency)
|
||
|
||
**Cel:** Przeniesienie silnika promocji do Domain. Rozbicie cyklicznej zależności `shop\Promotion ↔ front\factory\ShopPromotion`.
|
||
|
||
**Obecna zależność cykliczna:**
|
||
```
|
||
shop\Promotion::find_promotion() → front\factory\ShopPromotion::promotion_type_XX()
|
||
front\factory\ShopPromotion::promotion_type_XX() → shop\Product::is_product_on_promotion()
|
||
```
|
||
|
||
**Rozwiązanie:** Wszystko w jednym serwisie `PromotionFrontendService`.
|
||
|
||
**NOWE:**
|
||
- `Domain/Promotion/PromotionFrontendService.php`:
|
||
- `getActivePromotions()` (z `shop\Promotion`)
|
||
- `applyPromotions(array $basket)` (z `shop\Promotion::find_promotion()`)
|
||
- `private applyType01..05()` (z `front\factory\ShopPromotion`)
|
||
- `private isProductOnPromotion()` (z `shop\Product` — proste zapytanie)
|
||
- Testy: `PromotionFrontendServiceTest` (7 typów promocji + brak aktywnych)
|
||
|
||
**ZMIANA:**
|
||
- `shop/Promotion` → fasada do `PromotionFrontendService::applyPromotions()`
|
||
- `front/factory/ShopPromotion` → fasada
|
||
|
||
---
|
||
|
||
### Etap: Product Frontend Service
|
||
|
||
**Cel:** Migracja `front\factory\ShopProduct` i statycznych metod `shop\Product` do Domain.
|
||
|
||
**NOWE:**
|
||
- `Domain/Product/ProductFrontendService.php`:
|
||
- Z `front\factory\ShopProduct`: `productDetails()` (~330 linii z Redis), `promotedProducts()`, `topProducts()`, `newProducts()`, `productUrl()`, `getMinimalPrice()`, `isProductActive()`, `getProductSku()`, `getProductEan()`, `productImage()`, `productWp()`, `randomProducts()`, `warehouseMessageZero()`, `warehouseMessageNonzero()`
|
||
- Z `shop\Product` (statyczne): `isProductOnPromotion()`, `getProductImg()`, `getProductUrl()`, `addVisit()`, `productSetsForBasket()`, `searchProductsByName()`, `searchProductByNameAjax()`
|
||
- Testy: `ProductFrontendServiceTest`
|
||
|
||
**ZMIANA:**
|
||
- `front/factory/ShopProduct` → fasada
|
||
- `shop/Product` statyczne metody → fasady do `ProductFrontendService`
|
||
|
||
**UWAGA:** Konstruktor `shop\Product`, `getFromCache()`, `calculate_basket_product_price()` — zostają na razie (instancyjne, używane w szablonach). Migracja w etapie "Product Instance + Cache".
|
||
|
||
---
|
||
|
||
### Etap: Client Authentication (Security Fix)
|
||
|
||
**Cel:** Migracja `front\factory\ShopClient` + NAPRAWIENIE hardcoded password bypass.
|
||
|
||
**NOWE:**
|
||
- `Domain/Client/ClientFrontendService.php`:
|
||
- `login()` — **BEZ** bypassa 'Legia1916', z opcjonalną migracją md5 → password_hash
|
||
- `signup()`, `registerConfirm()`, `sendPasswordRecovery()`, `resetPassword()`
|
||
- `clientDetails()`, `clientOrders()`
|
||
- CRUD adresów: `saveAddress()`, `deleteAddress()`, `getAddresses()`, `markAddressAsCurrent()`
|
||
- Testy: `ClientFrontendServiceTest` — **KRYTYCZNY test: login z 'Legia1916' NIE przechodzi**
|
||
|
||
**ZMIANA:**
|
||
- `front/factory/ShopClient` → fasada
|
||
- `front/controls/ShopClient` → deleguje do serwisu
|
||
|
||
---
|
||
|
||
### Etap: Transport, Payment, Coupon Frontend Services
|
||
|
||
**Cel:** Frontend serwisy dla transportu, płatności i kuponów.
|
||
|
||
**NOWE:**
|
||
- `Domain/Transport/TransportFrontendService.php` — `transportMethods()` (filtrowanie WP, free delivery), `transportCost()`, `transportDetails()`
|
||
- `Domain/PaymentMethod/PaymentMethodFrontendService.php` — `activePaymentMethods()`, `paymentMethodsByTransport()`, `paymentMethodDetails()`
|
||
- `Domain/Coupon/CouponFrontendService.php` — `validateCoupon()`, `applyCoupon()`, `markCouponUsed()`
|
||
- Testy: 3 pliki testowe
|
||
|
||
**ZMIANA:**
|
||
- `front/factory/ShopTransport` → fasada
|
||
- `front/factory/ShopCoupon` → fasada
|
||
- `shop/Coupon` → fasada
|
||
- `shop/Transport` → fasada
|
||
|
||
---
|
||
|
||
### Etap: Basket Service
|
||
|
||
**Cel:** Migracja logiki koszyka do `Domain\Basket\BasketService`.
|
||
|
||
**NOWE:**
|
||
- `Domain/Basket/BasketService.php`:
|
||
- `addProduct()`, `removeProduct()`, `changeQuantity()`, `increaseQuantity()`, `decreaseQuantity()`
|
||
- `summaryPrice()`, `countProducts()`, `countProductsText()`
|
||
- `validateStock()` (z `shop\Basket::check_product_quantity_in_stock()`)
|
||
- `calculateProductPrice()` (z `shop\Product::calculate_basket_product_price()` ~112 linii)
|
||
- Testy: `BasketServiceTest` (pricing z promocjami/kuponami, walidacja stanów)
|
||
|
||
**ZMIANA:**
|
||
- `front/factory/ShopBasket` → fasada
|
||
- `front/controls/ShopBasket` — wewnętrznie używa `BasketService`
|
||
- `shop/Basket` → fasada
|
||
- `shop/Product::calculate_basket_product_price()` → fasada
|
||
|
||
---
|
||
|
||
### Etap: shop\Product Instance + Cache
|
||
|
||
**Cel:** Refaktoring konstruktora `shop\Product` i `getFromCache()`.
|
||
|
||
**NOWE:**
|
||
- `Domain/Product/ProductDataLoader.php`:
|
||
- `loadFull(int $productId, ?string $langId, ?string $permutationHash)` — ładowanie pełnych danych produktu
|
||
- `loadCached()` — Redis cache wrapper
|
||
- Testy: `ProductDataLoaderTest`
|
||
|
||
**ZMIANA:**
|
||
- `shop/Product` — konstruktor i `getFromCache()` delegują do `ProductDataLoader`
|
||
- ArrayAccess interface zachowany (szablony dalej używają `$product->property`)
|
||
|
||
---
|
||
|
||
### Etap: Order Creation Frontend Service
|
||
|
||
**Cel:** Migracja `front\factory\ShopOrder::basket_save()` (~180 linii).
|
||
|
||
**NOWE:**
|
||
- `Domain/Order/OrderFrontendService.php`:
|
||
- `createOrder()` — tworzenie zamówienia z koszyka (walidacja, kalkulacja cen, insert, redukcja stanów, obsługa kuponu, wysyłka emaili, auto-status dla pobrania)
|
||
- `generateOrderNumber()` — format YYYY/MM/NNN
|
||
- `orderDetails()`, `orderIdByHash()`, `orderHashById()`
|
||
- Testy: `OrderFrontendServiceTest`
|
||
|
||
**ZMIANA:**
|
||
- `front/factory/ShopOrder` → fasada
|
||
|
||
---
|
||
|
||
### Etap: Payment Webhook Service
|
||
|
||
**Cel:** Wyodrębnienie webhooków płatności z `front\controls\ShopOrder`.
|
||
|
||
**NOWE:**
|
||
- `Domain/Payment/PaymentWebhookService.php`:
|
||
- `processTpay(array $params)` — weryfikacja tPay
|
||
- `processPrzelewy24(array $params)` — weryfikacja przez API + walidacja kwoty
|
||
- `processHotpay(array $params)` — walidacja SHA256 hash
|
||
- `private markOrderPaid()` — wspólna logika (update status + email + Apilo sync)
|
||
- Testy: `PaymentWebhookServiceTest`
|
||
|
||
**ZMIANA:**
|
||
- `front/controls/ShopOrder` — webhooki stają się thin wrappers
|
||
|
||
**POPRAWA:** Zamiana `file_put_contents('tpay.txt')` na `\Log::save_log()`
|
||
|
||
---
|
||
|
||
### Etap: shop\Order Instance + Apilo Service
|
||
|
||
**Cel:** Refaktoring `shop\Order` instancyjnych metod + wyodrębnienie integracji Apilo.
|
||
|
||
**NOWE:**
|
||
- `Domain/Integrations/ApiloService.php`:
|
||
- `syncPayment()`, `syncStatus()`, `processQueue()`
|
||
- `private queueSync()`, `private loadQueue()`, `private saveQueue()`
|
||
- `Domain/Order/OrderOperationsService.php`:
|
||
- `setAsPaid()`, `setAsUnpaid()`, `updateStatus()`, `sendStatusChangeEmail()`, `resendConfirmationEmail()`
|
||
- Testy: `ApiloServiceTest`, `OrderOperationsServiceTest`
|
||
|
||
**ZMIANA:**
|
||
- `shop/Order` instancyjne metody → fasady do `OrderOperationsService`
|
||
- Konstruktor i ArrayAccess bez zmian
|
||
|
||
---
|
||
|
||
### Etap: Frontend App + Controllers (DI layer)
|
||
|
||
**Cel:** Stworzenie `front\App` (wzorowanego na `admin\App`) z mapą kontrolerów i DI.
|
||
|
||
**NOWE:**
|
||
- `autoload/front/App.php` — `render()`, `handleAjax()`, `getControllerFactories()` (DI wiring)
|
||
- `autoload/front/Controllers/ShopBasketController.php` — DI z `BasketService`, `ProductFrontendService`
|
||
- `autoload/front/Controllers/ShopOrderController.php` — DI z `OrderFrontendService`, `PaymentWebhookService`
|
||
- `autoload/front/Controllers/ShopClientController.php` — DI z `ClientFrontendService`
|
||
- Testy: 3 pliki testowe kontrolerów
|
||
|
||
**ZMIANA:**
|
||
- `front/controls/ShopBasket`, `ShopOrder`, `ShopClient` → delegują do nowych kontrolerów
|
||
|
||
---
|
||
|
||
### Etap: Site Layout Engine
|
||
|
||
**Cel:** Refaktoring `front\view\Site::show()` (~600 linii) na testowalny `LayoutEngine`.
|
||
|
||
**NOWE:**
|
||
- `autoload/front/View/LayoutEngine.php`:
|
||
- `resolveLayout(array $page, array $params)` — wybór layoutu (product > category > article > page > default)
|
||
- `processPatterns(string $html, array $context)` — zamiana tagów szablonowych
|
||
- Osobne prywatne metody: `replaceCategories()`, `replaceProducts()`, `replaceMenus()`, `replaceLanguageTags()`, `replaceBanners()`, `replaceArticles()`, `replaceContainers()`, `replaceMetaTags()`, etc.
|
||
- Testy: `LayoutEngineTest`
|
||
|
||
**ZMIANA:**
|
||
- `front/view/Site::show()` → thin wrapper na `LayoutEngine`
|
||
|
||
---
|
||
|
||
### Etap: Entry Point Unification
|
||
|
||
**Cel:** Ujednolicenie bootstrapu `index.php` i `ajax.php`.
|
||
|
||
**NOWE:**
|
||
- `autoload/front/Bootstrap.php` — `init()` (autoloader, config, sesja, DB, lang/settings)
|
||
- `autoload/front/PostProcessor.php` — ekstrakcja DOM manipulacji z `index.php` (GTM, Facebook Pixel, WebP, lazy loading)
|
||
|
||
**ZMIANA:**
|
||
- `index.php` → uproszczony: `Bootstrap::init()` → `App::render()` → `PostProcessor::process()`
|
||
- `ajax.php` → uproszczony: `Bootstrap::init()` → `App::handleAjax()`
|
||
|
||
---
|
||
|
||
### Etap: Legacy Cleanup
|
||
|
||
**Cel:** Finalne porządki.
|
||
|
||
**USUNIĘCIE:**
|
||
- Martwy kod `eval()` dla `[PHP]` bloków (jeśli nieużywany)
|
||
- `class.Cache.php` (legacy file-based) jeśli wszystkie użycia przeniesione na `CacheHandler`
|
||
- Pusta klasa `front\view\ShopTransport`
|
||
|
||
**ZMIANA:**
|
||
- Dodanie `@deprecated` do wszystkich metod-fasad w `front/factory/`, `front/controls/`, `shop/`
|
||
- PHPDoc do wszystkich nowych klas Domain z `@since`
|
||
- Aktualizacja `tests/bootstrap.php`
|
||
- BUG FIX: `shop\Search` — typo `shop\Produt` → `shop\Product`
|
||
- BUG FIX: `front\factory\Newsletter::newsletter_unsubscribe()` — poprawka SQL
|
||
|
||
---
|
||
|
||
## Podsumowanie
|
||
|
||
| Etap | Zakres | Priorytet | Nowe klasy Domain | Testy |
|
||
|------|--------|-----------|-------------------|-------|
|
||
| Settings + Languages | Fundamenty | FUNDAMENT | 2 serwisy | 2 |
|
||
| Category Frontend | Kategorie | WYSOKI | 1 serwis | 1 |
|
||
| Banners/Menu/Pages/Articles/Layouts | Treści | ŚREDNI | 5 serwisów | 5 |
|
||
| Promotion Engine | Promocje | KRYTYCZNY | 1 serwis | 1 |
|
||
| Product Frontend | Produkty | KRYTYCZNY | 1 serwis | 1 |
|
||
| Client/Auth (security fix) | Klienci | KRYTYCZNY | 1 serwis | 1 |
|
||
| Transport/Payment/Coupon | Dostawa/Płatności | WYSOKI | 3 serwisy | 3 |
|
||
| Basket Service | Koszyk | WYSOKI | 1 serwis | 1 |
|
||
| Product Instance + Cache | Produkt cache | ŚREDNI | 1 loader | 1 |
|
||
| Order Creation | Zamówienia | WYSOKI | 1 serwis | 1 |
|
||
| Payment Webhooks | Webhooki | WYSOKI | 1 serwis | 1 |
|
||
| Order Instance + Apilo | Zamówienie + Apilo | ŚREDNI | 2 serwisy | 2 |
|
||
| Frontend App + Controllers | DI layer | WYSOKI | App + 3 kontrolery | 3 |
|
||
| Layout Engine | Silnik layoutu | ŚREDNI | 1 engine | 1 |
|
||
| Entry Point Unification | Entry points | ŚREDNI | Bootstrap + PostProcessor | 1 |
|
||
| Legacy Cleanup | Porządki | NISKI | — | — |
|
||
|
||
**Łącznie:** 16 etapów, ~24 nowe klasy Domain, ~25 plików testowych
|
||
|
||
### Wzorce do przestrzegania (z migracji admin)
|
||
- Konstruktor DI z `$db` (medoo)
|
||
- CacheHandler (Redis) dla cachingu — unifikacja (usunięcie starego `Cache`)
|
||
- Fasady w `shop\*` i `front\factory\*` dla kompatybilności wstecznej
|
||
- Testy PHPUnit z mockami medoo
|
||
- Namespace `\Domain\*` → `autoload/Domain/*/`
|
||
- Namespace `\front\Controllers\` → `autoload/front/Controllers/`
|
||
- **Klasy Domain sa wspolne dla admin i frontendu** — NIE tworzymy osobnych FrontendService/AdminService. Metody frontendowe (z cache Redis) dodajemy do istniejacych repozytoriow/serwisow Domain. Klasy sa ladowane lazy (instancja tworzona dopiero przy wywolaniu), wiec nie wplywaja na wydajnosc.
|
||
|
||
### Weryfikacja po każdym etapie
|
||
1. `composer test` (pełny suite PHPUnit)
|
||
2. Manualne sprawdzenie frontendu: strona główna, kategoria, produkt, koszyk, zamówienie
|
||
3. Sprawdzenie AJAX: dodawanie do koszyka, zmiana transportu, kupon
|
||
4. Sprawdzenie webhooków płatności (tPay, Przelewy24, Hotpay)
|