Files
shopPRO/docs/REFACTORING_PLAN.md
Jacek Pyziak 6543f8dc31 feat: Add Transport module with repository, controller, and views
- Implemented TransportRepository for managing transport data with methods for listing, finding, saving, and retrieving transport costs.
- Created ShopTransportController to handle transport-related actions, including listing, editing, and saving transports.
- Added views for transport management: transports list and transport edit forms.
- Introduced JavaScript for responsive tabs in transport edit view.
- Updated testing suite with comprehensive unit tests for TransportRepository and ShopTransportController.
- Increased test coverage with new assertions and scenarios for transport functionalities.
2026-02-14 20:16:18 +01:00

9.7 KiB

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

// ❌ 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

// 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ć

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 CacheHandler, RedisConnection, clear_product_cache
2 Product 0.238-0.252 getQuantity, getPrice, getName, archive/unarchive
3 Banner 0.239 find, delete, save, kontroler DI
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

Product - szczegolowy status

  • getQuantity (ver. 0.238)
  • getPrice (ver. 0.239)
  • getName (ver. 0.239)
  • archive / unarchive (ver. 0.241/0.252)
  • is_product_on_promotion
  • getFromCache
  • getProductImg

📋 Do zrobienia

  • Order
  • Category
  • ShopAttribute
  • ShopProduct (factory)

Kolejność refaktoryzacji (priorytet)

1-21: Cache, Product, Banner, Settings, Dictionaries, ProductArchive, Filemanager, Users, Pages, Integrations, ShopPromotion, ShopCoupon, ShopStatuses, ShopPaymentMethod, ShopTransport

Nastepne: 22. Order 23. Category 24. ShopAttribute

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

  • Single Responsibility - jedna klasa = jedna odpowiedzialność
  • Open/Closed - otwarty na rozszerzenia, zamknięty na modyfikacje
  • Liskov Substitution - podklasy mogą zastąpić nadklasy
  • Interface Segregation - wiele małych interfejsów
  • Dependency 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

// ✅ 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

composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse autoload/Domain

Testowanie

Framework: PHPUnit

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
│   │   ├── Product/ProductRepositoryTest.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
│           ├── ShopPromotionControllerTest.php
│           ├── ShopStatusesControllerTest.php
│           └── UsersControllerTest.php
└── Integration/

Łącznie: 300 testów, 895 asercji

Pelna dokumentacja testow: TESTING.md


Rozpoczęto: 2025-02-05 Ostatnia aktualizacja: 2026-02-14 Changelog zmian: docs/CHANGELOG.md