Refactor code structure for improved readability and maintainability
This commit is contained in:
@@ -8,7 +8,6 @@ Gdy użytkownik napisze `KONIEC PRACY`, wykonaj kolejno:
|
||||
2. Aktualizacja dokumentacji technicznej, jeśli zmiany tego wymagają:
|
||||
- `docs/DATABASE_STRUCTURE.md`
|
||||
- `docs/PROJECT_STRUCTURE.md`
|
||||
- `docs/FRONTEND_REFACTORING_PLAN.md`
|
||||
- `docs/FORM_EDIT_SYSTEM.md`
|
||||
- `docs/CHANGELOG.md`
|
||||
- `docs/TESTING.md`
|
||||
@@ -22,14 +21,7 @@ Przed rozpoczęciem implementacji sprawdź aktualną zawartość:
|
||||
|
||||
- `docs/DATABASE_STRUCTURE.md`
|
||||
- `docs/PROJECT_STRUCTURE.md`
|
||||
- `docs/REFACTORING_PLAN.md`
|
||||
- `docs/FRONTEND_REFACTORING_PLAN.md`
|
||||
- `docs/CHANGELOG.md`
|
||||
- `docs/TESTING.md`
|
||||
|
||||
To ma pomóc zachować spójność zmian i dokumentacji.
|
||||
|
||||
|
||||
## INNE
|
||||
|
||||
Przejdźmy teraz do refaktoringu wszystkiego co związane z https://shoppro.project-dc.pl/admin/shop_product/, nowe widoki, klasy (usuwanie starych), poprawa routingu, przeszukanie innych klas pod względem zależności. Zapisz plan i przedstaw mi go a po akceptacji realizuj krok po kroku w trybie Human In The Loop
|
||||
62
CLAUDE.md
62
CLAUDE.md
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## 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 is undergoing a migration from legacy architecture to Domain-Driven Design with Dependency Injection.
|
||||
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).
|
||||
|
||||
## PHP Version Constraint
|
||||
|
||||
@@ -50,21 +50,27 @@ shopPRO/
|
||||
│ ├── 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
|
||||
│ ├── admin/ # Admin panel layer
|
||||
│ │ └── Controllers/ # DI controllers (\admin\Controllers\)
|
||||
│ ├── front/ # Frontend layer
|
||||
│ │ ├── App.php # Frontend router (\front\App)
|
||||
│ │ ├── LayoutEngine.php # Layout engine (\front\LayoutEngine)
|
||||
│ │ ├── Controllers/ # DI controllers (\front\Controllers\)
|
||||
│ │ └── Views/ # Static views (\front\Views\)
|
||||
│ └── shop/ # EMPTY — all legacy classes migrated to Domain\
|
||||
│ │ ├── 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
|
||||
├── libraries/ # Third-party libraries (Medoo, RedBeanPHP, PHPMailer)
|
||||
├── tests/ # PHPUnit tests
|
||||
│ ├── bootstrap.php
|
||||
│ ├── stubs/ # Test stubs (CacheHandler, Helpers, ShopProduct)
|
||||
@@ -89,25 +95,27 @@ Custom autoloader in each entry point (not Composer autoload at runtime). Tries
|
||||
2. `autoload/{namespace}/{ClassName}.php` (PSR-4 style, fallback)
|
||||
|
||||
### Namespace Conventions (case-sensitive on Linux!)
|
||||
- `\Domain\` → `autoload/Domain/` (uppercase D — new directory)
|
||||
- `\admin\Controllers\` → `autoload/admin/Controllers/` (lowercase a — existing directory)
|
||||
- `\Domain\` → `autoload/Domain/` (uppercase D)
|
||||
- `\admin\Controllers\` → `autoload/admin/Controllers/` (lowercase a)
|
||||
- `\Shared\` → `autoload/Shared/`
|
||||
- `\front\` → `autoload/front/`
|
||||
- ~~`\shop\`~~ → `autoload/shop/` (EMPTY — all classes migrated to `\Domain\`)
|
||||
- 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 for admin + frontend)
|
||||
### Domain-Driven Architecture (migration complete)
|
||||
|
||||
All modules use this pattern:
|
||||
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, 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::route()` via `$newControllers` map
|
||||
- Wired in `admin\App::getControllerFactories()`
|
||||
|
||||
**Frontend Controllers** (`autoload/front/Controllers/`):
|
||||
- DI via constructor
|
||||
@@ -133,12 +141,20 @@ All modules use this pattern:
|
||||
- Full schema: `docs/DATABASE_STRUCTURE.md`
|
||||
|
||||
### Form Edit System
|
||||
Universal form system for admin edit views. Uses ViewModels (`FormEditViewModel`, `FormField`, `FormTab`, `FormAction`), validation (`FormValidator`), and rendering (`FormFieldRenderer`). Template: `admin/templates/components/form-edit.php`. Docs: `docs/FORM_EDIT_SYSTEM.md`.
|
||||
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
|
||||
@@ -161,6 +177,11 @@ $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)
|
||||
@@ -175,7 +196,7 @@ $controller = new \admin\Controllers\ExampleController($repo);
|
||||
|
||||
When user says **"KONIEC PRACY"**, execute in order:
|
||||
1. Run tests
|
||||
2. Update documentation if needed: `docs/DATABASE_STRUCTURE.md`, `docs/PROJECT_STRUCTURE.md`, `docs/FRONTEND_REFACTORING_PLAN.md`, `docs/FORM_EDIT_SYSTEM.md`, `docs/CHANGELOG.md`, `docs/TESTING.md`
|
||||
2. Update documentation if needed: `docs/DATABASE_STRUCTURE.md`, `docs/PROJECT_STRUCTURE.md`, `docs/FORM_EDIT_SYSTEM.md`, `docs/CHANGELOG.md`, `docs/TESTING.md`
|
||||
3. Prepare update package per `docs/UPDATE_INSTRUCTIONS.md`
|
||||
4. Commit
|
||||
5. Push
|
||||
@@ -184,12 +205,9 @@ Before starting implementation, review current state of docs (see AGENTS.md for
|
||||
|
||||
## Key Documentation
|
||||
- `docs/MEMORY.md` — project memory: known issues, confirmed patterns, ORM pitfalls, caching conventions
|
||||
- `docs/PROJECT_STRUCTURE.md` — detailed project structure and module status
|
||||
- `docs/REFACTORING_PLAN.md` — Domain migration plan and status
|
||||
- `docs/FRONTEND_REFACTORING_PLAN.md` — frontend migration plan (mostly complete)
|
||||
- `docs/LEGACY_SHOP_REFACTORING_PLAN.md` — plan usunięcia 12 legacy klas z `autoload/shop/` (UKOŃCZONY — wszystkie 12 klas usunięte)
|
||||
- `docs/PROJECT_STRUCTURE.md` — current architecture, layers, cache, entry points, integrations
|
||||
- `docs/DATABASE_STRUCTURE.md` — full database schema
|
||||
- `docs/TESTING.md` — test suite status and history
|
||||
- `docs/TESTING.md` — test suite guide and structure
|
||||
- `docs/FORM_EDIT_SYSTEM.md` — form system architecture
|
||||
- `docs/CHANGELOG.md` — version history
|
||||
- `docs/UPDATE_INSTRUCTIONS.md` — how to build client update packages
|
||||
|
||||
2049
docs/CLASS_CATALOG.md
Normal file
2049
docs/CLASS_CATALOG.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,634 +0,0 @@
|
||||
# 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 | ZMIGROWANY do `front\App` — usunięty | route(), checkUrlParams(), title(), pageTitle(), getControllerFactories() |
|
||||
| ShopBasket | ZMIGROWANY do `front\Controllers\ShopBasketController` | Operacje koszyka, add/remove/quantity, checkout |
|
||||
| ShopClient | ZMIGROWANY do `front\Controllers\ShopClientController` | Logowanie, rejestracja, odzyskiwanie hasla, adresy, zamowienia |
|
||||
| ShopOrder | ZMIGROWANY do `front\Controllers\ShopOrderController` | Webhooki płatności + order details |
|
||||
| ShopProduct | ZMIGROWANY — usunięty | logika w ProductRepository + szablony |
|
||||
| ShopProducer | ZMIGROWANY do `front\Controllers\ShopProducerController` | list(), products() |
|
||||
| ShopCoupon | ZMIGROWANY do `front\Controllers\ShopCouponController` | use_coupon(), delete_coupon() |
|
||||
| Newsletter | ZMIGROWANY do `front\Controllers\NewsletterController` | signin(), confirm(), unsubscribe() |
|
||||
|
||||
### ~~front/factory/~~ (20 klas — USUNIĘTY w ver. 0.292, wszystkie zmigrowane do Domain)
|
||||
| Klasa | Status | Priorytet migracji |
|
||||
|-------|--------|--------------------|
|
||||
| ShopProduct | ZMIGROWANA do `ProductRepository` — usunięta | — |
|
||||
| ShopOrder | ZMIGROWANA do `OrderRepository` — usunięta | — |
|
||||
| ShopClient | ZMIGROWANA do `ClientRepository` + `ShopClientController` — usunięta | — |
|
||||
| ShopCategory | ZMIGROWANA do `CategoryRepository` — usunięta | — |
|
||||
| Articles | ZMIGROWANA do `ArticleRepository` — usunięta | — |
|
||||
| ShopPromotion | ZMIGROWANA do `PromotionRepository` — usunięta | — |
|
||||
| ShopBasket | ZMIGROWANA do `Domain\Basket\BasketCalculator` — usunięta | — |
|
||||
| ShopTransport | ZMIGROWANA do `TransportRepository` — usunięta | — |
|
||||
| ShopPaymentMethod | ZMIGROWANA do `PaymentMethodRepository` — usunięta | — |
|
||||
| ShopStatuses | ZMIGROWANA do `ShopStatusRepository` — usunięta | — |
|
||||
| Scontainers | ZMIGROWANA (Domain) — usunięta | — |
|
||||
| Newsletter | ZMIGROWANA (Domain) — usunięta | — |
|
||||
| Settings | ZMIGROWANA do `SettingsRepository` — usunięta | — |
|
||||
| Languages | USUNIĘTA — przepięta na Domain | — |
|
||||
| Layouts | USUNIETA — przepieta na Domain | — |
|
||||
| Banners | USUNIETA — przepieta na Domain | — |
|
||||
| Menu | USUNIETA — przepieta na Domain | — |
|
||||
| Pages | USUNIETA — przepieta na Domain | — |
|
||||
| ShopAttribute | ZMIGROWANA (Domain) — usunięta | — |
|
||||
| ShopCoupon | ZMIGROWANA do `CouponRepository` — usunięta | — |
|
||||
|
||||
### front/view/ (12 klas — renderowanie)
|
||||
| Klasa | Status |
|
||||
|-------|--------|
|
||||
| Site | ZMIGROWANY do `front\LayoutEngine` — usunięty |
|
||||
| ShopCategory | PRZENIESIONA do `front\Views\ShopCategory` |
|
||||
| Articles | Czyste VIEW |
|
||||
| Scontainers | PRZENIESIONA do `front\Views\Scontainers` |
|
||||
| Menu | PRZENIESIONA do `front\Views\Menu` |
|
||||
| Banners | PRZENIESIONA do `front\Views\Banners` |
|
||||
| Languages, Newsletter | PRZENIESIONE do `front\Views\` (nowy namespace) |
|
||||
| ShopClient | PRZENIESIONA do `front\Views\ShopClient` |
|
||||
| ShopOrder | ZMIGROWANA do `ShopOrderController` — usunięta |
|
||||
| ShopPaymentMethod | USUNIĘTA (pusta klasa) |
|
||||
| ShopTransport | USUNIĘTA (pusta klasa) |
|
||||
|
||||
### 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 | — | USUNIETA — callery na PaymentMethodRepository | — |
|
||||
| Producer | — | USUNIETA (callery na ProducerRepository) | — |
|
||||
| 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 | ~960 | PRZENIESIONA do Shared\Helpers\Helpers — 12 metod usunieto, bug fix |
|
||||
| Tpl | ~90 | PRZENIESIONA do `Shared\Tpl\Tpl` — DRY render(), bug fix branch 3, ~135 plikow przepietych |
|
||||
| CacheHandler | ~50 | ZMIGROWANY do `Shared\Cache\CacheHandler` — wrappery usuniete |
|
||||
| RedisConnection | ~40 | ZMIGROWANY do `Shared\Cache\RedisConnection` — wrappery usuniete |
|
||||
| Email | ~100 | OK — PHPMailer wrapper (drobne poprawki) |
|
||||
| Log | ~20 | OK — audit logging |
|
||||
| DbModel | — | USUNIETA — logika wbudowana w `shop\Promotion` |
|
||||
| Cache | ~50 | USUNIETA — zastapiona CacheHandler (Redis) w ver. 0.282 |
|
||||
| Html | ~80 | OK — form helpers |
|
||||
| Image | ~100 | OK — GD wrapper |
|
||||
| Mobile_Detect | — | USUNIETA — przestarzala detekcja UA, zastapiona responsive design |
|
||||
|
||||
### cms/ (1 klasa)
|
||||
| Klasa | Status |
|
||||
|-------|--------|
|
||||
| Layout | USUNIETA — zastapiona przez `$layoutsRepo->find()` |
|
||||
|
||||
### 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'`~~ **NAPRAWIONE** — `ClientRepository::authenticate()` bez bypass
|
||||
2. ~~`front\factory\Settings::get_single_settings_value()` — ignoruje `$param`, zawsze zwraca `firm_name`~~ **NAPRAWIONE** — klasa usunięta, `SettingsRepository::getSingleValue()` z poprawnym `$param`
|
||||
3. ~~`front\factory\Newsletter::newsletter_unsubscribe()` — błędna składnia SQL w delete~~ **NAPRAWIONE** — `NewsletterRepository::unsubscribe()` z poprawną składnią medoo `delete()`
|
||||
4. ~~`cms\Layout::__get()` — referuje nieistniejące `$this->data`~~ **NAPRAWIONE** — klasa usunięta, zastąpiona przez `$layoutsRepo->find()`
|
||||
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: Newsletter Frontend — ZREALIZOWANY
|
||||
|
||||
**Cel:** Przeniesienie logiki frontendowej z `front\factory\Newsletter` do `Domain\Newsletter\NewsletterRepository`. Migracja view do nowego namespace `front\Views`.
|
||||
|
||||
**DODANE METODY (do istniejącej klasy `NewsletterRepository`):**
|
||||
- `unsubscribe(string $hash): bool` — FIX: poprawna składnia medoo `delete()` (2 args zamiast 3)
|
||||
- `confirmSubscription(string $hash): bool`
|
||||
- `getHashByEmail(string $email): ?string`
|
||||
- `removeByEmail(string $email): bool`
|
||||
- `signup(string $email, string $serverName, bool $ssl, array $settings): bool`
|
||||
- `sendQueued(int $limit, string $serverName, bool $ssl, string $unsubscribeLabel): bool`
|
||||
- Konstruktor rozszerzony o opcjonalne: `ArticleRepository`, `NewsletterPreviewRenderer` (lazy-init)
|
||||
- Testy: 10 nowych testów w `NewsletterRepositoryTest`
|
||||
|
||||
**ZMIANA:**
|
||||
- `front/factory/Newsletter` → USUNIĘTA (logika przeniesiona do `NewsletterRepository`)
|
||||
- `front/view/Newsletter` → USUNIĘTA, zastąpiona przez `front/Views/Newsletter` (nowy namespace, bez `class.` prefix)
|
||||
- `front/controls/Newsletter` → thin wrapper na `NewsletterRepository`
|
||||
- `front/view/Site::show()` → `\front\Views\Newsletter::render()`
|
||||
- `index.php` → `$newsletterRepo->sendQueued()`
|
||||
- `front/factory/ShopClient` (4 miejsca) → `NewsletterRepository::templateByName()`
|
||||
- `tests/bootstrap.php` — dodane stuby: `S::email_check()`, `S::get_session()`, `S::set_session()`
|
||||
|
||||
**BUG FIX:** `newsletter_unsubscribe()` — medoo `delete()` wywoływane z 3 argumentami zamiast 2
|
||||
|
||||
---
|
||||
|
||||
### Etap: Category Frontend Service — ZREALIZOWANY
|
||||
|
||||
**Cel:** Migracja `front\factory\ShopCategory` i `front\view\ShopCategory` do Domain + Views.
|
||||
|
||||
**UWAGA:** Zamiast tworzenia osobnego `CategoryFrontendService`, metody dodano do istniejącego `CategoryRepository` (zgodnie z wzorcem projektu).
|
||||
|
||||
**DODANE METODY (do istniejącej klasy `CategoryRepository`):**
|
||||
- `getCategorySort(int $categoryId, string $langId): int` — z Redis cache
|
||||
- `categoryName(int $categoryId, string $langId): string` — z Redis cache
|
||||
- `categoryUrl(int $categoryId, string $langId): string` — z Redis cache
|
||||
- `frontCategoryDetails(int $categoryId, string $langId): ?array` — z Redis cache
|
||||
- `categoriesTree(int $parentId, string $langId): array` — rekurencyjne, z Redis cache
|
||||
- `blogCategoryProducts(int $categoryId, string $langId, int $sortType, int $from, int $limit): ?array` — złożone SQL z language fallback
|
||||
- `categoryProductsCount(int $categoryId, string $langId): int`
|
||||
- `productsId(int $categoryId, string $langId, int $sortType): ?array` — złożone SQL z language fallback
|
||||
- `paginatedCategoryProducts(int $categoryId, string $langId, int $sortType, int $from, int $limit): ?array`
|
||||
- Stałe: `SORT_ORDER_SQL`, `PRODUCTS_PER_PAGE`, `LANGUAGE_FALLBACK_NAME_SQL`
|
||||
- Testy: +17 w `CategoryRepositoryTest`
|
||||
|
||||
**NOWE:**
|
||||
- `front\Views\ShopCategory` — czysty VIEW (`categoryDescription()`, `categoryView()`, `categories()`)
|
||||
- BUG FIX: `categoryView()` — `category_products_count()` wywoływane z tablicą zamiast ID
|
||||
|
||||
**ZMIANA:**
|
||||
- `front/factory/ShopCategory` → USUNIETA (logika przeniesiona do `CategoryRepository`)
|
||||
- `front/view/ShopCategory` → USUNIETA (zastąpiona przez `front\Views\ShopCategory`)
|
||||
- `index.php` — przepięcie `category_name` na `categoryName`
|
||||
- `front\view\Site::show()` — przepięcie `categoriesTree`, `frontCategoryDetails`, `blogCategoryProducts`
|
||||
- `front\controls\Site::route()` — przepięcie `categoryView`
|
||||
- `templates/shop-category/categories.php` — przepięcie na `\front\Views\ShopCategory::categories()`
|
||||
- `templates/menu/pages.php` — przepięcie `category_url` na `categoryUrl`
|
||||
- `front\controls\ShopProduct` — przepięcie `products_id` + `get_category_sort`
|
||||
|
||||
**Testy:** 501 OK, 1562 asercji
|
||||
|
||||
---
|
||||
|
||||
### Etap: Articles Frontend — ZREALIZOWANY
|
||||
|
||||
**Cel:** Migracja `front\factory\Articles`, `front\view\Articles` i statycznych metod `class.Article` do Domain + Views.
|
||||
|
||||
**DODANE METODY (do istniejącej klasy `ArticleRepository`):**
|
||||
- `articleDetailsFrontend(int $articleId, string $langId): ?array` — z copy_from fallback + Redis cache
|
||||
- `articlesIds(int $pageId, string $langId, int $limit, int $sortType, int $from): ?array` — złożone SQL z language fallback + sortowanie + LIMIT + Redis cache
|
||||
- `pageArticlesCount(int $pageId, string $langId): int` — COUNT z Redis cache
|
||||
- `pageArticles(array $page, string $langId, int $bs): array` — paginacja
|
||||
- `news(int $pageId, int $limit, string $langId): ?array` — inline sort_type query (eliminacja zależności od `front\factory\Pages`)
|
||||
- `articleNoindex(int $articleId, string $langId): bool` — jawny $langId zamiast `global $lang`
|
||||
- `topArticles(int $pageId, int $limit, string $langId): ?array` — ORDER BY views DESC + Redis cache
|
||||
- `newsListArticles(int $pageId, int $limit, string $langId): ?array` — ORDER BY date_add DESC + CacheHandler (Redis) zamiast legacy `\Cache`
|
||||
|
||||
**NOWE:**
|
||||
- `front\Views\Articles` — czysty VIEW + utility:
|
||||
- Renderowanie: `fullArticle()`, `miniatureArticlesList()`, `entryArticlesList()`, `fullArticlesList()`, `news()`, `newsList()`
|
||||
- Utility: `generateTableOfContents()`, `processHeaders()`, `generateHeadersIds()`, `getImage()`
|
||||
|
||||
**ZMIANA:**
|
||||
- `front\factory\Articles` → fasada (10 metod delegujących do repo + Views)
|
||||
- `front\view\Articles` → fasada (5 metod delegujących do repo + Views)
|
||||
- `class.Article` → USUNIĘTA (encja + metody statyczne przeniesione do `ArticleRepository` + `front\Views\Articles`)
|
||||
- `front\view\Site::show()` → 5 sekcji przepiętych na repo + Views
|
||||
- `front\controls\Site::route()` → single article + page_type switch przepięte na repo + Views
|
||||
- 5 szablonów `templates/articles/*` → `\front\Views\Articles::`
|
||||
- `tests/bootstrap.php` — dodany stub `S::is_array_fix()`
|
||||
- Testy: 13 nowych w `ArticleRepositoryTest` (450 OK, 1431 asercji)
|
||||
|
||||
---
|
||||
|
||||
### Etap: Banners Frontend — ZREALIZOWANY
|
||||
|
||||
**Cel:** Migracja `front\factory\Banners` i `front\view\Banners` do Domain + Views.
|
||||
|
||||
**DODANE METODY (do istniejącej klasy `BannerRepository`):**
|
||||
- `banners(string $langId): ?array` — aktywne banery (home_page=0), filtrowanie dat, Redis cache, plaski format languages
|
||||
- `mainBanner(string $langId): ?array` — baner glowny (home_page=1), filtrowanie dat, Redis cache, plaski format languages
|
||||
|
||||
**NOWE:**
|
||||
- `front\Views\Banners` — czysty VIEW (`banners()`, `mainBanner()`)
|
||||
|
||||
**ZMIANA:**
|
||||
- `front\factory\Banners` → USUNIETA (logika przeniesiona do `BannerRepository`)
|
||||
- `front\view\Banners` → USUNIETA (zastapiona przez `front\Views\Banners`)
|
||||
- `front\view\Site::show()` — przepiecie na `$bannerRepo->banners()` / `$bannerRepo->mainBanner()` + `\front\Views\Banners::`
|
||||
- Testy: 4 nowe w `BannerRepositoryTest` (454 OK, 1449 asercji)
|
||||
|
||||
---
|
||||
|
||||
### Etap: Menu, Pages, Layouts Frontend Services — ZREALIZOWANY
|
||||
|
||||
**Cel:** Migracja pozostałych fabryk "liściowych".
|
||||
|
||||
**UWAGA:** Zamiast tworzenia osobnych FrontendService, metody dodano do istniejących repozytoriów Domain (zgodnie z wzorcem projektu).
|
||||
|
||||
**DODANE METODY (do istniejących klas):**
|
||||
- `Domain/Layouts/LayoutsRepository` — `categoryDefaultLayoutId()`, `getDefaultLayout()`, `getProductLayout()`, `getArticleLayout()`, `getCategoryLayout()`, `getActiveLayout()` (Redis cache, 3-level fallback)
|
||||
- `Domain/Pages/PagesRepository` — `frontPageDetails()`, `frontPageSort()`, `frontMainPageId()`, `frontLangUrl()`, `frontMenuDetails()`, `frontMenuPages()` (Redis cache, rekurencja)
|
||||
- Testy: +8 w `LayoutsRepositoryTest`, +8 w `PagesRepositoryTest`
|
||||
|
||||
**NOWE:**
|
||||
- `front\Views\Menu` — czysty VIEW (`pages()`, `menu()`)
|
||||
|
||||
**ZMIANA:**
|
||||
- `front/factory/Layouts` → USUNIETA (logika w `LayoutsRepository`)
|
||||
- `front/factory/Menu` → USUNIETA (logika w `PagesRepository`)
|
||||
- `front/factory/Pages` → USUNIETA (logika w `PagesRepository`)
|
||||
- `front/view/Menu` → USUNIETA (zastapiona przez `front\Views\Menu`)
|
||||
- `templates/menu/submenu.php` → USUNIETA (martwy kod)
|
||||
- `front\view\Site::show()` — przepiecie na `$layoutsRepo` + `$pagesRepo`
|
||||
- `front\controls\Site::check_url_params()` — przepiecie na `$pagesRepo->frontPageDetails()`
|
||||
- `index.php` — przepiecie na `$pagesRepo->frontPageDetails()`
|
||||
- `Shared\Helpers\Helpers::htacces()` — optymalizacja 3→1 wywolan
|
||||
- Szablony `templates/menu/*` — przepiecie na `\front\Views\Menu::`
|
||||
- `templates/site/languages.php` — przepiecie na `$pagesRepo->frontLangUrl()`
|
||||
|
||||
**BUG FIX:** `frontPageDetails()` — null `$lang_id` przy wczesnym `check_url_params()` (usuniety string type hint + cast + `?? ''` na call site)
|
||||
|
||||
**Testy:** 470 OK, 1484 asercji
|
||||
|
||||
---
|
||||
|
||||
### 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) — ZREALIZOWANY
|
||||
|
||||
**Cel:** Migracja `front\factory\ShopClient`, `front\view\ShopClient`, `front\controls\ShopClient` + NAPRAWIENIE hardcoded password bypass.
|
||||
|
||||
**UWAGA:** Zamiast tworzenia osobnego `ClientFrontendService`, metody dodano do istniejącego `ClientRepository` (zgodnie z wzorcem projektu). Kontroler utworzony jako `front\Controllers\ShopClientController` z DI.
|
||||
|
||||
**DODANE METODY (do istniejącej klasy `ClientRepository`):**
|
||||
- Simple CRUD: `clientDetails()`, `clientEmail()`, `clientAddresses()`, `addressDetails()`, `addressDelete()`, `addressSave(int $clientId, ?int $addressId, array $data)`, `markAddressAsCurrent()`
|
||||
- `clientOrders()` — zachowuje zależność od `\front\factory\ShopOrder::order_details()`
|
||||
- `authenticate(string $email, string $password)` — **BEZ** bypassa 'Legia1916', zwraca `['status' => 'ok'|'error'|'inactive', ...]`
|
||||
- `createClient()` — zwraca `['id' => ..., 'hash' => ...]` lub null
|
||||
- `confirmRegistration()` — zwraca email lub null
|
||||
- `generateNewPassword()` — zwraca `['email' => ..., 'password' => ...]` lub null
|
||||
- `initiatePasswordRecovery()` — zwraca hash lub null
|
||||
- Testy: +36 w `ClientRepositoryTest` (guard clauses, authenticate 5 scenariuszy, createClient, confirmRegistration, generateNewPassword, initiatePasswordRecovery, address CRUD, markAddressAsCurrent)
|
||||
|
||||
**NOWE:**
|
||||
- `front\Views\ShopClient` — czysty VIEW (8 metod camelCase: addressEdit, clientAddresses, clientMenu, clientOrders, recoverPassword, miniLogin, loginForm, registerForm)
|
||||
- `front\Controllers\ShopClientController` — instancyjny kontroler z DI (`ClientRepository` przez konstruktor)
|
||||
- 15 metod publicznych (camelCase)
|
||||
- Prywatny helper `buildEmailBody(string $templateName, array $replacements = [])` — deduplikuje 4× powtórzony wzorzec budowania emaili z newslettera
|
||||
- `authenticate()` zwraca dane → kontroler obsługuje sesję/flash/redirect (separation of concerns)
|
||||
- `addressSave()` przyjmuje `array $data` zamiast 6 parametrów
|
||||
|
||||
**ZMIANA:**
|
||||
- `front/factory/ShopClient` → USUNIETA (logika przeniesiona do `ClientRepository`)
|
||||
- `front/view/ShopClient` → USUNIETA (zastąpiona przez `front\Views\ShopClient`)
|
||||
- `front/controls/ShopClient` → USUNIETA (zastąpiona przez `front\Controllers\ShopClientController`)
|
||||
- `front\controls\Site::getControllerFactories()` — zarejestrowany `'ShopClient'`
|
||||
- `front\factory\ShopOrder` — przepięcie `client_email` na `ClientRepository::clientEmail()`
|
||||
- `front\Controllers\ShopBasketController` — przepięcie `client_addresses` na `ClientRepository::clientAddresses()`
|
||||
- `front\view\Site` — przepięcie `mini_login` na `\front\Views\ShopClient::miniLogin()`
|
||||
- 3 szablony `shop-client/*` — przepięcie `client_menu` na `\front\Views\ShopClient::clientMenu()`
|
||||
- `templates/shop-basket/summary-view.php` — przepięcie `login_form` na `\front\Views\ShopClient::loginForm()`
|
||||
|
||||
**SECURITY FIX:** Hardcoded password bypass `'Legia1916'` usunięty — `authenticate()` sprawdza wyłącznie md5(register_date + password)
|
||||
|
||||
**Testy:** 537 OK, 1648 asercji
|
||||
|
||||
---
|
||||
|
||||
### 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 — ZREALIZOWANY (ver. 0.290)
|
||||
|
||||
**Cel:** Migracja `front\factory\ShopOrder::basket_save()` (~180 linii).
|
||||
|
||||
**ZREALIZOWANE:** (wg wytycznej "NIE tworzymy osobnych FrontendService/AdminService" — metody dodane do istniejącego `OrderRepository`)
|
||||
- `Domain/Order/OrderRepository.php` — dodane metody frontendowe:
|
||||
- `createFromBasket()` — tworzenie zamówienia z koszyka (21 parametrów, pełna logika basket_save)
|
||||
- `generateOrderNumber()` — format YYYY/MM/NNN
|
||||
- `orderDetailsFrontend()`, `findIdByHash()`, `findHashById()`
|
||||
- `front/Controllers/ShopOrderController.php` — kontroler z DI (OrderRepository)
|
||||
- Testy: `OrderRepositoryTest` (9 nowych), `ShopOrderControllerTest` (3 nowe)
|
||||
|
||||
**USUNIĘTE:**
|
||||
- `front/factory/class.ShopOrder.php`
|
||||
- `front/controls/class.ShopOrder.php`
|
||||
- `front/view/class.ShopOrder.php`
|
||||
|
||||
**CALLERY ZAKTUALIZOWANE:**
|
||||
- `ShopBasketController` — DI OrderRepository, zmiana basket_save/order_hash
|
||||
- `ClientRepository::clientOrders()` — OrderRepository::orderDetailsFrontend()
|
||||
- `shop\Order::order_resend_confirmation_email()` — OrderRepository::orderDetailsFrontend()
|
||||
- `cron-turstmate.php` — OrderRepository::orderDetailsFrontend()
|
||||
|
||||
---
|
||||
|
||||
### Etap: Payment Webhook Service — ZREALIZOWANY (ver. 0.290)
|
||||
|
||||
**Cel:** Wyodrębnienie webhooków płatności z `front\controls\ShopOrder`.
|
||||
|
||||
**ZREALIZOWANE:** (webhooki przeniesione do `front\Controllers\ShopOrderController` — nadal używają `\shop\Order` do operacji statusów/płatności)
|
||||
- `ShopOrderController::paymentStatusTpay()` — przeniesione 1:1
|
||||
- `ShopOrderController::paymentStatusPrzelewy24pl()` — ujednolicone z tpay (set_as_paid + update_status zamiast ręcznego $mdb->update)
|
||||
- `ShopOrderController::paymentStatusHotpay()` — analogiczna zamiana na \shop\Order metody
|
||||
|
||||
**UWAGA:** `\shop\Order` nie jest jeszcze zmigrowany — osobny etap (Order Instance + Apilo Service)
|
||||
|
||||
---
|
||||
|
||||
### 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)~~ **ZREALIZOWANE** w ver. 0.282
|
||||
- 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~~ **ZREALIZOWANE** w etapie Newsletter Frontend
|
||||
|
||||
---
|
||||
|
||||
## Podsumowanie
|
||||
|
||||
| Etap | Zakres | Priorytet | Nowe klasy Domain | Testy |
|
||||
|------|--------|-----------|-------------------|-------|
|
||||
| Settings + Languages | Fundamenty | FUNDAMENT | 2 serwisy | 2 |
|
||||
| ~~Category Frontend~~ | ~~Kategorie~~ | ZREALIZOWANY | — | — |
|
||||
| ~~Banners/Menu/Pages/Articles/Layouts~~ | ~~Treści~~ | ZREALIZOWANY | — | — |
|
||||
| Promotion Engine | Promocje | KRYTYCZNY | 1 serwis | 1 |
|
||||
| Product Frontend | Produkty | KRYTYCZNY | 1 serwis | 1 |
|
||||
| ~~Client/Auth (security fix)~~ | ~~Klienci~~ | ZREALIZOWANY | — | — |
|
||||
| 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.
|
||||
|
||||
### Nazewnictwo plikow
|
||||
- Nowe klasy: `NazwaKlasy.php` (bez przedrostka `class.`)
|
||||
- Legacy: `class.NazwaKlasy.php` — zostawiamy do momentu migracji danej klasy
|
||||
- Autoloader obsluguje oba formaty (probuje `class.X.php`, potem `X.php`)
|
||||
- Nowe katalogi z duzej litery: `Views/`, `Controllers/` (legacy: `view/`, `controls/`, `factory/`)
|
||||
|
||||
### Statyczne vs instancyjne metody
|
||||
- **Statyczne** — gdy klasa jest bezstanowa (brak konstruktora, brak properties, brak DI). Czyste funkcje: dane wchodzą, wynik wychodzi. Przykład: klasy VIEW (`front\Views\Languages::render($data)`, `front\view\Banners::banners($data)`)
|
||||
- **Instancyjne** — gdy klasa ma zależności do wstrzyknięcia (repozytoria, serwisy) lub trzyma stan. Przykład: kontrolery z DI (`ShopProductController` z `ProductRepository`, `LanguagesRepository`)
|
||||
|
||||
### 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)
|
||||
@@ -1,234 +0,0 @@
|
||||
# Plan refaktoryzacji `autoload/shop/` — usunięcie legacy klas
|
||||
|
||||
## Kontekst
|
||||
|
||||
Katalog `autoload/shop/` zawierał **12 legacy klas** (~2 363 linii kodu), które pełniły rolę fasad/wrapperów nad warstwą `Domain\`. Wszystkie klasy zostały usunięte — logika przeniesiona do warstwy `Domain\` / `Shared\`, wywołania zaktualizowane.
|
||||
|
||||
**Status: UKOŃCZONE** (wszystkie 12 klas usunięte, katalog `autoload/shop/` pusty)
|
||||
|
||||
## Status
|
||||
|
||||
| Faza | Klasy | Status |
|
||||
|------|-------|--------|
|
||||
| 1 | Transport, ProductSet, Coupon | ✅ Ukończona |
|
||||
| 2 | Shop, Search, Basket | ✅ Ukończona |
|
||||
| 3 | ProductCustomField, Category, ProductAttribute | ✅ Ukończona |
|
||||
| 4 | Promotion | ✅ Ukończona |
|
||||
| 5 | Order, Product | ✅ Ukończona |
|
||||
|
||||
---
|
||||
|
||||
## Faza 1 — Trywialne fasady (0 logiki do migracji)
|
||||
|
||||
### 1.1 `class.Transport.php` ✅ (~31 linii)
|
||||
**Jedyne zewnętrzne użycie:**
|
||||
- `admin\Controllers\ShopOrderController.php` → `\shop\Transport::transport_list()`
|
||||
|
||||
**Plan:**
|
||||
- Dodać metodę `allActiveOrdered()` do `Domain\Transport\TransportRepository` (odpowiednik `transport_list()`)
|
||||
- Zamienić wywołanie w `ShopOrderController`
|
||||
- Usunąć `class.Transport.php`
|
||||
|
||||
### 1.2 `class.ProductSet.php` ✅ (~49 linii)
|
||||
**Jedyne zewnętrzne użycie:**
|
||||
- `admin\Controllers\ShopProductController.php:224` → `\shop\ProductSet::sets_list()`
|
||||
|
||||
**Plan:**
|
||||
- `ProductSetRepository::allSets()` już istnieje — zamienić wywołanie na `$this->productSetRepo->allSets()`
|
||||
- Wstrzyknąć `ProductSetRepository` do `ShopProductController` (jeśli jeszcze nie jest)
|
||||
- Usunąć `class.ProductSet.php`
|
||||
|
||||
### 1.3 `class.Coupon.php` ✅ (~84 linii)
|
||||
**Zewnętrzne użycia (3×):**
|
||||
- `shop\class.Order.php:171` → `new \shop\Coupon($id)` (do przeniesienia w fazie Order)
|
||||
- `front\Controllers\ShopOrderController.php:139` → `new \shop\Coupon($id)`
|
||||
- `admin\Controllers\ShopOrderController.php:170` → `new \shop\Coupon($id)`
|
||||
|
||||
**Plan:**
|
||||
- `CouponRepository::findByName()` / `find()` już istnieje — dodać `findById(int $id): ?array` jeśli brak
|
||||
- Zamienić `new \shop\Coupon($id)` → `$this->couponRepo->findById($id)` w obu kontrolerach
|
||||
- Użycie w `class.Order.php` — rozwiąże się w fazie Order
|
||||
- Usunąć `class.Coupon.php`
|
||||
|
||||
---
|
||||
|
||||
## Faza 2 — Proste wrappery (minimalna logika do przeniesienia)
|
||||
|
||||
### 2.1 `class.Shop.php` ✅ (~39 linii) — utility cenowe
|
||||
**Zewnętrzne użycia (~24× w szablonach):**
|
||||
- `templates/shop-product/product.php`, `product-mini.php`
|
||||
- `templates/shop-search/product-search.php`
|
||||
- `templates/shop-basket/alert-product-sets.php`
|
||||
- `templates/controls/alert-product-sets.php`
|
||||
|
||||
**Plan:**
|
||||
- Przenieść `shortPrice()` i `isWholeNumber()` do `Shared\Helpers\Helpers` jako metody statyczne
|
||||
- Zamienić `\shop\Shop::shortPrice()` → `\Shared\Helpers\Helpers::shortPrice()` we wszystkich szablonach (replace_all)
|
||||
- Usunąć `class.Shop.php`
|
||||
|
||||
### 2.2 `class.Search.php` ✅ (~70 linii)
|
||||
**Jedyne zewnętrzne użycie:**
|
||||
- `front\LayoutEngine.php:337` → `\shop\Search::simple_form()`
|
||||
|
||||
**Plan:**
|
||||
- Przenieść `simple_form()` do `front\Views\ShopSearch` (nowa klasa View, statyczna)
|
||||
- Przenieść `search_results()` i `search_products()` do `front\Controllers\ShopSearchController` lub odpowiedniej istniejącej lokalizacji
|
||||
- Zamienić wywołanie w `LayoutEngine`
|
||||
- Usunąć `class.Search.php`
|
||||
- Poprawić bug: `use shop\Produt;` (literówka — brakuje 'c')
|
||||
|
||||
### 2.3 `class.Basket.php` ✅ (~92 linii)
|
||||
**Zewnętrzne użycia (6× w `ShopBasketController`):**
|
||||
- `validate_basket()` — prosta walidacja tablicy sesji
|
||||
- `check_product_quantity_in_stock()` — sprawdzenie stanów magazynowych
|
||||
|
||||
**Plan:**
|
||||
- Przenieść obie metody do `Domain\Basket\BasketCalculator` (już istnieje)
|
||||
- Zamienić wywołania w `ShopBasketController`
|
||||
- Usunąć `class.Basket.php`
|
||||
|
||||
---
|
||||
|
||||
## Faza 3 — Klasy z logiką cache/atrybutów
|
||||
|
||||
### 3.1 `class.ProductCustomField.php` ✅ (~74 linii)
|
||||
**Zewnętrzne użycia (2×):**
|
||||
- `Domain\Order\OrderRepository.php:643` → `\shop\ProductCustomField::getFromCache()`
|
||||
- `templates/shop-basket/_partials/product-custom-fields.php:3` → `\shop\ProductCustomField::getFromCache()`
|
||||
|
||||
**Plan:**
|
||||
- Dodać `findCached(int $id): ?array` do `Domain\Product\ProductRepository` (lub nowy `ProductCustomFieldRepository`)
|
||||
- Zamienić wywołania w OrderRepository i szablonie
|
||||
- Usunąć `class.ProductCustomField.php`
|
||||
|
||||
### 3.2 `class.Category.php` ✅ (~84 linii)
|
||||
**Zewnętrzne użycia (2×):**
|
||||
- `index.php:225` → `\shop\Category::get_category_products_id()` (FB Pixel)
|
||||
- `templates/shop-category/category.php:19` → `\shop\Category::get_subcategory_by_category()`
|
||||
|
||||
**Plan:**
|
||||
- `CategoryRepository::productsId()` prawdopodobnie istnieje — sprawdzić i użyć lub dodać
|
||||
- Dodać `subcategoriesCached(int $categoryId): array` do `CategoryRepository`
|
||||
- Zamienić wywołania
|
||||
- Usunąć `class.Category.php`
|
||||
|
||||
### 3.3 `class.ProductAttribute.php` ✅ (~119 linii)
|
||||
**Zewnętrzne użycia (3 lokalizacje):**
|
||||
- `shop\class.Product.php` — użycia wewnętrzne (rozwiążą się w fazie Product)
|
||||
- `admin/templates/shop-product/product-combination.php:32` → `getAttributeName()`, `get_value_name()`
|
||||
- `templates/shop-product/_partial/product-attribute.php:13` → `get_value_name()`
|
||||
|
||||
**Plan:**
|
||||
- `AttributeRepository::getAttributeNameById()` i `getAttributeValueById()` już istnieją
|
||||
- Dodać brakujące metody do `AttributeRepository`: `isValueDefault()`, `getAttributeOrder()`, `getAttributeNameByValue()` (z Redis cache)
|
||||
- Zamienić wywołania w szablonach
|
||||
- Usunąć `class.ProductAttribute.php`
|
||||
|
||||
---
|
||||
|
||||
## Faza 4 — Klasy z logiką promocji
|
||||
|
||||
### 4.1 `class.Promotion.php` ✅ (~107 linii)
|
||||
**Zewnętrzne użycia (3 lokalizacje):**
|
||||
- `front\Controllers\ShopBasketController.php` (6×) → `\shop\Promotion::find_promotion()`
|
||||
- `admin\Controllers\ShopPromotionController.php` → `::$condition_type`, `::$discount_type`
|
||||
|
||||
**Plan:**
|
||||
- Przenieść `get_active_promotions()` do `PromotionRepository` (z Redis cache)
|
||||
- Przenieść `find_promotion()` do `PromotionRepository` — orkiestracja logiki applyType*
|
||||
- Przenieść stałe `$condition_type` / `$discount_type` jako stałe klasowe do `PromotionRepository`
|
||||
- Zamienić wywołania w `ShopBasketController` i `ShopPromotionController`
|
||||
- Usunąć `class.Promotion.php`
|
||||
|
||||
---
|
||||
|
||||
## Faza 5 — Duże klasy z wieloma zależnościami
|
||||
|
||||
### 5.1 `class.Order.php` ✅ (~562 linii)
|
||||
**Główna logika do migracji:**
|
||||
- `OrderAdminService` ma już: `setOrderAsPaid()`, `setOrderAsUnpaid()`, `changeStatus()`, `resendConfirmationEmail()`, `saveOrderByAdmin()`, `deleteOrder()`, `saveNotes()`
|
||||
- **Brakuje:** logika Apilo sync (`process_apilo_sync_queue()`, `sync_apilo_payment()`, `sync_apilo_status()`, queue management)
|
||||
- **Brakuje:** `send_status_change_email()` (ale może być zintegrowane w `changeStatus()`)
|
||||
|
||||
**Plan:**
|
||||
1. Sprawdzić, czy `OrderAdminService` obsługuje już Apilo sync (metoda `sendOrderToApilo()` istnieje)
|
||||
2. Przenieść `process_apilo_sync_queue()` + kolejkę Apilo do `Domain\Integrations\ApiloService` (lub do `IntegrationsRepository`)
|
||||
3. Przenieść `send_status_change_email()` do `OrderAdminService` (jeśli nie jest częścią `changeStatus()`)
|
||||
4. Usunąć referencję do `new \shop\Coupon()` — użyć `CouponRepository` (z fazy 1.3)
|
||||
5. Zaktualizować `cron.php` (jeśli woła `process_apilo_sync_queue`)
|
||||
6. Usunąć `class.Order.php`
|
||||
|
||||
### 5.2 `class.Product.php` ✅ (~952 linii) — NAJWIĘKSZA KLASA
|
||||
**Stan:** Większość logiki zmigowana do `ProductRepository`, ale klasa pełni rolę entity z ArrayAccess (używana w szablonach jako `$product['name']`).
|
||||
|
||||
**Metody do przeniesienia:**
|
||||
- `getFromCache()` — cache wrappera entity → przenieść do `ProductRepository::findCached()`
|
||||
- `getDefaultCombinationPrices()` → `ProductRepository`
|
||||
- `generateSubtitleFromAttributes()` → `ProductRepository`
|
||||
- `getProductDataBySelectedAttributes()` → `ProductRepository`
|
||||
- `is_product_on_promotion()` → `ProductRepository`
|
||||
- `product_sets_when_add_to_basket()` → `ProductSetRepository`
|
||||
- `add_visit()` → `ProductRepository`
|
||||
- `getProductImg()` / `getProductUrl()` → `ProductRepository`
|
||||
- `searchProductsByName()` / `searchProductByNameAjax()` / `searchProductsByNameCount()` → `ProductRepository`
|
||||
- `is_stock_0_buy()` → `ProductRepository`
|
||||
- `get_product_permutation_quantity_options()` → `ProductRepository`
|
||||
- `calculate_basket_product_price()` → `Domain\Basket\BasketCalculator`
|
||||
- `get_product_id_by_attributes()` / `get_product_permutation_hash()` / `get_product_attributes()` → `ProductRepository` lub `AttributeRepository`
|
||||
- `array_cartesian()` / `permutations()` → `ProductRepository` (helper prywatny)
|
||||
- `generate_sku_code()` → `ProductRepository`
|
||||
- `product_meta()` → `ProductRepository`
|
||||
|
||||
**Kluczowy problem:** szablony używają `$product['field']` przez ArrayAccess. Po migracji szablony będą dostawać zwykłe `array` z `ProductRepository` — to jest kompatybilne, bo `$product['field']` działa tak samo na tablicy.
|
||||
|
||||
**Plan:**
|
||||
1. Etapami przenosić metody statyczne do `ProductRepository` / `AttributeRepository`
|
||||
2. Przenieść `calculate_basket_product_price()` do `BasketCalculator`
|
||||
3. Zamienić `Product::getFromCache()` → `ProductRepository::findCached()` (zwraca tablicę)
|
||||
4. Zaktualizować szablony i kontrolery
|
||||
5. Usunąć `class.Product.php`
|
||||
|
||||
---
|
||||
|
||||
## Pliki do modyfikacji (podsumowanie)
|
||||
|
||||
| Plik | Zmiany |
|
||||
|------|--------|
|
||||
| `autoload/Domain/Transport/TransportRepository.php` | + `allActiveOrdered()` |
|
||||
| `autoload/Domain/Basket/BasketCalculator.php` | + `validateBasket()`, `checkStock()`, `calculateProductPrice()` |
|
||||
| `autoload/Domain/Promotion/PromotionRepository.php` | + `getActivePromotions()`, `findPromotion()`, stałe |
|
||||
| `autoload/Domain/Product/ProductRepository.php` | + ~15 metod z class.Product.php |
|
||||
| `autoload/Domain/Attribute/AttributeRepository.php` | + `isValueDefault()`, `getAttributeOrder()`, `getAttributeNameByValue()` |
|
||||
| `autoload/Domain/Category/CategoryRepository.php` | + `subcategoriesCached()`, `categoryProductIds()` |
|
||||
| `autoload/Domain/Order/OrderAdminService.php` | + email statusu, sprawdzenie Apilo |
|
||||
| `autoload/Domain/Integrations/` | + `ApiloSyncService` (queue Apilo) |
|
||||
| `autoload/Domain/Coupon/CouponRepository.php` | + `findById()` |
|
||||
| `autoload/Shared/Helpers/Helpers.php` | + `shortPrice()`, `isWholeNumber()` |
|
||||
| `autoload/front/Views/ShopSearch.php` | NOWY — `simple_form()` |
|
||||
| `autoload/front/LayoutEngine.php` | zamiana `\shop\Search` → `\front\Views\ShopSearch` |
|
||||
| `autoload/front/Controllers/ShopBasketController.php` | zamiana `\shop\Basket`, `\shop\Promotion` |
|
||||
| `autoload/admin/Controllers/ShopOrderController.php` | zamiana `\shop\Coupon`, `\shop\Transport` |
|
||||
| `autoload/admin/Controllers/ShopProductController.php` | zamiana `\shop\ProductSet` |
|
||||
| `autoload/admin/Controllers/ShopPromotionController.php` | zamiana `::$condition_type`, `::$discount_type` |
|
||||
| `autoload/front/Controllers/ShopOrderController.php` | zamiana `\shop\Coupon` |
|
||||
| Szablony (`templates/`) | zamiana `\shop\Shop::shortPrice()`, `\shop\ProductAttribute::*`, `\shop\Category::*` |
|
||||
| `index.php` | zamiana `\shop\Category::get_category_products_id()` |
|
||||
| `autoload/Domain/Order/OrderRepository.php` | zamiana `\shop\ProductCustomField` |
|
||||
|
||||
## Weryfikacja
|
||||
|
||||
Po każdej fazie:
|
||||
1. Uruchomić `./test.ps1` — wszystkie 610+ testów muszą przechodzić
|
||||
2. Grep po `\shop\` w całym codebase — upewnić się, że usunięta klasa nie jest nigdzie używana
|
||||
3. Po zakończeniu wszystkich faz: `grep -r "\\\\shop\\\\" autoload/ templates/ admin/ index.php ajax.php cron.php api.php` powinien zwracać 0 wyników
|
||||
|
||||
## Szacunek złożoności
|
||||
|
||||
| Faza | Klasy | Linii do usunięcia | Złożoność |
|
||||
|------|-------|---------------------|-----------|
|
||||
| 1 | Transport, ProductSet, Coupon | ~164 | Niska |
|
||||
| 2 | Shop, Search, Basket | ~201 | Niska-średnia |
|
||||
| 3 | ProductCustomField, Category, ProductAttribute | ~277 | Średnia |
|
||||
| 4 | Promotion | ~107 | Średnia |
|
||||
| 5 | Order, Product | ~1 514 | Wysoka |
|
||||
| **Razem** | **12 klas** | **~2 363** | |
|
||||
@@ -12,7 +12,6 @@ Notatki i wnioski zebrane podczas pracy z kodem. Aktualizowane na bieżąco.
|
||||
## Znane problemy / TODO
|
||||
|
||||
- `\Shared\Helpers\Helpers::send_email()` i `Shared\Email\Email::send()` — zduplikowana logika PHPMailer. Docelowo zunifikować w `Shared\Email\Email`
|
||||
- `shop\Search` — typo w `use`: `shop\Produt` zamiast `shop\Product`
|
||||
|
||||
## Wzorce potwierdzone w projekcie
|
||||
|
||||
|
||||
@@ -1,504 +1,173 @@
|
||||
# Struktura Projektu shopPRO
|
||||
|
||||
Dokumentacja struktury projektu shopPRO do szybkiego odniesienia.
|
||||
Aktualna architektura po zakonczonej migracji na Domain-Driven Design + Dependency Injection.
|
||||
|
||||
## System Cache (Redis)
|
||||
## Warstwa domenowa (`autoload/Domain/`)
|
||||
|
||||
### Klasy odpowiedzialne za cache
|
||||
Kazdy modul zawiera Repository (i opcjonalnie dodatkowe klasy). Konstruktor DI z `$db` (Medoo). Metody sluza zarowno adminowi, jak i frontendowi (wspolna warstwa).
|
||||
|
||||
#### RedisConnection (`Shared\Cache\RedisConnection`)
|
||||
- **Plik:** `autoload/Shared/Cache/RedisConnection.php`
|
||||
- **Opis:** Singleton zarządzający połączeniem z Redis
|
||||
- **Metody:**
|
||||
- `getInstance()` - pobiera instancję połączenia
|
||||
- `getConnection()` - zwraca obiekt Redis
|
||||
| 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 |
|
||||
|
||||
#### CacheHandler (`Shared\Cache\CacheHandler`)
|
||||
- **Plik:** `autoload/Shared/Cache/CacheHandler.php`
|
||||
- **Opis:** Handler do obsługi cache Redis
|
||||
- **Metody:**
|
||||
- `get($key)` - pobiera wartość z cache (zwraca zserializowany string, wymaga `unserialize()`)
|
||||
- `set($key, $value, $ttl = 86400)` - zapisuje wartość do cache (serializuje wewnętrznie)
|
||||
- `exists($key)` - sprawdza czy klucz istnieje
|
||||
- `delete($key)` - usuwa pojedynczy klucz
|
||||
- `deletePattern($pattern)` - usuwa klucze według wzorca
|
||||
## Warstwa admin (`autoload/admin/`)
|
||||
|
||||
#### USUNIĘTA: Cache (legacy file-based)
|
||||
- ~~`autoload/class.Cache.php`~~ — usunięta w ver. 0.282
|
||||
- Zastąpiona przez `CacheHandler` (Redis) we wszystkich wywołaniach
|
||||
### Router: `admin\App`
|
||||
- `getControllerFactories()` — mapa kontrolerow z DI wiring
|
||||
- Brak fallbacku na legacy — wszystkie moduly na nowych kontrolerach
|
||||
|
||||
#### Helpers (`Shared\Helpers\Helpers`)
|
||||
- **Plik:** `autoload/Shared/Helpers/Helpers.php`
|
||||
- **Metody cache:**
|
||||
- `clear_product_cache(int $product_id)` - czyści cache konkretnego produktu
|
||||
### 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
|
||||
|
||||
### Wzorce kluczy Redis
|
||||
### Support
|
||||
- `admin\Support\TableListRequestFactory` — paginacja/sortowanie tabel
|
||||
- `admin\Support\Forms\FormRequestHandler` — obsluga formularzy (persist przy bledach)
|
||||
- `admin\Support\Forms\FormFieldRenderer` — renderowanie pol formularzy
|
||||
|
||||
#### Produkty
|
||||
### 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 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:{product_id}:{lang_id}:{permutation_hash}
|
||||
```
|
||||
- Przechowuje tablicę danych produktu (z kombinacjami, obrazkami, producentem itd.)
|
||||
- TTL: 24 godziny (86400 sekund)
|
||||
- Klasa: `Domain\Product\ProductRepository::findCached()` - `autoload/Domain/Product/ProductRepository.php`
|
||||
|
||||
#### Opcje ilościowe produktu
|
||||
```
|
||||
ProductRepository::getProductPermutationQuantityOptions:v2:{product_id}:{permutation}
|
||||
```
|
||||
- Przechowuje informacje o ilości i komunikatach magazynowych
|
||||
- Klasa: `Domain\Product\ProductRepository::getProductPermutationQuantityOptions()` - `autoload/Domain/Product/ProductRepository.php`
|
||||
|
||||
#### Zestawy produktów
|
||||
```
|
||||
ProductRepository::productSetsWhenAddToBasket:{product_id}
|
||||
```
|
||||
- Przechowuje produkty często kupowane razem
|
||||
- Klasa: `Domain\Product\ProductRepository::productSetsWhenAddToBasket()` - `autoload/Domain/Product/ProductRepository.php`
|
||||
|
||||
## Integracje z systemami zewnętrznymi (CRON)
|
||||
|
||||
### Plik: `cron.php`
|
||||
|
||||
#### Apilo
|
||||
- **Aktualizacja pojedynczego produktu:** synchronizacja cen i stanow
|
||||
- Czestotliwosc: Co 10 minut
|
||||
- **Synchronizacja cennika:** masowa aktualizacja cen z Apilo
|
||||
- Czestotliwosc: Co 1 godzine
|
||||
- **Synchronizacja zaleglych syncow platnosci/statusow:** kolejka retry dla chwilowej niedostepnosci Apilo (`temp/apilo-sync-queue.json`)
|
||||
- Przetwarzanie: przy kazdym uruchomieniu `cron.php` (limit wsadowy)
|
||||
|
||||
**Uwaga:** Integracje Sellasist i Baselinker zostaly usuniete w ver. 0.263.
|
||||
|
||||
## Panel Administratora
|
||||
|
||||
### Routing
|
||||
- Główny katalog: `admin/`
|
||||
- Template główny: `admin/templates/site/main-layout.php`
|
||||
- Kontrolery (nowe): `autoload/admin/Controllers/`
|
||||
- Kontrolery legacy (fallback): `autoload/admin/controls/`
|
||||
|
||||
### Przycisk "Wyczyść cache"
|
||||
- **Lokalizacja UI:** `admin/templates/site/main-layout.php:172`
|
||||
- **JavaScript:** `admin/templates/site/main-layout.php:235-274`
|
||||
- **Endpoint AJAX:** `/admin/settings/clear_cache_ajax/`
|
||||
- **Kontroler:** `autoload/admin/Controllers/SettingsController.php:43-60`
|
||||
- **Działanie:**
|
||||
1. Pokazuje spinner "Czyszczę cache..."
|
||||
2. Czyści katalogi: `temp/`, `thumbs/`
|
||||
3. Wykonuje `flushAll()` na Redis
|
||||
4. Pokazuje "Cache wyczyszczony!" przez 2 sekundy
|
||||
5. Przywraca stan początkowy
|
||||
|
||||
## Struktura katalogów
|
||||
|
||||
```
|
||||
shopPRO/
|
||||
├── admin/ # Panel administratora
|
||||
│ ├── templates/ # Szablony widoków
|
||||
│ └── layout/ # Zasoby CSS/JS/ikony
|
||||
├── autoload/ # Klasy autoloadowane
|
||||
│ ├── admin/ # Klasy panelu admin
|
||||
│ │ ├── Controllers/ # Nowe kontrolery DI
|
||||
│ │ ├── controls/ # Kontrolery legacy (fallback)
|
||||
│ │ └── factory/ # Fabryki/helpery
|
||||
│ ├── Domain/ # Repozytoria/logika domenowa
|
||||
│ ├── Shared/ # Wspoldzielone narzedzia
|
||||
│ │ ├── Cache/ # CacheHandler, RedisConnection
|
||||
│ │ ├── Helpers/ # Helpers (ex class.S.php)
|
||||
│ │ └── Tpl/ # Tpl (silnik szablonow)
|
||||
│ ├── front/ # Klasy frontendu
|
||||
│ │ ├── App.php # Router (ex controls/Site) — route(), checkUrlParams(), getControllerFactories()
|
||||
│ │ ├── LayoutEngine.php # Layout engine (ex view/Site) — show(), contact(), cookieInformation()
|
||||
│ │ ├── Controllers/ # Kontrolery DI (Newsletter, ShopBasket, ShopClient, ShopCoupon, ShopOrder, ShopProducer, ShopProduct)
|
||||
│ │ └── Views/ # Widoki (Newsletter, Articles, Languages, Banners, Menu, Scontainers, ShopCategory, ShopClient)
|
||||
│ └── shop/ # Klasy sklepu
|
||||
├── docs/ # Dokumentacja techniczna
|
||||
├── libraries/ # Biblioteki zewnętrzne
|
||||
├── temp/ # Cache tymczasowy
|
||||
├── thumbs/ # Miniatury zdjęć
|
||||
└── cron.php # Zadania CRON
|
||||
shop\product:{id}:{lang}:{permutation_hash} — dane produktu (TTL 24h)
|
||||
ProductRepository::getProductPermutationQuantityOptions:v2:{id}:{perm} — ilosc + komunikaty
|
||||
ProductRepository::productSetsWhenAddToBasket:{id} — zestawy "kupowane razem"
|
||||
```
|
||||
|
||||
## Baza danych
|
||||
### 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/`
|
||||
|
||||
### Główne tabele produktów
|
||||
- `pp_shop_products` - produkty główne
|
||||
- `pp_shop_products_langs` - tłumaczenia produktów
|
||||
- `pp_shop_products_images` - zdjęcia produktów
|
||||
- `pp_shop_products_categories` - kategorie produktów
|
||||
- `pp_shop_products_custom_fields` - pola własne produktów
|
||||
## Entry pointy
|
||||
|
||||
### Tabele integracji
|
||||
- Kolumny w `pp_shop_products`:
|
||||
- `apilo_product_id`, `apilo_product_name`, `apilo_get_data_date`
|
||||
- Tabele ustawien:
|
||||
- `pp_shop_apilo_settings` (key-value)
|
||||
- `pp_shop_shoppro_settings` (key-value)
|
||||
| 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 (Ekomi CSV) |
|
||||
| `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 |
|
||||
|
||||
### Tabele checkout
|
||||
- `pp_shop_payment_methods` - metody platnosci sklepu (mapowanie `apilo_payment_type_id`)
|
||||
- `pp_shop_transports` - rodzaje transportu sklepu (mapowanie `apilo_carrier_account_id`)
|
||||
- `pp_shop_transport_payment_methods` - powiazanie metod transportu i platnosci
|
||||
### 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)
|
||||
|
||||
Pelna dokumentacja tabel: `DATABASE_STRUCTURE.md`
|
||||
### Routing frontend (index.php)
|
||||
Przed `front\App::route()`:
|
||||
1. Sprawdza tabele `pp_redirects` → 301 redirect
|
||||
2. Sprawdza tabele `pp_routes` → regex pattern → destination
|
||||
|
||||
## Konfiguracja
|
||||
### Newsletter queue
|
||||
`index.php` wywoluje `$newsletterRepo->sendQueued()` na koncu kazdego requestu frontendowego (limit 1 mail/request).
|
||||
|
||||
### Redis
|
||||
- Konfiguracja: `config.php` (zmienna `$config['redis']`)
|
||||
- Parametry: host, port, password
|
||||
## Integracje zewnetrzne
|
||||
|
||||
### Autoload
|
||||
- Funkcja: `__autoload_my_classes()` w `cron.php:6`
|
||||
- Wzorzec: `autoload/{namespace}/class.{ClassName}.php`
|
||||
### 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`
|
||||
|
||||
## Klasy pomocnicze
|
||||
### Webhooki platnosci (front\Controllers\ShopOrderController)
|
||||
- tPay, Przelewy24, Hotpay — ujednolicone: `set_as_paid` + `update_status`
|
||||
|
||||
### \Shared\Helpers\Helpers (autoload/Shared/Helpers/Helpers.php)
|
||||
Główna klasa helper (przeniesiona z `class.S.php`) z metodami:
|
||||
- `seo($val)` - generowanie URL SEO
|
||||
- `normalize_decimal($val, $precision)` - normalizacja liczb
|
||||
- `send_email()` - wysyłanie emaili
|
||||
- `delete_dir($dir)` - usuwanie katalogów
|
||||
- `htacces()` - generowanie .htaccess i sitemap.xml
|
||||
- `clear_product_cache($id)` - czyszczenie cache produktu
|
||||
## Biblioteki (`libraries/`)
|
||||
|
||||
### Medoo
|
||||
- Plik: `libraries/medoo/medoo.php`
|
||||
- Zmienna: `$mdb`
|
||||
- ORM do operacji na bazie danych
|
||||
- `medoo/medoo.php` — Medoo ORM (`$mdb`)
|
||||
- `rb.php` — RedBeanPHP ORM (`\R::`, `$pdo`)
|
||||
- `phpmailer/` — PHPMailer
|
||||
|
||||
## Najważniejsze wzorce
|
||||
## Wzorce architektoniczne
|
||||
|
||||
### Namespace'y
|
||||
- `\admin\Controllers\` - nowe kontrolery panelu admin (DI)
|
||||
- `\admin\controls\` - kontrolery legacy (fallback)
|
||||
- `\Domain\` - repozytoria/logika domenowa
|
||||
- `\admin\factory\` - helpery/fabryki admin
|
||||
- ~~`\front\factory\`~~ - USUNIĘTY — wszystkie fabryki zmigrowane do Domain
|
||||
- ~~`\front\controls\`~~ - USUNIĘTY — router przeniesiony do `\front\App`
|
||||
- ~~`\front\view\`~~ - USUNIĘTY — layout engine przeniesiony do `\front\LayoutEngine`
|
||||
- ~~`\shop\`~~ - USUNIĘTY — wszystkie klasy zmigrowane do `\Domain\`
|
||||
|
||||
### Cachowanie produktów
|
||||
### DI zamiast global
|
||||
```php
|
||||
// Pobranie produktu z cache
|
||||
$product = (new \Domain\Product\ProductRepository($mdb))->findCached($product_id, $lang_id, $permutation_hash);
|
||||
|
||||
// Czyszczenie cache produktu
|
||||
\Shared\Helpers\Helpers::clear_product_cache($product_id);
|
||||
// Kontroler wiring (w admin\App lub front\App)
|
||||
$repo = new \Domain\Example\ExampleRepository($mdb);
|
||||
$controller = new \admin\Controllers\ExampleController($repo);
|
||||
```
|
||||
|
||||
## Refaktoryzacja do Domain-Driven Architecture
|
||||
### Wspolna warstwa Domain
|
||||
Metody frontendowe (z Redis cache) dodawane do istniejacych repozytoriow — NIE tworzymy osobnych FrontendService/AdminService.
|
||||
|
||||
### Nowa struktura (w trakcie migracji)
|
||||
```
|
||||
autoload/
|
||||
├── Domain/ # Nowa warstwa biznesowa (namespace \Domain\)
|
||||
│ ├── Product/
|
||||
│ │ └── ProductRepository.php
|
||||
│ ├── Banner/
|
||||
│ │ └── BannerRepository.php
|
||||
│ ├── Settings/
|
||||
│ │ └── SettingsRepository.php
|
||||
│ ├── Cache/
|
||||
│ │ └── CacheRepository.php
|
||||
│ ├── Article/
|
||||
│ │ └── ArticleRepository.php
|
||||
│ ├── User/
|
||||
│ │ └── UserRepository.php
|
||||
│ ├── Languages/
|
||||
│ │ └── LanguagesRepository.php
|
||||
│ ├── Layouts/
|
||||
│ │ └── LayoutsRepository.php
|
||||
│ ├── Newsletter/
|
||||
│ │ ├── NewsletterRepository.php
|
||||
│ │ └── NewsletterPreviewRenderer.php
|
||||
│ ├── Scontainers/
|
||||
│ │ └── ScontainersRepository.php
|
||||
│ ├── Dictionaries/
|
||||
│ │ └── DictionariesRepository.php
|
||||
│ ├── Pages/
|
||||
│ │ └── PagesRepository.php
|
||||
│ ├── Integrations/
|
||||
│ │ └── IntegrationsRepository.php
|
||||
│ ├── Promotion/
|
||||
│ │ └── PromotionRepository.php
|
||||
│ ├── Coupon/
|
||||
│ │ └── CouponRepository.php
|
||||
│ ├── ShopStatus/
|
||||
│ │ └── ShopStatusRepository.php
|
||||
│ ├── Transport/
|
||||
│ │ └── TransportRepository.php
|
||||
│ ├── ProductSet/
|
||||
│ │ └── ProductSetRepository.php
|
||||
│ ├── Producer/
|
||||
│ │ └── ProducerRepository.php
|
||||
│ └── ...
|
||||
├── admin/
|
||||
│ ├── Controllers/ # Nowe kontrolery (namespace \admin\Controllers\)
|
||||
│ ├── class.Site.php # Router: nowy kontroler → fallback stary
|
||||
│ ├── controls/ # Stare kontrolery (niezależny fallback)
|
||||
│ ├── factory/ # Stare helpery (niezależny fallback)
|
||||
│ └── view/ # Widoki (statyczne - bez zmian)
|
||||
├── front/
|
||||
│ ├── App.php # Router (namespace \front\) — route(), checkUrlParams(), getControllerFactories()
|
||||
│ ├── LayoutEngine.php # Layout engine (namespace \front\) — show(), contact(), cookieInformation()
|
||||
│ ├── Controllers/ # Kontrolery frontendowe (namespace \front\Controllers\) z DI
|
||||
│ └── Views/ # Widoki (namespace \front\Views\) — czyste VIEW, statyczne
|
||||
├── shop/ # Legacy - fasady do Domain
|
||||
```
|
||||
### Klasy View — statyczne, bezstanowe
|
||||
`front\Views\*` — nie wymagaja DI. Czyste funkcje: dane wchodza, HTML wychodzi.
|
||||
|
||||
**Aktualizacja 2026-02-14 (ver. 0.268):**
|
||||
- Dodano modul domenowy `Domain/PaymentMethod/PaymentMethodRepository.php`.
|
||||
- Dodano kontroler DI `admin/Controllers/ShopPaymentMethodController.php`.
|
||||
- Modul `/admin/shop_payment_method/*` dziala na nowych widokach (`payment-methods-list`, `payment-method-edit`).
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopPaymentMethod.php`, `autoload/admin/factory/class.ShopPaymentMethod.php`, `autoload/admin/view/class.ShopPaymentMethod.php`, `admin/templates/shop-payment-method/view-list.php`.
|
||||
### Kontrolery — instancyjne z DI
|
||||
`Controllers\*` — repozytoria wstrzykiwane przez konstruktor.
|
||||
|
||||
**Aktualizacja 2026-02-14 (ver. 0.269):**
|
||||
- Dodano modul domenowy `Domain/Transport/TransportRepository.php`.
|
||||
- Dodano kontroler DI `admin/Controllers/ShopTransportController.php`.
|
||||
- Modul `/admin/shop_transport/*` dziala na nowych widokach (`transports-list`, `transport-edit`).
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopTransport.php`, `autoload/admin/view/class.ShopTransport.php`, `admin/templates/shop-transport/view-list.php`.
|
||||
- `admin\factory\ShopTransport` i `front\factory\ShopTransport` przepiete na repozytorium.
|
||||
### Nazewnictwo plikow
|
||||
- Nowe: `ClassName.php`
|
||||
- Legacy (pozostalosci): `class.ClassName.php`
|
||||
- Autoloader obsluguje oba formaty
|
||||
|
||||
**Aktualizacja 2026-02-14 (ver. 0.270):**
|
||||
- `OrderAdminService` zapisuje nieudane syncy Apilo (status/platnosc) do kolejki `temp/apilo-sync-queue.json`.
|
||||
- `cron.php` automatycznie ponawia zalegle syncy (`OrderAdminService::processApiloSyncQueue()`).
|
||||
- `OrderAdminService::setOrderAsPaid()` wysyla mapowany typ platnosci Apilo (z mapowania metody platnosci), bez stalej wartosci `type`.
|
||||
|
||||
**Aktualizacja 2026-02-15 (ver. 0.276):**
|
||||
- Dodano modul domenowy `Domain/Order/OrderRepository.php`.
|
||||
- Dodano serwis aplikacyjny `Domain/Order/OrderAdminService.php`.
|
||||
- Dodano kontroler DI `admin/Controllers/ShopOrderController.php`.
|
||||
- Modul `/admin/shop_order/*` dziala na nowych widokach (`orders-list`, `order-details`, `order-edit`).
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopOrder.php`, `autoload/admin/factory/class.ShopOrder.php`, `admin/templates/shop-order/view-list.php`.
|
||||
|
||||
**Aktualizacja 2026-02-15 (ver. 0.277):**
|
||||
- Dodano globalna wyszukiwarke admin w `admin/templates/site/main-layout.php` (produkty + zamowienia).
|
||||
- Dodano endpoint AJAX `SettingsController::globalSearchAjax()` w `autoload/admin/Controllers/SettingsController.php`.
|
||||
- Usunieto fasade `autoload/admin/factory/class.Integrations.php`.
|
||||
- Wywołania integracji przepiete bezposrednio na `Domain/Integrations/IntegrationsRepository.php`.
|
||||
|
||||
### Routing admin (admin\Site::route())
|
||||
1. Sprawdź mapę `$newControllers` → utwórz instancję z DI → wywołaj
|
||||
2. Jeśli nowy kontroler nie istnieje (`class_exists()` = false) → fallback na `admin\controls\`
|
||||
3. Stary kontroler jest NIEZALEŻNY od nowych klas (bezpieczny fallback)
|
||||
|
||||
### Dependency Injection
|
||||
Nowe klasy używają **Dependency Injection** zamiast `global` variables:
|
||||
```php
|
||||
// STARE
|
||||
global $mdb;
|
||||
$quantity = $mdb->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
|
||||
// NOWE
|
||||
$repository = new \Domain\Product\ProductRepository($mdb);
|
||||
$quantity = $repository->getQuantity($id);
|
||||
```
|
||||
|
||||
## Testowanie (tylko dla deweloperów)
|
||||
|
||||
**UWAGA:** Pliki testów NIE są częścią aktualizacji dla klientów!
|
||||
|
||||
### Narzędzia
|
||||
- **PHPUnit 9.6.34** - framework testowy
|
||||
- **test.bat** - uruchamianie testów
|
||||
- **composer.json** - autoloading PSR-4
|
||||
|
||||
Pelna dokumentacja testow: `TESTING.md`
|
||||
|
||||
## Dodatkowa aktualizacja 2026-02-14 (ver. 0.271)
|
||||
- Dodano modul domenowy `Domain/Attribute/AttributeRepository.php`.
|
||||
- Dodano kontroler DI `admin/Controllers/ShopAttributeController.php`.
|
||||
- Modul `/admin/shop_attribute/*` zostal przepiety na nowe widoki (`attributes-list`, `attribute-edit`, `values-edit`).
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopAttribute.php`, `autoload/admin/factory/class.ShopAttribute.php`, `autoload/admin/view/class.ShopAttribute.php`, `admin/templates/shop-attribute/_partials/value.php`.
|
||||
- Przepieto zaleznosci kombinacji produktu na `Domain\Attribute\AttributeRepository` i `shop\ProductAttribute`.
|
||||
- Dla `ShopAttribute` routing celowo nie wykonuje fallbacku akcji do legacy kontrolera.
|
||||
|
||||
## Dodatkowa aktualizacja 2026-02-15 (ver. 0.272)
|
||||
- Dodano modul domenowy `Domain/ProductSet/ProductSetRepository.php`.
|
||||
- Dodano kontroler DI `admin/Controllers/ShopProductSetsController.php`.
|
||||
- Modul `/admin/shop_product_sets/*` dziala na nowych widokach (`product-sets-list`, `product-set-edit`).
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopProductSets.php`, `autoload/admin/factory/class.ShopProductSet.php`, `admin/templates/shop-product-sets/view-list.php`, `admin/templates/shop-product-sets/set-edit.php`.
|
||||
- `shop\ProductSet` przepiety na fasade do `Domain\ProductSet\ProductSetRepository`.
|
||||
|
||||
## Dodatkowa aktualizacja 2026-02-15 (ver. 0.273)
|
||||
- Dodano modul domenowy `Domain/Producer/ProducerRepository.php`.
|
||||
|
||||
## Dodatkowa aktualizacja 2026-02-15 (ver. 0.274)
|
||||
- Dodano modul domenowy `Domain/Client/ClientRepository.php`.
|
||||
- Dodano kontroler DI `admin/Controllers/ShopClientsController.php`.
|
||||
- Modul `/admin/shop_clients/*` dziala na nowych widokach opartych o `components/table-list`.
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopClients.php`, `autoload/admin/factory/class.ShopClients.php`.
|
||||
- Routing i menu admin przepiete na kanoniczny URL `/admin/shop_clients/list/`.
|
||||
- Dodano kontroler DI `admin/Controllers/ShopProducerController.php`.
|
||||
- Modul `/admin/shop_producer/*` dziala na nowych widokach (`producers-list`, `producer-edit`).
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopProducer.php`, `admin/templates/shop-producer/list.php`, `admin/templates/shop-producer/edit.php`.
|
||||
- `shop\Producer` przepiety na fasade do `Domain\Producer\ProducerRepository`.
|
||||
- `admin\controls\ShopProduct` uzywa `ProducerRepository::allProducers()`.
|
||||
- Usunieto 6 pustych factory facades: `admin\factory\Languages`, `admin\factory\Newsletter`, `admin\factory\Scontainers`, `admin\factory\ShopProducer`, `admin\factory\ShopTransport`, `admin\factory\Layouts`.
|
||||
- Przepieto 2 wywolania `admin\factory\ShopTransport` w `admin\factory\ShopProduct` na `Domain\Transport\TransportRepository`.
|
||||
- Usuniety fallback do `admin\factory\Layouts` w `admin\controls\ShopProduct`.
|
||||
|
||||
## Dodatkowa aktualizacja 2026-02-15 (ver. 0.274)
|
||||
- Dodano kontroler DI `admin/Controllers/ShopProductController.php` (akcje `mass_edit`, `mass_edit_save`, `get_products_by_category`).
|
||||
- Routing `admin\Site` rozszerzono o mapowanie `ShopProduct` do nowego kontrolera.
|
||||
- `Domain/Product/ProductRepository.php` rozszerzono o metody dla mass-edit: `allProductsForMassEdit`, `getProductsByCategory`, `applyDiscountPercent`.
|
||||
- Usunieto legacy akcje mass-edit z `autoload/admin/controls/class.ShopProduct.php`.
|
||||
- Widok `/admin/shop_product/mass_edit/` przepiety na nowy partial `admin/templates/shop-product/mass-edit-custom-script.php`.
|
||||
- Ujednolicono UI drzewek (strzalki/expand) w:
|
||||
- `admin/templates/pages/pages-list.php` + `admin/templates/pages/subpages-list.php`
|
||||
- `admin/templates/articles/subpages-list.php` + `admin/templates/articles/article-edit-custom-script.php`
|
||||
|
||||
## Dodatkowa aktualizacja 2026-02-15 (ver. 0.275)
|
||||
- Dodano modul domenowy `Domain/Category/CategoryRepository.php`.
|
||||
- Dodano kontroler DI `admin/Controllers/ShopCategoryController.php`.
|
||||
- Modul `/admin/shop_category/*` dziala przez DI i kanoniczny URL `/admin/shop_category/list/` (z zachowaniem aliasu `view_list`).
|
||||
- Widoki `shop-category/*` maja wydzielone skrypty `*-custom-script.php` i ujednolicone strzalki drzewa (`button + caret + aria-expanded`).
|
||||
- Endpointy AJAX dla drzewka kategorii i kolejnosci produktow przepiete na `/admin/shop_category/save_categories_order/`, `/admin/shop_category/save_products_order/`, `/admin/shop_category/cookie_categories/`.
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopCategory.php`, `autoload/admin/factory/class.ShopCategory.php`, `autoload/admin/view/class.ShopCategory.php`.
|
||||
- Przepieto zaleznosci `ShopProduct` z `admin\factory\ShopCategory` na `Domain\Category\CategoryRepository`.
|
||||
- Usunieto preload `autoload/admin/factory/class.ShopCategory.php` z `libraries/grid/config.php`.
|
||||
|
||||
## Dodatkowa aktualizacja 2026-02-15 (ver. 0.277) - ShopProduct (factory)
|
||||
- `Domain/Product/ProductRepository.php` rozszerzono o ~40 metod: CRUD, save, delete, duplicate, toggleStatus, updatePrice, kombinacje, zdjecia/pliki, Google Feed XML, custom labels.
|
||||
- `admin/Controllers/ShopProductController.php` rozszerzono o ~30 akcji obslugujacych caly modul produktow.
|
||||
- Konstruktor kontrolera teraz przyjmuje `ProductRepository` + `IntegrationsRepository`.
|
||||
- Routing w `admin\Site` zaktualizowany (dodano `IntegrationsRepository`, blokada fallbacku na legacy).
|
||||
- Przepieto zaleznosci zewnetrzne: `ProductArchiveController`, `order-details.php`, `cron.php`, `cron-xml.php`, `products-list-table.php`, `stock.php`.
|
||||
- Przepieto endpointy AJAX z `admin/ajax.php` na kontroler: `product_file_delete`, `product_file_name_change`.
|
||||
- Przepieto `cookie_categories` w widokach product-edit i mass-edit na `/admin/shop_category/cookie_categories/`.
|
||||
- Usunieto legacy: `autoload/admin/controls/class.ShopProduct.php`, `autoload/admin/factory/class.ShopProduct.php`, `admin/ajax/shop.php`.
|
||||
- Usunieto `require_once 'ajax/shop.php'` z `admin/ajax.php`.
|
||||
|
||||
## Dodatkowa aktualizacja 2026-02-16 (ver. 0.277) - Dashboard, Update, legacy cleanup, admin\App
|
||||
- Dodano `Domain/Dashboard/DashboardRepository.php` (7 metod, Redis caching).
|
||||
- Dodano `admin/Controllers/DashboardController.php` (DI z DashboardRepository + ShopStatusRepository).
|
||||
- Dodano `Domain/Update/UpdateRepository.php` (update, runPendingMigrations, helper methods).
|
||||
- Dodano `admin/Controllers/UpdateController.php` (DI z UpdateRepository).
|
||||
- Przepisano `admin/templates/update/main-view.php` — usunieto `gridEdit`, `$.prompt()`, zastapiono panelami + `$.confirm()`.
|
||||
- Usunieto `autoload/admin/factory/class.Articles.php` (martwy kod), przeniesiono `articles_by_date_add` do `ArticleRepository`.
|
||||
- Przepieto `front\factory\Newsletter` na `ArticleRepository::articlesByDateAdd()`.
|
||||
- Przeniesiono logike z `admin\view\Page::show()` do `admin\App::render()`.
|
||||
- Przemianowano `admin\Site` na `admin\App` (plik `App.php`).
|
||||
- Usunieto fallback na `\admin\controls\` w routing (martwy kod).
|
||||
- Usunieto puste foldery: `autoload/admin/controls/`, `autoload/admin/factory/`, `autoload/admin/view/`.
|
||||
- Usunieto stary plik `autoload/admin/class.Site.php`.
|
||||
- Pelna migracja admin zakonczona — wszystkie moduly na Domain + DI + Controllers.
|
||||
|
||||
## Aktualizacja 2026-02-16 (ver. 0.279) - Newsletter + Languages frontend migration
|
||||
- Usunięta fasada `front\factory\Languages` — wszystkie 26 zależności przepięte bezpośrednio na `Domain\Languages\LanguagesRepository`.
|
||||
- Usunięta fasada `front\factory\Newsletter` — logika przeniesiona do `Domain\Newsletter\NewsletterRepository` (6 nowych metod frontendowych).
|
||||
- Usunięty stary kontroler `front\controls\Newsletter` i widok `front\view\Newsletter`.
|
||||
- Utworzony nowy namespace `front\Controllers\` — pierwszy frontowy kontroler z DI: `NewsletterController`.
|
||||
- Utworzony nowy namespace `front\Views\` — czyste widoki statyczne: `Languages`, `Newsletter`, `Banners`.
|
||||
- Zaktualizowany routing w `front\controls\Site::route()` — `getControllerFactories()` (DI) z fallbackiem na stare `front\controls\`.
|
||||
- Przepięte 4 wywołania `Newsletter::get_template()` w `front\factory\ShopClient` na `NewsletterRepository::templateByName()`.
|
||||
- FIX: `newsletter_unsubscribe()` — błędna składnia medoo `delete()`.
|
||||
|
||||
## Aktualizacja 2026-02-16 (ver. 0.281) - Banners frontend migration
|
||||
- NOWE METODY w `Domain/Banner/BannerRepository.php`: `banners()`, `mainBanner()` (Redis cache, filtrowanie dat).
|
||||
- NOWY: `front\Views\Banners` — czysty VIEW (renderowanie szablonow banner/).
|
||||
- USUNIETA: `front\factory\Banners` — logika przeniesiona do `BannerRepository`.
|
||||
- USUNIETA: `front\view\Banners` — zastapiona przez `front\Views\Banners`.
|
||||
- UPDATE: `front\view\Site::show()` — przepiecie na repo + Views.
|
||||
|
||||
## Aktualizacja 2026-02-16 (ver. 0.282) - Cache cleanup, Shared namespace
|
||||
- NOWY: `Shared\Cache\CacheHandler` + `Shared\Cache\RedisConnection` — namespace Shared.
|
||||
- USUNIETA: `class.CacheHandler.php` — wrapper, 60 odwolan przepietych na `\Shared\Cache\CacheHandler`.
|
||||
- USUNIETA: `class.RedisConnection.php` — wrapper, 12 odwolan przepietych na `\Shared\Cache\RedisConnection`.
|
||||
- USUNIETA: `class.Cache.php` — legacy file-based cache.
|
||||
- UPDATE: 6 plikow przepietych z `\Cache::fetch/store` na `CacheHandler` (ShopProduct, ShopPaymentMethod, ShopCategory, ShopTransport, ShopAttribute, DictionariesRepository).
|
||||
|
||||
## Aktualizacja 2026-02-16 - class.S.php migration, Mobile_Detect removal, S cleanup
|
||||
- USUNIETA: `class.Mobile_Detect.php` — przestarzala detekcja mobilna (UA v2.8.16), zastapiona responsive design.
|
||||
- USUNIETA: metoda `S::is_mobile()` i 3 warunki mobilne w `front\view\Site` (m_html/m_css/m_js zawsze puste).
|
||||
- USUNIETE z `LayoutsRepository`: pola `m_html`, `m_css`, `m_js` (save + defaultLayout).
|
||||
- CLEANUP `class.S.php`: usunieto 12 nieuzywanych metod (set_array_value, parse_name, clear_redis_cache, get_domain, pre_dump, escape, chmod_r, rrmdir, rcopy, pre, json_to_array, is_empty_dir).
|
||||
- FIX: `array_cartesian_product()` — iteracja po niezdefiniowanej zmiennej `$array` zamiast parametru `$input`.
|
||||
- PRZENIESIONA: `class.S.php` → `Shared\Helpers\Helpers` (namespace `Shared\Helpers`, klasa `Helpers`).
|
||||
- ZAMIENIONE: ~140 plikow — `\S::` → `\Shared\Helpers\Helpers::`.
|
||||
- NOWY: `tests/stubs/Helpers.php` — stub klasy Helpers dla testow.
|
||||
- USUNIETA: `autoload/class.S.php` — zastapiona przez `Shared\Helpers\Helpers`.
|
||||
|
||||
## Aktualizacja 2026-02-17 (ver. 0.286) - Layouts, Menu, Pages frontend migration
|
||||
- NOWE METODY w `Domain/Layouts/LayoutsRepository.php`: `categoryDefaultLayoutId()`, `getDefaultLayout()`, `getProductLayout()`, `getArticleLayout()`, `getCategoryLayout()`, `getActiveLayout()`.
|
||||
- NOWE METODY w `Domain/Pages/PagesRepository.php`: `frontPageDetails()`, `frontPageSort()`, `frontMainPageId()`, `frontLangUrl()`, `frontMenuDetails()`, `frontMenuPages()`.
|
||||
- NOWY: `front\Views\Menu` — czysty VIEW (`pages()`, `menu()`).
|
||||
- USUNIETA: `front\factory\class.Layouts.php` — logika przeniesiona do `LayoutsRepository`.
|
||||
- USUNIETA: `front\factory\class.Menu.php` — logika przeniesiona do `PagesRepository`.
|
||||
- USUNIETA: `front\factory\class.Pages.php` — logika przeniesiona do `PagesRepository`.
|
||||
- USUNIETA: `front\view\class.Menu.php` — zastapiona przez `front\Views\Menu`.
|
||||
- USUNIETA: `templates\menu\submenu.php` — martwy kod.
|
||||
|
||||
## Aktualizacja 2026-02-17 - Tpl namespace, CurlServer removal, thumb.php fix
|
||||
- NOWY: `autoload/Shared/Tpl/Tpl.php` — silnik szablonow w namespace `Shared\Tpl`.
|
||||
- USUNIETA: `autoload/class.Tpl.php` — zastapiona przez `Shared\Tpl\Tpl`.
|
||||
- USUNIETA: `autoload/curl.class.php` — klasa `CurlServer` bez referencji w projekcie.
|
||||
- ZAMIENIONE: ~135 plikow — `\Tpl::` / `new \Tpl` → `\Shared\Tpl\Tpl::` / `new \Shared\Tpl\Tpl`.
|
||||
- FIX: `libraries/thumb.php` — require przepiety na `Shared/Image/ImageManipulator.php`, poprawiony short open tag.
|
||||
- FIX: `Tpl::render()` branch 3 — sprawdzal `../templates_user/` ale ladowal `../templates/`.
|
||||
|
||||
## Aktualizacja 2026-02-17 (ver. 0.289) - ShopCategory + ShopClient frontend migration
|
||||
- **ShopCategory (frontend)** — migracja factory + view na Domain + Views
|
||||
- NOWE METODY w `CategoryRepository`: `getCategorySort()`, `categoryName()`, `categoryUrl()`, `frontCategoryDetails()`, `categoriesTree()`, `blogCategoryProducts()`, `categoryProductsCount()`, `productsId()`, `paginatedCategoryProducts()` — z Redis cache, language fallback SQL, stale zamiast magic numbers
|
||||
- NOWY: `front\Views\ShopCategory` — czysty VIEW (`categoryDescription()`, `categoryView()`, `categories()`)
|
||||
- USUNIETA: `front\factory\class.ShopCategory.php` — logika przeniesiona do `CategoryRepository`
|
||||
- USUNIETA: `front\view\class.ShopCategory.php` — zastapiona przez `front\Views\ShopCategory`
|
||||
- **ShopClient (frontend)** — migracja factory + view + controls na Domain + Views + Controllers
|
||||
- NOWE METODY w `ClientRepository`: `clientDetails()`, `clientEmail()`, `clientAddresses()`, `addressDetails()`, `addressDelete()`, `addressSave()`, `markAddressAsCurrent()`, `clientOrders()`, `authenticate()`, `createClient()`, `confirmRegistration()`, `generateNewPassword()`, `initiatePasswordRecovery()`
|
||||
- NOWY: `front\Views\ShopClient` — czysty VIEW (8 metod camelCase)
|
||||
- NOWY: `front\Controllers\ShopClientController` — instancyjny kontroler z DI (15 metod + `buildEmailBody()` helper)
|
||||
- USUNIETA: `front\factory\class.ShopClient.php`, `front\view\class.ShopClient.php`, `front\controls\class.ShopClient.php`
|
||||
- SECURITY FIX: usuniety hardcoded password bypass `'Legia1916'`
|
||||
- OPTYMALIZACJA: `buildEmailBody()` deduplikuje 4x powtorzony wzorzec budowania emaili z newslettera
|
||||
- OPTYMALIZACJA: `addressSave()` przyjmuje `array $data` zamiast 6 parametrow
|
||||
|
||||
---
|
||||
|
||||
## Aktualizacja 2026-02-17 (ver. 0.290) - ShopCoupon + ShopOrder frontend migration
|
||||
- **ShopCoupon (frontend)** — migracja controls + factory na Domain + Controllers
|
||||
- NOWE METODY w `CouponRepository`: `findByName()`, `isAvailable()`, `markAsUsed()`, `incrementUsedCount()`
|
||||
- NOWY: `front\Controllers\ShopCouponController` — instancyjny kontroler z DI (`useCoupon()`, `deleteCoupon()`)
|
||||
- KONWERSJA: `shop\Coupon` na fasade z dzialajacymi metodami (`is_one_time()`, `set_as_used()`)
|
||||
- FIX: kupony jednorazowe nigdy nie byly oznaczane jako uzyte
|
||||
- USUNIETA: `front\controls\class.ShopCoupon.php`, `front\factory\class.ShopCoupon.php`
|
||||
- **ShopOrder (frontend)** — migracja controls + factory + view na Domain + Controllers
|
||||
- NOWE METODY w `OrderRepository`: `findIdByHash()`, `findHashById()`, `orderDetailsFrontend()`, `generateOrderNumber()`, `createFromBasket()` (~180 linii logiki basket_save)
|
||||
- NOWY: `front\Controllers\ShopOrderController` — instancyjny kontroler z DI (`paymentConfirmation()`, `paymentStatusTpay()`, `paymentStatusPrzelewy24pl()`, `paymentStatusHotpay()`, `orderDetails()`)
|
||||
- POPRAWA: webhooks przelewy24/hotpay — ujednolicone z tpay (set_as_paid + update_status zamiast recznego $mdb->update)
|
||||
- UPDATE: `ShopBasketController` — DI OrderRepository, zmiana wywolan basket_save/order_hash
|
||||
- UPDATE: `ClientRepository::clientOrders()`, `shop\Order::order_resend_confirmation_email()`, `cron-turstmate.php` — przepiete na `OrderRepository`
|
||||
- USUNIETA: `front\controls\class.ShopOrder.php`, `front\factory\class.ShopOrder.php`, `front\view\class.ShopOrder.php`
|
||||
|
||||
## Aktualizacja 2026-02-17 (ver. 0.291) - ShopProducer frontend migration
|
||||
- NOWA METODA w `ProducerRepository`: `allActiveProducers()` — pełne dane aktywnych producentów
|
||||
- NOWY: `front\Controllers\ShopProducerController` — instancyjny kontroler z DI (products, list)
|
||||
- USUNIETA: `front\controls\class.ShopProducer.php` — logika przeniesiona do kontrolera + repo
|
||||
- USUNIETA: `autoload\shop\class.Producer.php` — fasada niepotrzebna
|
||||
- UPDATE: `front\view\Site::show()` — przepiecie na `$producerRepo->findForFrontend()`
|
||||
- UPDATE: `front\controls\Site::getControllerFactories()` — zarejestrowany `ShopProducer`
|
||||
|
||||
## Aktualizacja 2026-02-17 (ver. 0.293) - front\controls\Site + front\view\Site → front\App + front\LayoutEngine
|
||||
- Przemianowano `front\controls\Site` na `front\App` (plik `App.php`) — router z camelCase metodami.
|
||||
- Przemianowano `front\view\Site` na `front\LayoutEngine` (plik `LayoutEngine.php`) — layout engine z camelCase metodami.
|
||||
- Przepiete call sites: `index.php` (3 miejsca), `ajax.php` (1 miejsce).
|
||||
- Usuniete pliki: `autoload/front/controls/class.Site.php`, `autoload/front/view/class.Site.php`.
|
||||
- Usuniete puste foldery: `autoload/front/controls/`, `autoload/front/view/`.
|
||||
- Pelna migracja frontendu zakonczona — struktura `autoload/front/`: `App.php`, `LayoutEngine.php`, `Controllers/`, `Views/`.
|
||||
|
||||
## Aktualizacja 2026-02-17 (ver. 0.292) - ShopProduct + ShopPaymentMethod + ShopPromotion + ShopStatuses + ShopTransport frontend migration
|
||||
- **Pelna migracja front\factory\** — USUNIETY caly folder `autoload/front/factory/`; 5 ostatnich klas zmigrowanych:
|
||||
- `front\factory\ShopProduct` (~410 linii) → `ProductRepository` (~20 nowych metod frontendowych)
|
||||
- `front\factory\ShopPaymentMethod` → `PaymentMethodRepository` (metody frontendowe z Redis cache)
|
||||
- `front\factory\ShopPromotion` → `PromotionRepository` (5 metod applyType*)
|
||||
- `front\factory\ShopStatuses` → przepiecie bezposrednio na `ShopStatusRepository`
|
||||
- `front\factory\ShopTransport` → `TransportRepository` (4 metody frontendowe z Redis cache)
|
||||
- Usuniete legacy: `front\controls\class.ShopProduct.php`, `front\view\class.ShopPaymentMethod.php`, `front\view\class.ShopTransport.php`, `shop\class.PaymentMethod.php`
|
||||
- FIX: broken `transports_list()` w ajax.php → nowa metoda `forPaymentMethod()`
|
||||
- Pelna migracja frontendu zakonczona — `autoload/front/`: `App.php`, `LayoutEngine.php`, `Controllers/`, `Views/`
|
||||
|
||||
---
|
||||
*Dokument aktualizowany: 2026-02-17 (ver. 0.293)*
|
||||
### 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)
|
||||
|
||||
@@ -1,308 +0,0 @@
|
||||
# Plan Refaktoryzacji shopPRO - Domain-Driven Architecture
|
||||
|
||||
## Cel
|
||||
Stopniowe przeniesienie logiki biznesowej do architektury warstwowej:
|
||||
- **Domain/** - logika biznesowa (core)
|
||||
- **Admin/** - warstwa administratora
|
||||
- **Frontend/** - warstwa użytkownika
|
||||
- **Shared/** - współdzielone narzędzia
|
||||
|
||||
## Docelowa struktura
|
||||
|
||||
```
|
||||
autoload/
|
||||
├── Domain/ # Logika biznesowa (CORE) - namespace \Domain\
|
||||
│ ├── Product/
|
||||
│ │ ├── ProductRepository.php
|
||||
│ │ ├── ProductService.php # (przyszłość)
|
||||
│ │ └── ProductCacheService.php # (przyszłość)
|
||||
│ ├── Banner/
|
||||
│ │ └── BannerRepository.php
|
||||
│ ├── Settings/
|
||||
│ │ └── SettingsRepository.php
|
||||
│ ├── Cache/
|
||||
│ │ └── CacheRepository.php
|
||||
│ ├── Order/
|
||||
│ ├── Category/
|
||||
│ └── ...
|
||||
│
|
||||
├── admin/ # Warstwa administratora (istniejący katalog!)
|
||||
│ ├── Controllers/ # Nowe kontrolery - namespace \admin\Controllers\
|
||||
│ ├── controls/ # Stare kontrolery (legacy fallback)
|
||||
│ ├── factory/ # Stare helpery (legacy)
|
||||
│ └── view/ # Widoki (statyczne - OK bez zmian)
|
||||
│
|
||||
├── Frontend/ # Warstwa użytkownika (przyszłość)
|
||||
│ ├── Controllers/
|
||||
│ └── Services/
|
||||
│
|
||||
├── Shared/ # Współdzielone narzędzia
|
||||
│ ├── Cache/
|
||||
│ │ ├── CacheHandler.php
|
||||
│ │ └── RedisConnection.php
|
||||
│ └── Helpers/
|
||||
│ └── S.php
|
||||
│
|
||||
└── [LEGACY] # Stare klasy (stopniowo deprecated)
|
||||
├── shop/
|
||||
├── admin/factory/
|
||||
└── front/factory/
|
||||
```
|
||||
|
||||
### WAŻNE: Konwencja namespace → katalog (Linux case-sensitive!)
|
||||
- `\Domain\` → `autoload/Domain/` (duże D - nowy katalog)
|
||||
- `\admin\Controllers\` → `autoload/admin/Controllers/` (małe a - istniejący katalog)
|
||||
- NIE używać `\Admin\` (duże A) bo na serwerze Linux katalog to `admin/` (małe a)
|
||||
|
||||
## Zasady migracji
|
||||
|
||||
### 1. Stopniowość
|
||||
- Przenosimy **jedną funkcję na raz**
|
||||
- Zachowujemy kompatybilność wsteczną
|
||||
- Stare klasy działają jako fasady do nowych
|
||||
|
||||
### 2. Dependency Injection zamiast statycznych metod
|
||||
```php
|
||||
// ❌ STARE - statyczne
|
||||
class Product {
|
||||
public static function getQuantity($id) {
|
||||
global $mdb;
|
||||
return $mdb->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ NOWE - instancje z DI
|
||||
class ProductRepository {
|
||||
private $db;
|
||||
|
||||
public function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function getQuantity($id) {
|
||||
return $this->db->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Fasady dla kompatybilności
|
||||
```php
|
||||
// Stara klasa wywołuje nową
|
||||
namespace shop;
|
||||
|
||||
class Product {
|
||||
public static function getQuantity($id) {
|
||||
global $mdb;
|
||||
$repo = new \Domain\Product\ProductRepository($mdb);
|
||||
return $repo->getQuantity($id);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Proces migracji funkcji
|
||||
|
||||
### Krok 1: Wybór funkcji
|
||||
- Wybierz prostą funkcję statyczną
|
||||
- Sprawdź jej zależności
|
||||
- Przeanalizuj gdzie jest używana
|
||||
|
||||
### Krok 2: Stworzenie nowej struktury
|
||||
- Utwórz folder `Domain/{Module}/`
|
||||
- Stwórz odpowiednią klasę (Repository/Service/Entity)
|
||||
- Przenieś logikę
|
||||
|
||||
### Krok 3: Znalezienie użyć
|
||||
```bash
|
||||
grep -r "Product::getQuantity" .
|
||||
```
|
||||
|
||||
### Krok 4: Aktualizacja wywołań
|
||||
- Opcja A: Bezpośrednie wywołanie nowej klasy
|
||||
- Opcja B: Fasada w starej klasie (zalecane na początek)
|
||||
|
||||
### Krok 5: Testy
|
||||
- Napisz test jednostkowy dla nowej funkcji
|
||||
- Sprawdź czy stare wywołania działają
|
||||
|
||||
## Status migracji
|
||||
|
||||
### ✅ Zmigrowane moduły
|
||||
| # | Modul | Wersja | Zakres |
|
||||
|---|-------|--------|--------|
|
||||
| 1 | Cache | 0.237, 0.282 | CacheHandler, RedisConnection, clear_product_cache, Shared\Cache namespace, eliminacja class.Cache.php |
|
||||
| 2 | Product | 0.238-0.252, 0.274, 0.277 | getQuantity, getPrice, getName, archive/unarchive, allProductsForMassEdit, getProductsByCategory, applyDiscountPercent, pelna migracja factory (CRUD, save, delete, duplicate, kombinacje, zdjecia/pliki, Google Feed XML) |
|
||||
| 3 | Banner | 0.239, 0.281 | find, delete, save, kontroler DI, frontend: banners(), mainBanner() z Redis cache, usuniete fasady front\factory + front\view |
|
||||
| 4 | Settings | 0.240/0.250 | saveSettings, getSettings, kontroler DI |
|
||||
| 5 | Dictionaries | 0.251 | listForAdmin, find, save, delete, kontroler DI |
|
||||
| 6 | ProductArchive | 0.252 | kontroler DI, table-list |
|
||||
| 7 | Filemanager | 0.252 | kontroler DI, fix Invalid Key |
|
||||
| 8 | Users | 0.253 | CRUD, logon, 2FA, kontroler DI |
|
||||
| 9 | Languages | 0.254 | languages + translations, kontroler DI |
|
||||
| 10 | Layouts | 0.256 | find, save, delete, menusWithPages, categoriesTree |
|
||||
| 11 | Newsletter | 0.257-0.258 | subskrybenci, szablony, ustawienia |
|
||||
| 12 | Scontainers | 0.259 | listForAdmin, find, save, delete |
|
||||
| 13 | ArticlesArchive | 0.260 | restore, deletePermanently |
|
||||
| 14 | Articles | 0.261 | pelna migracja (CRUD, AJAX, galeria, pliki) |
|
||||
| 15 | Pages | 0.262 | menu/page CRUD, drzewo stron, AJAX |
|
||||
| 16 | Integrations | 0.263 | Apilo/ShopPRO, cleanup Sellasist/Baselinker |
|
||||
| 17 | ShopPromotion | 0.264-0.265 | listForAdmin, find, save, delete, categoriesTree |
|
||||
| 18 | ShopCoupon | 0.266 | listForAdmin, find, save, delete, categoriesTree |
|
||||
| 19 | ShopStatuses | 0.267 | listForAdmin, find, save, color picker |
|
||||
| 20 | ShopPaymentMethod | 0.268 | listForAdmin, find, save, allActive, mapowanie Apilo, DI kontroler |
|
||||
| 21 | ShopTransport | 0.269 | listForAdmin, find, save, allActive, allForAdmin, findActiveById, getTransportCost, lowestTransportPrice, getApiloCarrierAccountId, powiazanie z PaymentMethod, DI kontroler |
|
||||
| 22 | ShopAttribute | 0.271 | list/edit/save/delete/values, nowy edytor wartosci, cleanup legacy, przepiecie zaleznosci kombinacji |
|
||||
| 23 | ShopProductSets | 0.272 | listForAdmin, find, save, delete, allSets, allProductsMap, multi-select Selectize, DI kontroler |
|
||||
| 24 | ShopProducer | 0.273 | listForAdmin, find, save, delete, allProducers, producerProducts, fasada shop\Producer, DI kontroler |
|
||||
| 25 | ShopProduct (mass_edit) | 0.274 | DI kontroler + routing dla `mass_edit`, `mass_edit_save`, `get_products_by_category`, cleanup legacy akcji |
|
||||
| 26 | ShopClients | 0.274 | DI kontroler + routing dla `list/details`, nowe listy na `components/table-list`, cleanup legacy controls/factory |
|
||||
| 27 | ShopCategory | 0.275 | CategoryRepository + DI kontroler + routing, endpointy AJAX (`save_categories_order`, `save_products_order`, `cookie_categories`), cleanup legacy controls/factory/view |
|
||||
| 28 | ShopOrder | 0.276 | OrderRepository + OrderAdminService + DI kontroler + routing + nowe widoki (`orders-list`, `order-details`, `order-edit`) + cleanup legacy controls/factory/view-list |
|
||||
| 29 | ShopProduct (factory) | 0.277 | Pelna migracja factory: ProductRepository (CRUD, save, delete, duplicate, toggleStatus, updatePrice, kombinacje, zdjecia/pliki, Google Feed XML) + DI kontroler (list, edit, save, operacje, kombinacje, zdjecia/pliki) + routing + przepiecie zaleznosci (ProductArchive, order-details, cron, cron-xml, products-list-table, stock) + usunięcie legacy (controls, factory, ajax/shop.php) |
|
||||
| 30 | Dashboard | 0.277 | DashboardRepository (7 metod, Redis caching) + DashboardController (DI) + cleanup legacy controls/shop |
|
||||
| 31 | Update | 0.277 | UpdateRepository (update, runPendingMigrations, helper methods) + UpdateController (DI) + przepisany template (panele, $.confirm) + cleanup legacy controls/factory/view |
|
||||
| 32 | Legacy cleanup | 0.277 | Usunieto admin/factory/Articles (martwy kod), admin/view/Page → App::render(), puste foldery controls/factory/view |
|
||||
| 33 | admin\App | 0.277 | Rename Site → App, usunieto fallback na controls, uproszczony routing, plik App.php bez przedrostka class. |
|
||||
|
||||
### Product - szczegolowy status
|
||||
- ✅ getQuantity (ver. 0.238)
|
||||
- ✅ getPrice (ver. 0.239)
|
||||
- ✅ getName (ver. 0.239)
|
||||
- ✅ archive / unarchive (ver. 0.241/0.252)
|
||||
- ✅ allProductsForMassEdit (ver. 0.274)
|
||||
- ✅ getProductsByCategory (ver. 0.274)
|
||||
- ✅ applyDiscountPercent (ver. 0.274)
|
||||
- ✅ countProducts, listForAdmin, findForAdmin, allProductsList, productCategoriesText, getParentId (ver. 0.277)
|
||||
- ✅ saveProduct + helpery (ver. 0.277)
|
||||
- ✅ delete, duplicate, toggleStatus, updatePriceBrutto/Promo, updateCustomLabel (ver. 0.277)
|
||||
- ✅ getPermutations, generateCombinations, deleteCombination, countCombinations, saveCombination* (ver. 0.277)
|
||||
- ✅ deleteImage, updateImageAlt, saveImagesOrder, deleteFile, updateFileName, generateGoogleFeedXml, generateEAN (ver. 0.277)
|
||||
- ✅ updateCombinationPricesFromBase (ver. 0.277)
|
||||
- [ ] is_product_on_promotion (frontend — osobna migracja)
|
||||
- [ ] getFromCache (frontend — osobna migracja)
|
||||
- [ ] getProductImg (frontend — osobna migracja)
|
||||
|
||||
### 📋 Do zrobienia
|
||||
- Frontend: migracja `front\factory\ShopProduct`
|
||||
|
||||
## Kolejność refaktoryzacji (priorytet)
|
||||
|
||||
1-33: ✅ Cache, Product, Banner, Settings, Dictionaries, ProductArchive, Filemanager, Users, Pages, Integrations, ShopPromotion, ShopCoupon, ShopStatuses, ShopPaymentMethod, ShopTransport, ShopAttribute, ShopProductSets, ShopProducer, ShopProduct (mass_edit), ShopClients, ShopCategory, ShopOrder, ShopProduct (factory), Dashboard, Update, Legacy cleanup, admin\App
|
||||
34: ✅ Shared\Cache namespace (ver. 0.282) — CacheHandler + RedisConnection → Shared\Cache\, eliminacja class.Cache.php, przepiecie 6 plikow na CacheHandler
|
||||
35: ✅ Shared\Tpl namespace (ver. 0.285) — Tpl → Shared\Tpl\Tpl, eliminacja class.Tpl.php + curl.class.php, fix thumb.php
|
||||
36: ✅ ShopProducer frontend (ver. 0.291) — front\controls\ShopProducer + shop\Producer usunięte, front\Controllers\ShopProducerController z DI, allActiveProducers() w ProducerRepository
|
||||
|
||||
## Form Edit System
|
||||
|
||||
Nowy uniwersalny system formularzy edycji:
|
||||
- ✅ Klasy ViewModel: `FormFieldType`, `FormField`, `FormTab`, `FormAction`, `FormEditViewModel`
|
||||
- ✅ Walidacja: `FormValidator` z obsługą reguł per pole i sekcje językowe
|
||||
- ✅ Persist: `FormRequestHandler` - zapamiętywanie danych przy błędzie walidacji
|
||||
- ✅ Renderer: `FormFieldRenderer` - renderowanie wszystkich typów pól
|
||||
- ✅ Szablon: `admin/templates/components/form-edit.php` - uniwersalny layout
|
||||
- Wspierane typy pól: text, number, email, password, date, datetime, switch, select, textarea, editor, image, file, hidden, lang_section, color
|
||||
- Obsługa zakładek (vertical) i sekcji językowych (horizontal)
|
||||
- **Do zrobienia**: Przerobić pozostałe kontrolery/formularze (Product, Category, Pages, itd.)
|
||||
|
||||
Pelna dokumentacja: `docs/FORM_EDIT_SYSTEM.md`
|
||||
|
||||
## Zasady kodu
|
||||
|
||||
### 1. SOLID Principles
|
||||
- **S**ingle Responsibility - jedna klasa = jedna odpowiedzialność
|
||||
- **O**pen/Closed - otwarty na rozszerzenia, zamknięty na modyfikacje
|
||||
- **L**iskov Substitution - podklasy mogą zastąpić nadklasy
|
||||
- **I**nterface Segregation - wiele małych interfejsów
|
||||
- **D**ependency Inversion - zależności od abstrakcji
|
||||
|
||||
### 2. Nazewnictwo
|
||||
- **Entity** - `Product.php` (reprezentuje obiekt domenowy)
|
||||
- **Repository** - `ProductRepository.php` (dostęp do danych)
|
||||
- **Service** - `ProductService.php` (logika biznesowa)
|
||||
- **Controller** - `ProductController.php` (obsługa requestów)
|
||||
|
||||
### 3. Type Hinting
|
||||
```php
|
||||
// ✅ DOBRE
|
||||
public function getQuantity(int $id): ?int {
|
||||
return $this->db->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
}
|
||||
|
||||
// ❌ ZŁE
|
||||
public function getQuantity($id) {
|
||||
return $this->db->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
}
|
||||
```
|
||||
|
||||
## Narzędzia pomocnicze
|
||||
|
||||
### Autoloader (produkcja)
|
||||
Autoloader w 9 entry pointach obsługuje dwie konwencje:
|
||||
1. `autoload/{namespace}/class.{ClassName}.php` (legacy)
|
||||
2. `autoload/{namespace}/{ClassName}.php` (PSR-4, fallback)
|
||||
|
||||
Entry pointy: `index.php`, `ajax.php`, `api.php`, `cron.php`, `cron-turstmate.php`, `download.php`, `admin/index.php`, `admin/ajax.php`, `cron/cron-xml.php`
|
||||
|
||||
### Static Analysis
|
||||
```bash
|
||||
composer require --dev phpstan/phpstan
|
||||
vendor/bin/phpstan analyse autoload/Domain
|
||||
```
|
||||
|
||||
## Testowanie
|
||||
|
||||
### Framework: PHPUnit
|
||||
```bash
|
||||
composer test
|
||||
```
|
||||
|
||||
### Struktura testów
|
||||
```
|
||||
tests/
|
||||
├── Unit/
|
||||
│ ├── Domain/
|
||||
│ │ ├── Article/ArticleRepositoryTest.php
|
||||
│ │ ├── Banner/BannerRepositoryTest.php
|
||||
│ │ ├── Cache/CacheRepositoryTest.php
|
||||
│ │ ├── Coupon/CouponRepositoryTest.php
|
||||
│ │ ├── Dictionaries/DictionariesRepositoryTest.php
|
||||
│ │ ├── Integrations/IntegrationsRepositoryTest.php
|
||||
│ │ ├── PaymentMethod/PaymentMethodRepositoryTest.php
|
||||
│ │ ├── Producer/ProducerRepositoryTest.php
|
||||
│ │ ├── Product/ProductRepositoryTest.php
|
||||
│ │ ├── ProductSet/ProductSetRepositoryTest.php
|
||||
│ │ ├── Promotion/PromotionRepositoryTest.php
|
||||
│ │ ├── Settings/SettingsRepositoryTest.php
|
||||
│ │ ├── ShopStatus/ShopStatusRepositoryTest.php
|
||||
│ │ └── User/UserRepositoryTest.php
|
||||
│ └── admin/
|
||||
│ └── Controllers/
|
||||
│ ├── ArticlesControllerTest.php
|
||||
│ ├── DictionariesControllerTest.php
|
||||
│ ├── IntegrationsControllerTest.php
|
||||
│ ├── ProductArchiveControllerTest.php
|
||||
│ ├── SettingsControllerTest.php
|
||||
│ ├── ShopCouponControllerTest.php
|
||||
│ ├── ShopPaymentMethodControllerTest.php
|
||||
│ ├── ShopProducerControllerTest.php
|
||||
│ ├── ShopProductSetsControllerTest.php
|
||||
│ ├── ShopPromotionControllerTest.php
|
||||
│ ├── ShopStatusesControllerTest.php
|
||||
│ └── UsersControllerTest.php
|
||||
└── Integration/
|
||||
```
|
||||
**Lacznie: 454 testow, 1449 asercji**
|
||||
|
||||
Aktualizacja 2026-02-15 (ver. 0.273):
|
||||
- dodano testy `tests/Unit/Domain/Producer/ProducerRepositoryTest.php`
|
||||
- dodano testy `tests/Unit/admin/Controllers/ShopProducerControllerTest.php`
|
||||
|
||||
Aktualizacja 2026-02-14 (ver. 0.271):
|
||||
- dodano testy `tests/Unit/Domain/Attribute/AttributeRepositoryTest.php`
|
||||
- dodano testy `tests/Unit/admin/Controllers/ShopAttributeControllerTest.php`
|
||||
|
||||
Pelna dokumentacja testow: `TESTING.md`
|
||||
|
||||
---
|
||||
*Rozpoczęto: 2025-02-05*
|
||||
*Ostatnia aktualizacja: 2026-02-16*
|
||||
*Changelog zmian: `docs/CHANGELOG.md`*
|
||||
@@ -1,176 +0,0 @@
|
||||
# Plan Refaktoryzacji - ShopAttribute (`/admin/shop_attribute`)
|
||||
|
||||
Data przygotowania: 2026-02-14
|
||||
Tryb realizacji: Human In The Loop (HITL)
|
||||
Status: Zrealizowano kroki 0-6 (2026-02-14)
|
||||
|
||||
## 1. Cel i zakres
|
||||
|
||||
Celem jest pelna migracja modulu `shop_attribute` z legacy (`admin/controls`, `admin/factory`, `admin/view`, `grid/gridEdit`) na:
|
||||
|
||||
- `Domain/*` (repozytorium + logika zapisu),
|
||||
- `admin/Controllers/*` (DI),
|
||||
- nowe widoki oparte o `components/table-list` i `components/form-edit`,
|
||||
- kanoniczny routing (`list`, `edit`, `save`, `delete`, `values`, `values_save`) z kompatybilnoscia aliasow legacy.
|
||||
|
||||
Zakres obejmuje takze przeglad i przepiecie zaleznosci w innych klasach (admin/front/shop), aby usunac twarde powiazanie ze starym modulem.
|
||||
|
||||
## 2. Stan obecny (baseline)
|
||||
|
||||
### Legacy modułu
|
||||
- `autoload/admin/controls/class.ShopAttribute.php`
|
||||
- `autoload/admin/factory/class.ShopAttribute.php`
|
||||
- `autoload/admin/view/class.ShopAttribute.php`
|
||||
- `admin/templates/shop-attribute/*` (stare `grid` / `gridEdit` + AJAX `attribute_value_tpl`)
|
||||
|
||||
### Zaleznosci poza modulem
|
||||
- `autoload/admin/controls/class.ShopProduct.php` (lista atrybutow do kombinacji)
|
||||
- `admin/templates/shop-product/product-combination.php` (nazwy atrybut/wartosc)
|
||||
- `autoload/admin/factory/class.ShopProduct.php` (m.in. `value_details`, aktualizacja cen kombinacji)
|
||||
- `autoload/front/factory/class.ShopAttribute.php` i `autoload/shop/class.ProductAttribute.php` (odczyt front/shop)
|
||||
- `templates/shop-product/_partial/product-attribute.php`, `autoload/front/factory/class.ShopOrder.php`
|
||||
|
||||
### Ryzyka znalezione w aktualnym UI wartosci
|
||||
- domyslny jezyk w tytule jest hardcoded (`pl`),
|
||||
- wybor domyslnej wartosci oparty o indeksy wierszy (podatne na bledy po usuwaniu),
|
||||
- brak walidacji biznesowej (np. wymagane minimum 1 wartosc i 1 nazwa w jezyku domyslnym),
|
||||
- UX edycji wartosci jest malo czytelny przy duzej liczbie pozycji.
|
||||
|
||||
## 3. Architektura docelowa
|
||||
|
||||
### Nowe klasy
|
||||
- `autoload/Domain/Attribute/AttributeRepository.php`
|
||||
- `autoload/admin/Controllers/ShopAttributeController.php`
|
||||
|
||||
### Nowe widoki
|
||||
- `admin/templates/shop-attribute/attributes-list.php` (nowy `table-list`)
|
||||
- `admin/templates/shop-attribute/attribute-edit.php` (nowy `form-edit`)
|
||||
- `admin/templates/shop-attribute/attribute-values-edit.php` (nowy ekran wartosci)
|
||||
- `admin/templates/shop-attribute/attribute-values-custom-script.php` (logika JS dla wartosci)
|
||||
- `admin/templates/shop-attribute/_partials/value-row.php` (opcjonalny partial pojedynczego wiersza)
|
||||
|
||||
### Routing
|
||||
- kanoniczne:
|
||||
- `/admin/shop_attribute/list/`
|
||||
- `/admin/shop_attribute/edit/id={id}`
|
||||
- `/admin/shop_attribute/save/`
|
||||
- `/admin/shop_attribute/delete/id={id}`
|
||||
- `/admin/shop_attribute/values/id={id}`
|
||||
- `/admin/shop_attribute/values_save/id={id}`
|
||||
- brak aliasow kompatybilnosci legacy (decyzja: URL-e niekanoniczne nie sa utrzymywane)
|
||||
|
||||
## 4. Plan realizacji HITL (krok po kroku)
|
||||
|
||||
## Krok 0 - Freeze i test baseline
|
||||
Zakres:
|
||||
- uruchomienie testow referencyjnych (minimum smoke + wskazane pelne),
|
||||
- zapisanie stanu wyjsciowego i listy plikow modulu.
|
||||
|
||||
Wyjscie:
|
||||
- potwierdzony baseline testow przed zmianami.
|
||||
|
||||
Punkt akceptacji HITL:
|
||||
- akceptacja startu implementacji po weryfikacji baseline.
|
||||
|
||||
## Krok 1 - Domain Repository (bez zmian UI)
|
||||
Zakres:
|
||||
- utworzenie `AttributeRepository` z metodami admin:
|
||||
- `listForAdmin()`, `findAttribute()`, `saveAttribute()`, `deleteAttribute()`,
|
||||
- `findValues()`, `saveValues()`,
|
||||
- pomocnicze: `getAttributeNameById()`, `getAttributeValueById()`, `getAttributesListForCombinations()`, `valueDetails()`.
|
||||
- normalizacja danych i bezpieczne parsowanie inputow (`switch`, liczby, tablice ID).
|
||||
- centralizacja invalidacji cache/temp po zapisach.
|
||||
|
||||
Wyjscie:
|
||||
- gotowa warstwa domenowa pod kontroler DI.
|
||||
|
||||
Punkt akceptacji HITL:
|
||||
- review API repozytorium i nazw metod przed podpieciem kontrolera.
|
||||
|
||||
## Krok 2 - Kontroler DI i routing
|
||||
Zakres:
|
||||
- dodanie `ShopAttributeController` (akcje list/edit/save/delete/values/valuesSave),
|
||||
- podpiecie do `admin\Site::$newControllers`,
|
||||
- ustawienie kanonicznych URL bez aliasow legacy,
|
||||
- aktualizacja linku menu do `/admin/shop_attribute/list/`.
|
||||
|
||||
Wyjscie:
|
||||
- modul dziala przez nowy kontroler, bez usuwania legacy w tym kroku.
|
||||
|
||||
Punkt akceptacji HITL:
|
||||
- potwierdzenie zgodnosci URL i backward compatibility.
|
||||
|
||||
## Krok 3 - Migracja widokow (lista + formularz cechy)
|
||||
Zakres:
|
||||
- przepisanie listy na `components/table-list`,
|
||||
- przepisanie formularza cechy na `components/form-edit`,
|
||||
- utrzymanie obecnej funkcjonalnosci (status, typ, kolejnosc, nazwy per jezyk).
|
||||
|
||||
Wyjscie:
|
||||
- brak zaleznosci od `grid`/`gridEdit` w tych ekranach.
|
||||
|
||||
Punkt akceptacji HITL:
|
||||
- akceptacja UX i danych na liscie oraz formularzu cechy.
|
||||
|
||||
## Krok 4 - Nowy panel edycji wartosci (UX)
|
||||
Zakres:
|
||||
- przebudowa `values-edit` na bardziej intuicyjny formularz:
|
||||
- jeden czytelny widok tabelaryczny (wiersz = wartosc),
|
||||
- stabilny identyfikator wiersza zamiast indeksu do wyboru wartosci domyslnej,
|
||||
- walidacja: co najmniej 1 wartosc, nazwa w jezyku domyslnym, jedna domyslna wartosc,
|
||||
- jasne komunikaty bledow i podsumowanie zmian.
|
||||
- usuniecie zaleznosci od endpointu `attribute_value_tpl` (lub utrzymanie tylko jako alias fallback).
|
||||
|
||||
Wyjscie:
|
||||
- nowy edytor wartosci odporny na bledy indeksowania i wygodniejszy dla operatora.
|
||||
|
||||
Punkt akceptacji HITL:
|
||||
- decyzja biznesowa o finalnym UX (wariant A/B ponizej) i akceptacja wygladu.
|
||||
|
||||
### Warianty UX do decyzji
|
||||
- Wariant A (rekomendowany): osobny ekran `values`, ale w nowym ukladzie tabelarycznym + walidacje.
|
||||
- Wariant B: integracja wartosci bezposrednio w `attribute-edit` (mniej klikniec, ale wieksza zlozonosc formularza).
|
||||
|
||||
## Krok 5 - Przepiecie zaleznosci i usuniecie legacy
|
||||
Zakres:
|
||||
- przeszukanie i przepiecie wszystkich uzyc `admin\factory\ShopAttribute` w kodzie admina,
|
||||
- aktualizacja zaleznosci w miejscach zwiazanych z kombinacjami produktu,
|
||||
- usuniecie starych klas:
|
||||
- `autoload/admin/controls/class.ShopAttribute.php`
|
||||
- `autoload/admin/view/class.ShopAttribute.php`
|
||||
- `autoload/admin/factory/class.ShopAttribute.php` (po przepieciu wszystkich odwolan)
|
||||
- cleanup starych szablonow nieuzywanych.
|
||||
|
||||
Wyjscie:
|
||||
- brak runtime zaleznosci od legacy `ShopAttribute`.
|
||||
|
||||
Punkt akceptacji HITL:
|
||||
- akceptacja listy usuwanych plikow i finalnego cleanupu.
|
||||
|
||||
## Krok 6 - Testy + dokumentacja + release
|
||||
Zakres:
|
||||
- nowe testy:
|
||||
- `tests/Unit/Domain/Attribute/AttributeRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/ShopAttributeControllerTest.php`
|
||||
- uruchomienie regresji (co najmniej testy modułowe + docelowo caly suite),
|
||||
- aktualizacja dokumentacji:
|
||||
- `docs/DATABASE_STRUCTURE.md` (tabele atrybutow),
|
||||
- `docs/PROJECT_STRUCTURE.md`,
|
||||
- `docs/REFACTORING_PLAN.md`,
|
||||
- `docs/CHANGELOG.md`,
|
||||
- `docs/TESTING.md`.
|
||||
|
||||
Wyjscie:
|
||||
- modul gotowy do release, z domknietym testowaniem i dokumentacja.
|
||||
|
||||
Punkt akceptacji HITL:
|
||||
- finalna akceptacja pakietu zmian przed procedura releasowa.
|
||||
|
||||
## 5. Kryteria akceptacji
|
||||
|
||||
- `shop_attribute` dziala przez `ShopAttributeController` + `AttributeRepository`.
|
||||
- Lista i formularze nie korzystaja z `grid/gridEdit`.
|
||||
- Panel wartosci nie opiera domyslnej wartosci na nietrwalych indeksach.
|
||||
- Stare klasy `controls/view/factory` modulu zostaja usuniete po przepieciu zaleznosci.
|
||||
- Testy jednostkowe dla nowego repozytorium i kontrolera przechodza.
|
||||
- Dokumentacja techniczna jest zaktualizowana.
|
||||
@@ -1,138 +0,0 @@
|
||||
# Plan Refaktoryzacji: shop_payment_method
|
||||
|
||||
Data utworzenia: 2026-02-14
|
||||
Status: ZREALIZOWANY (Etapy 1-4 zakonczone: 2026-02-14)
|
||||
|
||||
## 1. Cel
|
||||
|
||||
Pelna migracja modulu `/admin/shop_payment_method/*` do obecnego standardu projektu:
|
||||
- `Domain/*` dla logiki danych,
|
||||
- `admin/Controllers/*` z DI dla routingu,
|
||||
- widoki oparte o `components/table-list` i `components/form-edit`,
|
||||
- usuniecie legacy klas/podpiecie zaleznosci.
|
||||
|
||||
## 2. Stan obecny (inwentaryzacja)
|
||||
|
||||
Aktualny modul jest legacy i opiera sie o `grid`:
|
||||
- `autoload/admin/controls/class.ShopPaymentMethod.php`
|
||||
- `autoload/admin/factory/class.ShopPaymentMethod.php`
|
||||
- `autoload/admin/view/class.ShopPaymentMethod.php` (pusta)
|
||||
- `admin/templates/shop-payment-method/view-list.php` (grid + inline edit)
|
||||
- menu: `admin/templates/site/main-layout.php` -> `/admin/shop_payment_method/view_list/`
|
||||
|
||||
Zaleznosci wykryte poza modulem:
|
||||
- `autoload/admin/controls/class.ShopTransport.php` korzysta z `admin\\factory\\ShopPaymentMethod::payments_list()`
|
||||
- `autoload/front/factory/class.ShopPaymentMethod.php` ma bezposrednie zapytania do `pp_shop_payment_methods`
|
||||
- `autoload/shop/class.PaymentMethod.php` ma bezposrednie zapytania do `pp_shop_payment_methods`
|
||||
- `cron.php` korzysta z `front\\factory\\ShopPaymentMethod::get_apilo_payment_method_id()`
|
||||
|
||||
## 3. Zakres refaktoru
|
||||
|
||||
W zakresie:
|
||||
1. Nowe repozytorium domenowe dla metod platnosci.
|
||||
2. Nowy kontroler admin z DI i routingiem kanonicznym.
|
||||
3. Nowe widoki listy i edycji (bez legacy `grid`).
|
||||
4. Przepiecie zaleznosci (`ShopTransport`, `front\\factory\\ShopPaymentMethod`, `shop\\PaymentMethod`) na nowe API.
|
||||
5. Cleanup legacy klas/plikow zwiazanych z modulem.
|
||||
6. Testy jednostkowe + aktualizacja dokumentacji.
|
||||
|
||||
Poza zakresem (na ten etap):
|
||||
1. Refaktoryzacja calego modulu `shop_transport` (zrobimy tylko przepiecie zaleznosci dot. payment methods).
|
||||
2. Zmiany biznesowe w checkout poza zachowaniem obecnej logiki.
|
||||
|
||||
## 4. Architektura docelowa
|
||||
|
||||
Planowane nowe pliki:
|
||||
- `autoload/Domain/PaymentMethod/PaymentMethodRepository.php`
|
||||
- `autoload/admin/Controllers/ShopPaymentMethodController.php`
|
||||
- `admin/templates/shop-payment-method/payment-methods-list.php`
|
||||
- `admin/templates/shop-payment-method/payment-method-edit.php`
|
||||
|
||||
Planowane aktualizacje:
|
||||
- `autoload/admin/class.Site.php` (rejestracja `ShopPaymentMethod` w DI routerze)
|
||||
- `admin/templates/site/main-layout.php` (kanoniczny URL `/admin/shop_payment_method/list/`)
|
||||
- `autoload/admin/controls/class.ShopTransport.php` (usuniecie zaleznosci od legacy factory)
|
||||
- `autoload/front/factory/class.ShopPaymentMethod.php` (fasada delegujaca do Domain repo)
|
||||
- `autoload/shop/class.PaymentMethod.php` (fasada delegujaca do Domain repo)
|
||||
|
||||
Planowane usuniecia:
|
||||
- `autoload/admin/controls/class.ShopPaymentMethod.php`
|
||||
- `autoload/admin/factory/class.ShopPaymentMethod.php`
|
||||
- `autoload/admin/view/class.ShopPaymentMethod.php`
|
||||
- `admin/templates/shop-payment-method/view-list.php`
|
||||
|
||||
## 5. Etapy realizacji (Human In The Loop)
|
||||
|
||||
### Etap 1: Domain + testy repozytorium
|
||||
Zakres:
|
||||
- utworzenie `PaymentMethodRepository` z metodami:
|
||||
- `listForAdmin(...)`
|
||||
- `find(int $id)`
|
||||
- `save(int $id, array $data)`
|
||||
- `allActive()`
|
||||
- `findActiveById(int $id)`
|
||||
- `isActive(int $id)`
|
||||
- `getApiloPaymentTypeId(int $id)`
|
||||
- `forTransport(int $transportId)`
|
||||
- dodanie testu: `tests/Unit/Domain/PaymentMethod/PaymentMethodRepositoryTest.php`
|
||||
|
||||
Checkpoint:
|
||||
- STOP i prosba o akceptacje po wdrozeniu etapu 1.
|
||||
|
||||
### Etap 2: Admin Controller + routing + nowe widoki
|
||||
Zakres:
|
||||
- nowy `ShopPaymentMethodController` (akcje: `list`, `edit`, `save`)
|
||||
- migracja listy/edycji na `table-list` + `form-edit`
|
||||
- podpiecie w `admin\\Site` (DI factory map)
|
||||
- kompatybilnosc URL:
|
||||
- kanoniczne: `/admin/shop_payment_method/list|edit|save/`
|
||||
- aliasy legacy do decyzji po wdrozeniu (proponuje: tymczasowo wlaczyc)
|
||||
- test kontrolera: `tests/Unit/admin/Controllers/ShopPaymentMethodControllerTest.php`
|
||||
|
||||
Checkpoint:
|
||||
- STOP i prosba o akceptacje po wdrozeniu etapu 2.
|
||||
|
||||
### Etap 3: Przepiecie zaleznosci miedzymodulowych
|
||||
Zakres:
|
||||
- `ShopTransport` pobiera liste platnosci przez nowe repozytorium (bez legacy factory)
|
||||
- `front\\factory\\ShopPaymentMethod` jako fasada do repozytorium domenowego
|
||||
- `shop\\PaymentMethod` jako fasada do repozytorium domenowego
|
||||
- zachowanie dotychczasowych podpisow metod (BC)
|
||||
|
||||
Checkpoint:
|
||||
- STOP i prosba o akceptacje po wdrozeniu etapu 3.
|
||||
|
||||
### Etap 4: Cleanup + finalne testy + dokumentacja
|
||||
Zakres:
|
||||
- usuniecie legacy klas/plikow dla `shop_payment_method`
|
||||
- uruchomienie testow:
|
||||
- najpierw targetowane testy PaymentMethod,
|
||||
- potem caly suite (`composer test` lub `./test.ps1`)
|
||||
- aktualizacja dokumentacji:
|
||||
- `docs/DATABASE_STRUCTURE.md`
|
||||
- `docs/PROJECT_STRUCTURE.md`
|
||||
- `docs/REFACTORING_PLAN.md`
|
||||
- `docs/CHANGELOG.md`
|
||||
- `docs/TESTING.md`
|
||||
|
||||
Checkpoint:
|
||||
- STOP i prosba o finalna akceptacje przed etapem release (zip/commit/push wg procedury KONIEC PRACY, jesli zlecisz).
|
||||
|
||||
## 6. Ryzyka i kontrola regresji
|
||||
|
||||
1. Ryzyko: utrata kompatybilnosci URL (`view_list`).
|
||||
Kontrola: tymczasowe aliasy lub redirect + test akcji.
|
||||
|
||||
2. Ryzyko: regresja checkout przy pobieraniu metod platnosci.
|
||||
Kontrola: zachowanie podpisow metod we `front\\factory\\ShopPaymentMethod` i `shop\\PaymentMethod`, testy repozytorium.
|
||||
|
||||
3. Ryzyko: `ShopTransport` przestanie pokazywac metody platnosci.
|
||||
Kontrola: jawne przepiecie zaleznosci i test manualny widoku edycji transportu.
|
||||
|
||||
## 7. Kryteria akceptacji
|
||||
|
||||
1. `/admin/shop_payment_method/list/` dziala na nowym kontrolerze i nowym widoku.
|
||||
2. `/admin/shop_payment_method/edit/id={id}` i zapis dzialaja bez `grid`.
|
||||
3. Brak zaleznosci od legacy `admin\\controls\\ShopPaymentMethod` i `admin\\factory\\ShopPaymentMethod`.
|
||||
4. `ShopTransport`, frontend checkout i `cron.php` dzialaja na niezmienionych API publicznych.
|
||||
5. Nowe testy przechodza, a pelny suite nie ma regresji.
|
||||
567
docs/TESTING.md
567
docs/TESTING.md
@@ -1,187 +1,48 @@
|
||||
# Testowanie shopPRO
|
||||
# Testowanie shopPRO
|
||||
|
||||
## Szybki start
|
||||
|
||||
### Pelny zestaw testow
|
||||
```bash
|
||||
composer test
|
||||
```
|
||||
|
||||
Alternatywnie (Windows):
|
||||
```bash
|
||||
# Pelny suite (PowerShell — rekomendowane)
|
||||
./test.ps1
|
||||
./test.bat
|
||||
./test-simple.bat
|
||||
./test-debug.bat
|
||||
```
|
||||
|
||||
Alternatywnie (Git Bash):
|
||||
```bash
|
||||
./test.sh
|
||||
```
|
||||
|
||||
### Konkretny plik testowy
|
||||
```bash
|
||||
# Konkretny plik
|
||||
./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php
|
||||
./test.ps1 tests/Unit/admin/Controllers/ArticlesControllerTest.php
|
||||
```
|
||||
|
||||
### Konkretny test (`--filter`)
|
||||
```bash
|
||||
# Konkretny test
|
||||
./test.ps1 --filter testGetQuantityReturnsCorrectValue
|
||||
|
||||
# Alternatywne
|
||||
composer test # standard
|
||||
./test.bat # testdox (czytelna lista)
|
||||
./test-simple.bat # kropki
|
||||
./test-debug.bat # debug
|
||||
./test.sh # Git Bash
|
||||
```
|
||||
|
||||
## Aktualny stan suite
|
||||
|
||||
Ostatnio zweryfikowano: 2026-02-18
|
||||
## Aktualny stan
|
||||
|
||||
```text
|
||||
OK (610 tests, 1817 assertions)
|
||||
```
|
||||
|
||||
Aktualizacja po usunieciu autoload/shop/ — 12 legacy klas (2026-02-18, ver. 0.294):
|
||||
```text
|
||||
Pelny suite: OK (610 tests, 1817 assertions)
|
||||
Zmodyfikowane testy: PromotionRepositoryTest (cache key \shop\Promotion → PromotionRepository)
|
||||
Zmodyfikowane testy: ShopOrderControllerTest (zamiana \shop\Coupon → CouponRepository DI)
|
||||
```
|
||||
Zweryfikowano: 2026-02-18 (ver. 0.294)
|
||||
|
||||
Aktualizacja po migracji front\controls\Site + front\view\Site (2026-02-17, ver. 0.293):
|
||||
```text
|
||||
Pelny suite: OK (610 tests, 1816 assertions)
|
||||
Brak nowych testow — czysty rename/restructure (klasy statyczne, bez logiki biznesowej)
|
||||
```
|
||||
## Konfiguracja
|
||||
|
||||
Aktualizacja po migracji ShopProduct + ShopPaymentMethod + ShopPromotion + ShopStatuses + ShopTransport frontend (2026-02-17, ver. 0.292):
|
||||
```text
|
||||
Pelny suite: OK (610 tests, 1816 assertions)
|
||||
Nowe testy: ProductRepositoryTest (+20: getSkuWithFallback, getEanWithFallback, isProductActiveCached, productCategoriesFront, getWarehouseMessageZero/Nonzero, topProductIds, newProductIds, promotedProductIdsCached, getMinimalPrice, productImageCached, productNameCached, productUrlCached, randomProductIds, productWp)
|
||||
Nowe testy: PaymentMethodRepositoryTest (+5: paymentMethodsCached, paymentMethodCached, paymentMethodsByTransportCached, forTransportCached)
|
||||
Nowe testy: PromotionRepositoryTest (+7: applyTypeWholeBasket, applyTypeCategoriesOr, applyTypeCategoryCondition 2 scenariusze, applyTypeCategoriesAnd)
|
||||
Nowe testy: TransportRepositoryTest (+5: transportCostCached, findActiveByIdCached, findActiveByIdCachedNull, forPaymentMethod, forPaymentMethodEmpty)
|
||||
Nowy stub: tests/stubs/ShopProduct.php (shop\Product::is_product_on_promotion, get_product_price)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji ShopProducer frontend (2026-02-17, ver. 0.291):
|
||||
```text
|
||||
Pelny suite: OK (573 tests, 1738 assertions)
|
||||
Nowe testy: ProducerRepositoryTest (+5: allActiveProducers full/null, findForFrontend invalid/notFound/withLanguage)
|
||||
Nowe testy: ShopProducerControllerTest (+3: constructorAcceptsRepository, hasMainActionMethods, constructorRequiresProducerRepository)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji ShopCoupon + ShopOrder frontend (2026-02-17, ver. 0.290):
|
||||
```text
|
||||
Pelny suite: OK (565 tests, 1716 assertions)
|
||||
Nowe testy: CouponRepositoryTest (+12: findByName 3 scenariusze, isAvailable 5 scenariuszy, markAsUsed 2 scenariusze, incrementUsedCount 2 scenariusze)
|
||||
Nowe testy: ShopCouponControllerTest (+3: constructorAcceptsRepository, hasMainActionMethods, constructorRequiresCouponRepository)
|
||||
Nowe testy: OrderRepositoryTest (+10: findIdByHash 3 scenariusze, findHashById 2 scenariusze, orderDetailsFrontend 3 scenariusze, generateOrderNumber 2 scenariusze)
|
||||
Nowe testy: ShopOrderControllerTest (+3: constructorAcceptsRepository, hasMainActionMethods, constructorRequiresOrderRepository)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji ShopCategory + ShopClient frontend (2026-02-17, ver. 0.289):
|
||||
```text
|
||||
Pelny suite: OK (537 tests, 1648 assertions)
|
||||
Nowe testy: CategoryRepositoryTest (+17: getCategorySort, categoryName, categoryUrl, frontCategoryDetails, categoriesTree, blogCategoryProducts, categoryProductsCount, productsId, paginatedCategoryProducts)
|
||||
Nowe testy: ClientRepositoryTest (+36: clientDetails, clientEmail, clientAddresses, addressDetails, addressDelete, addressSave, markAddressAsCurrent, authenticate 5 scenariuszy, createClient, confirmRegistration, generateNewPassword, initiatePasswordRecovery, clientOrders)
|
||||
Zaktualizowane: tests/stubs/Helpers.php (stuby: lang, error, delete_session)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji BasketCalculator + ShopBasketController + cms\Layout removal (2026-02-17, ver. 0.288):
|
||||
```text
|
||||
Pelny suite: OK (484 tests, 1528 assertions)
|
||||
Nowe testy: BasketCalculatorTest (+8: summaryWp, countProducts, countProductsText — singular/plural/cast)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Scontainers + ShopAttribute frontend (2026-02-17, ver. 0.287):
|
||||
```text
|
||||
Pelny suite: OK (476 tests, 1512 assertions)
|
||||
Nowe testy: ScontainersRepositoryTest (+2: frontScontainerDetails, frontScontainerDetailsFallback)
|
||||
Nowe testy: AttributeRepositoryTest (+4: frontAttributeDetails, frontAttributeDetailsFallback, frontValueDetails, frontValueDetailsFallback)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Layouts + Menu/Pages frontend (2026-02-17, ver. 0.286):
|
||||
```text
|
||||
Pelny suite: OK (470 tests, 1484 assertions)
|
||||
Nowe testy: LayoutsRepositoryTest (+8: categoryDefaultLayoutId, getDefaultLayout, getProductLayout fallback, getArticleLayout, getCategoryLayout fallback, getActiveLayout, getActiveLayout fallback, getActiveLayout null)
|
||||
Nowe testy: PagesRepositoryTest (+8: frontPageDetails, frontPageDetailsNull, frontMainPageId, frontMainPageIdFallback, frontPageSort, frontMenuDetails, frontMenuDetailsNull, frontMenuPages)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Banners frontend (2026-02-16, ver. 0.281):
|
||||
```text
|
||||
Pelny suite: OK (454 tests, 1449 assertions)
|
||||
Nowe testy: BannerRepositoryTest (+4: banners flat languages, banners null, mainBanner flat languages, mainBanner null)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Articles frontend (2026-02-16, ver. 0.280):
|
||||
```text
|
||||
Pelny suite: OK (450 tests, 1431 assertions)
|
||||
Nowe testy: ArticleRepositoryTest (+13: articleDetailsFrontend, copyFromFallback, articlesIds, pageArticlesCount, pageArticlesPagination, articleNoindex, news, topArticles, newsListArticles)
|
||||
Zaktualizowane: tests/bootstrap.php (stub: S::is_array_fix)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Newsletter + Languages frontend (2026-02-16, ver. 0.279):
|
||||
```text
|
||||
Pelny suite: OK (437 tests, 1398 assertions)
|
||||
Nowe testy: NewsletterRepositoryTest (+10: unsubscribe, confirmSubscription, getHashByEmail, removeByEmail, signup, constructorOptionalDeps)
|
||||
Zaktualizowane: tests/bootstrap.php (stuby: S::email_check, S::get_session, S::set_session)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Settings + Languages frontend (2026-02-16, ver. 0.278):
|
||||
```text
|
||||
Pelny suite: OK (427 tests, 1378 assertions)
|
||||
Nowe testy: SettingsRepositoryTest (+6: allSettings, getSingleValue, bugfix param), LanguagesRepositoryTest (+7: defaultLanguage, activeLanguages, translations)
|
||||
Zaktualizowane: tests/bootstrap.php (stub CacheHandler: get/set/exists)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Dashboard + Update + legacy cleanup (2026-02-16, ver. 0.277):
|
||||
```text
|
||||
Pelny suite: OK (414 tests, 1335 assertions)
|
||||
Nowe testy: DashboardControllerTest (4), DashboardRepositoryTest (6), UpdateControllerTest (6), UpdateRepositoryTest (6)
|
||||
```
|
||||
|
||||
Aktualizacja po stabilizacji ShopOrder / Integrations / Global Search (2026-02-15, ver. 0.277):
|
||||
```text
|
||||
Pelny suite: OK (385 tests, 1246 assertions)
|
||||
SettingsControllerTest: OK (7 tests, 10 assertions)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji ShopClients (2026-02-15, ver. 0.274) - testy punktowe:
|
||||
```text
|
||||
OK (10 tests, 34 assertions)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji ShopCategory (2026-02-15, ver. 0.275) - testy punktowe:
|
||||
```text
|
||||
OK (16 tests, 72 assertions)
|
||||
```
|
||||
|
||||
Pelny suite po migracji ShopCategory (2026-02-15, ver. 0.275):
|
||||
```text
|
||||
OK (377 tests, 1197 assertions)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji ShopOrder (2026-02-15, ver. 0.276) - testy punktowe:
|
||||
```text
|
||||
OK (8 tests, 49 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-15:
|
||||
- `tests/Unit/Domain/Client/ClientRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/ShopClientsControllerTest.php`
|
||||
- `tests/Unit/Domain/Category/CategoryRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/ShopCategoryControllerTest.php`
|
||||
- `tests/Unit/Domain/Order/OrderRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/ShopOrderControllerTest.php`
|
||||
- **PHPUnit 9.6** via `phpunit.phar`
|
||||
- **Bootstrap:** `tests/bootstrap.php`
|
||||
- **Config:** `phpunit.xml`
|
||||
|
||||
## Struktura testow
|
||||
|
||||
```text
|
||||
```
|
||||
tests/
|
||||
|-- bootstrap.php
|
||||
|-- stubs/
|
||||
| |-- CacheHandler.php
|
||||
| |-- Helpers.php
|
||||
| `-- ShopProduct.php
|
||||
| |-- CacheHandler.php (inline w bootstrap)
|
||||
| |-- Helpers.php (Shared\Helpers\Helpers stub)
|
||||
| `-- ShopProduct.php (shop\Product stub)
|
||||
|-- Unit/
|
||||
| |-- Domain/
|
||||
| | |-- Article/ArticleRepositoryTest.php
|
||||
@@ -189,10 +50,14 @@ tests/
|
||||
| | |-- Banner/BannerRepositoryTest.php
|
||||
| | |-- Basket/BasketCalculatorTest.php
|
||||
| | |-- Cache/CacheRepositoryTest.php
|
||||
| | |-- Coupon/CouponRepositoryTest.php
|
||||
| | |-- Category/CategoryRepositoryTest.php
|
||||
| | |-- Coupon/CouponRepositoryTest.php
|
||||
| | |-- Dictionaries/DictionariesRepositoryTest.php
|
||||
| | |-- Integrations/IntegrationsRepositoryTest.php
|
||||
| | |-- Languages/LanguagesRepositoryTest.php
|
||||
| | |-- Layouts/LayoutsRepositoryTest.php
|
||||
| | |-- Newsletter/NewsletterRepositoryTest.php
|
||||
| | |-- Pages/PagesRepositoryTest.php
|
||||
| | |-- PaymentMethod/PaymentMethodRepositoryTest.php
|
||||
| | |-- Producer/ProducerRepositoryTest.php
|
||||
| | |-- Product/ProductRepositoryTest.php
|
||||
@@ -220,70 +85,17 @@ tests/
|
||||
| |-- ShopStatusesControllerTest.php
|
||||
| |-- ShopTransportControllerTest.php
|
||||
| `-- UsersControllerTest.php
|
||||
`-- Integration/
|
||||
```
|
||||
|
||||
## Tryby uruchamiania
|
||||
|
||||
### 1. TestDox (czytelna lista)
|
||||
```bash
|
||||
./test.bat
|
||||
```
|
||||
Uruchamia:
|
||||
```bash
|
||||
C:\xampp\php\php.exe phpunit.phar --testdox
|
||||
```
|
||||
|
||||
### 2. Standard (kropki)
|
||||
```bash
|
||||
./test-simple.bat
|
||||
```
|
||||
Uruchamia:
|
||||
```bash
|
||||
C:\xampp\php\php.exe phpunit.phar
|
||||
```
|
||||
|
||||
### 3. Debug (pelne logowanie)
|
||||
```bash
|
||||
./test-debug.bat
|
||||
```
|
||||
Uruchamia:
|
||||
```bash
|
||||
C:\xampp\php\php.exe phpunit.phar --debug
|
||||
```
|
||||
|
||||
### 4. PowerShell (najbardziej niezawodne)
|
||||
```bash
|
||||
./test.ps1
|
||||
```
|
||||
- najpierw probuje `php` z PATH
|
||||
- jesli brak, probuje m.in. `C:\xampp\php\php.exe`
|
||||
- zawsze dodaje `--do-not-cache-result`
|
||||
|
||||
## Interpretacja wynikow
|
||||
|
||||
```text
|
||||
. = test przeszedl
|
||||
E = error (blad wykonania)
|
||||
F = failure (niezgodna asercja)
|
||||
```
|
||||
|
||||
Przyklad sukcesu:
|
||||
```text
|
||||
................................................................. 65 / 82 ( 79%)
|
||||
................. 82 / 82 (100%)
|
||||
|
||||
OK (82 tests, 181 assertions)
|
||||
`-- Integration/ (puste — zarezerwowane)
|
||||
```
|
||||
|
||||
## Dodawanie nowych testow
|
||||
|
||||
1. Dodaj plik w odpowiednim module, np. `tests/Unit/Domain/<Module>/<Class>Test.php`.
|
||||
1. Plik w `tests/Unit/Domain/<Module>/<Class>Test.php` lub `tests/Unit/admin/Controllers/<Class>Test.php`.
|
||||
2. Rozszerz `PHPUnit\Framework\TestCase`.
|
||||
3. Nazwy metod zaczynaj od `test`.
|
||||
4. Trzymaj sie wzorca AAA: Arrange, Act, Assert.
|
||||
4. Wzorzec AAA: Arrange, Act, Assert.
|
||||
|
||||
## Mockowanie (przyklad)
|
||||
## Mockowanie Medoo
|
||||
|
||||
```php
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
@@ -295,317 +107,10 @@ $value = $repo->getQuantity(123);
|
||||
$this->assertEquals(42, $value);
|
||||
```
|
||||
|
||||
## Przydatne informacje
|
||||
## Bootstrap — stuby
|
||||
|
||||
- Konfiguracja PHPUnit: `phpunit.xml`
|
||||
- Bootstrap testow: `tests/bootstrap.php`
|
||||
- Dodatkowy opis: `tests/README.md`
|
||||
|
||||
## Aktualizacja suite
|
||||
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (119 tests, 256 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/User/UserRepositoryTest.php` (25 testow: CRUD, logon, 2FA verify/send, checkLogin, updateById)
|
||||
- `tests/Unit/admin/Controllers/UsersControllerTest.php` (12 testow: kontrakty + normalizeUser)
|
||||
|
||||
Aktualizacja po migracji widokow Users (2026-02-12):
|
||||
```text
|
||||
OK (120 tests, 262 assertions)
|
||||
```
|
||||
|
||||
## Aktualizacja suite (finalizacja Users)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (120 tests, 262 assertions)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Languages (2026-02-12):
|
||||
```text
|
||||
OK (130 tests, 301 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Languages/LanguagesRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/LanguagesControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.254)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (130 tests, 301 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Languages/LanguagesRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/LanguagesControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.255)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (130 tests, 303 assertions)
|
||||
```
|
||||
|
||||
## Aktualizacja suite (release 0.256)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (141 tests, 336 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Layouts/LayoutsRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/LayoutsControllerTest.php`
|
||||
|
||||
Zaktualizowane testy 2026-02-12:
|
||||
- `tests/Unit/Domain/Languages/LanguagesRepositoryTest.php` (defaultLanguageId)
|
||||
- `tests/Unit/admin/Controllers/ArticlesControllerTest.php` (konstruktor + LayoutsRepository)
|
||||
|
||||
## Aktualizacja suite (release 0.257)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (150 tests, 372 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Newsletter/NewsletterRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/NewsletterControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.258)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (150 tests, 372 assertions)
|
||||
```
|
||||
|
||||
## Aktualizacja suite (release 0.259)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (158 tests, 397 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Scontainers/ScontainersRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/ScontainersControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.260)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (165 tests, 424 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Article/ArticleRepositoryTest.php` (rozszerzenie o testy `restore`, `deletePermanently`, `listArchivedForAdmin`)
|
||||
- `tests/Unit/admin/Controllers/ArticlesArchiveControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.261)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (176 tests, 439 assertions)
|
||||
```
|
||||
|
||||
Nowe testy/rozszerzenia 2026-02-13:
|
||||
- `tests/Unit/Domain/Article/ArticleRepositoryTest.php` (nowe przypadki dla `pagesSummaryForArticles`, `updateImageAlt`, `markFileToDelete`)
|
||||
- `tests/Unit/admin/Controllers/ArticlesControllerTest.php` (nowe kontrakty dla akcji `imageAltChange`, `fileNameChange`, `imageDelete`, `fileDelete`)
|
||||
|
||||
## Aktualizacja suite (release 0.261)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (178 tests, 443 assertions)
|
||||
```
|
||||
|
||||
Nowe testy/rozszerzenia 2026-02-13:
|
||||
- `tests/Unit/Domain/Article/ArticleRepositoryTest.php` (nowe przypadki dla `saveFilesOrder`)
|
||||
|
||||
## Aktualizacja suite (Pages migration)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (186 tests, 478 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-13:
|
||||
- `tests/Unit/Domain/Pages/PagesRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/PagesControllerTest.php`
|
||||
|
||||
Zaktualizowane testy 2026-02-13:
|
||||
- `tests/Unit/admin/Controllers/ArticlesControllerTest.php` (konstruktor z `Domain\\Pages\\PagesRepository`)
|
||||
|
||||
## Aktualizacja suite (Integrations refactor, ver. 0.263)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (212 tests, 577 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-13:
|
||||
- `tests/Unit/Domain/Integrations/IntegrationsRepositoryTest.php` (16 testow: getSettings, getSetting, saveSetting, linkProduct, unlinkProduct, getProductSku, apiloGetAccessToken, invalid provider, settings table mapping)
|
||||
- `tests/Unit/admin/Controllers/IntegrationsControllerTest.php` (10 testow: kontrakty metod, return types, brak metod sellasist/baselinker)
|
||||
|
||||
Zaktualizowane pliki:
|
||||
- `tests/bootstrap.php` (dodany stub `S::remove_special_chars()`)
|
||||
|
||||
## Aktualizacja suite (ShopPromotion refactor, ver. 0.264)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (222 tests, 609 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-13:
|
||||
- `tests/Unit/Domain/Promotion/PromotionRepositoryTest.php` (6 testow: find default, save insert, delete, whitelist sortowania, drzewo kategorii)
|
||||
- `tests/Unit/admin/Controllers/ShopPromotionControllerTest.php` (4 testy: kontrakty metod i DI konstruktora)
|
||||
|
||||
## Aktualizacja suite (ShopPromotion fix + date_from, ver. 0.265)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (222 tests, 614 assertions)
|
||||
```
|
||||
|
||||
Zmiany testowe 2026-02-13:
|
||||
- rozszerzenie `tests/Unit/Domain/Promotion/PromotionRepositoryTest.php` o asercje `date_from`
|
||||
|
||||
## Aktualizacja suite (ShopCoupon refactor, ver. 0.266)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (235 tests, 682 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-13:
|
||||
- `tests/Unit/Domain/Coupon/CouponRepositoryTest.php` (8 testow: find default/normalize, save insert/update, delete, whitelist sortowania, drzewo kategorii)
|
||||
- `tests/Unit/admin/Controllers/ShopCouponControllerTest.php` (5 testow: kontrakty metod, aliasy legacy, DI konstruktora)
|
||||
|
||||
Ponowna weryfikacja po poprawkach UI (drzewko + checkboxy): 2026-02-13
|
||||
- `OK (235 tests, 682 assertions)`
|
||||
|
||||
## Aktualizacja suite (ShopStatuses refactor, ver. 0.267)
|
||||
Ostatnio zweryfikowano: 2026-02-14
|
||||
|
||||
```text
|
||||
OK (254 tests, 736 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-14:
|
||||
- `tests/Unit/Domain/ShopStatus/ShopStatusRepositoryTest.php` (9 testow: find z ID=0, find null apilo, save update, save z ID=0, empty apilo sets null, reject negative ID, getApiloStatusId, getByIntegrationStatusId, allStatuses, whitelist sortowania)
|
||||
- `tests/Unit/admin/Controllers/ShopStatusesControllerTest.php` (5 testow: kontrakty metod, brak aliasow legacy, return types, DI konstruktora)
|
||||
|
||||
## Aktualizacja suite (ShopPaymentMethod refactor, ver. 0.268)
|
||||
Ostatnio zweryfikowano: 2026-02-14
|
||||
|
||||
```text
|
||||
OK (280 tests, 828 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-14:
|
||||
- `tests/Unit/Domain/PaymentMethod/PaymentMethodRepositoryTest.php` (14 testow: find invalid/null/normalize, save update/null/non-numeric apilo, listForAdmin whitelist, allActive, allForAdmin, findActiveById, isActive, getApiloPaymentTypeId, forTransport)
|
||||
- `tests/Unit/admin/Controllers/ShopPaymentMethodControllerTest.php` (5 testow: kontrakty metod, brak aliasow legacy, return types, DI konstruktora)
|
||||
|
||||
## Aktualizacja suite (ShopTransport refactor, ver. 0.269)
|
||||
Ostatnio zweryfikowano: 2026-02-14
|
||||
|
||||
```text
|
||||
OK (300 tests, 895 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-14:
|
||||
- `tests/Unit/Domain/Transport/TransportRepositoryTest.php` (14 testow: find invalid/null/normalize/nullables, save insert/update/failure/default reset/switch normalization, listForAdmin whitelist, allActive, getApiloCarrierAccountId, getTransportCost, allForAdmin)
|
||||
- `tests/Unit/admin/Controllers/ShopTransportControllerTest.php` (5 testow: kontrakty metod, brak aliasow legacy, return types, DI konstruktora z 2 repo)
|
||||
|
||||
## Aktualizacja suite (Apilo sync hardening, ver. 0.270)
|
||||
Ostatnio zweryfikowano: 2026-02-14
|
||||
|
||||
```text
|
||||
OK (300 tests, 895 assertions)
|
||||
```
|
||||
|
||||
Zmiany testowe 2026-02-14:
|
||||
- brak nowych testow; pelna regresja po zmianach sync Apilo (TPAY -> Apilo) przeszla bez bledow
|
||||
|
||||
## Aktualizacja suite (ShopAttribute refactor, ver. 0.271)
|
||||
Ostatnio zweryfikowano: 2026-02-14
|
||||
|
||||
```text
|
||||
OK (312 tests, 948 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-14:
|
||||
- `tests/Unit/Domain/Attribute/AttributeRepositoryTest.php` (5 testow: domyslne dane cechy, whitelist sortowania/paginacji, zapis wartosci i domyslnej, usuwanie pustych tlumaczen, jezyk domyslny)
|
||||
- `tests/Unit/admin/Controllers/ShopAttributeControllerTest.php` (7 testow: kontrakty metod, brak aliasow legacy, return types, DI konstruktora, walidacja `validateValuesRows`)
|
||||
|
||||
## Aktualizacja suite (ShopProductSets refactor, ver. 0.272)
|
||||
Ostatnio zweryfikowano: 2026-02-15
|
||||
|
||||
```text
|
||||
OK (324 tests, 1000 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-15:
|
||||
- `tests/Unit/Domain/ProductSet/ProductSetRepositoryTest.php` (7 testow: find default/normalize, save insert/update, delete invalid, whitelist sortowania/paginacji, allSets)
|
||||
- `tests/Unit/admin/Controllers/ShopProductSetsControllerTest.php` (5 testow: kontrakty metod, aliasy legacy, return types, DI konstruktora)
|
||||
|
||||
## Aktualizacja suite (ShopProducer refactor, ver. 0.273)
|
||||
Ostatnio zweryfikowano: 2026-02-15
|
||||
|
||||
```text
|
||||
OK (338 tests, 1063 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-15:
|
||||
- `tests/Unit/Domain/Producer/ProducerRepositoryTest.php` (9 testow: find default/normalize, save insert/update, delete invalid/success, whitelist sortowania/paginacji, allProducers, producerProducts)
|
||||
- `tests/Unit/admin/Controllers/ShopProducerControllerTest.php` (5 testow: kontrakty metod, aliasy legacy, return types, DI konstruktora)
|
||||
|
||||
## Aktualizacja suite (ShopProduct mass_edit, ver. 0.274)
|
||||
Ostatnio zweryfikowano: 2026-02-15
|
||||
|
||||
```text
|
||||
OK (351 tests, 1091 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-15:
|
||||
- `tests/Unit/Domain/Product/ProductRepositoryTest.php` (rozszerzenie: `allProductsForMassEdit`, `getProductsByCategory`, `applyDiscountPercent`)
|
||||
- `tests/Unit/admin/Controllers/ShopProductControllerTest.php` (7 testow: kontrakty metod, return types, DI konstruktora)
|
||||
|
||||
## Aktualizacja suite (Layouts + Menu/Pages frontend, ver. 0.286)
|
||||
Ostatnio zweryfikowano: 2026-02-17
|
||||
|
||||
```text
|
||||
OK (470 tests, 1484 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-17:
|
||||
- `tests/Unit/Domain/Layouts/LayoutsRepositoryTest.php` (rozszerzenie: +8 testow frontend: categoryDefaultLayoutId, getDefaultLayout, getProductLayout, getArticleLayout, getCategoryLayout, getActiveLayout)
|
||||
- `tests/Unit/Domain/Pages/PagesRepositoryTest.php` (rozszerzenie: +8 testow frontend: frontPageDetails, frontMainPageId, frontPageSort, frontLangUrl, frontMenuDetails, frontMenuPages)
|
||||
|
||||
## Aktualizacja suite (BasketCalculator + ShopBasketController, ver. 0.288)
|
||||
Ostatnio zweryfikowano: 2026-02-17
|
||||
|
||||
```text
|
||||
OK (484 tests, 1528 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-17:
|
||||
- `tests/Unit/Domain/Basket/BasketCalculatorTest.php` (8 testow: summaryWp, summaryWpEmpty, countProducts, countProductsEmpty, countProductsTextSingular, countProductsTextPlural2to4, countProductsTextPlural5Plus, countProductsTextCastsToInt)
|
||||
|
||||
## Aktualizacja suite (Scontainers + ShopAttribute frontend, ver. 0.287)
|
||||
Ostatnio zweryfikowano: 2026-02-17
|
||||
|
||||
```text
|
||||
OK (476 tests, 1512 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-17:
|
||||
- `tests/Unit/Domain/Scontainers/ScontainersRepositoryTest.php` (rozszerzenie: +2 testow frontend: frontScontainerDetails, frontScontainerDetailsFallback)
|
||||
- `tests/Unit/Domain/Attribute/AttributeRepositoryTest.php` (rozszerzenie: +4 testow frontend: frontAttributeDetails, frontAttributeDetailsFallback, frontValueDetails, frontValueDetailsFallback)
|
||||
`tests/bootstrap.php` rejestruje autoloader i definiuje stuby:
|
||||
- `Redis`, `RedisConnection` — klasy Redis (aby nie wymagac rozszerzenia)
|
||||
- `Shared\Cache\CacheHandler` — inline stub z `get()`/`set()`/`exists()`/`delete()`/`deletePattern()`
|
||||
- `Shared\Helpers\Helpers` — z `tests/stubs/Helpers.php`
|
||||
- `shop\Product` — z `tests/stubs/ShopProduct.php`
|
||||
|
||||
Reference in New Issue
Block a user