Files
shopPRO/docs/REFACTORING_PLAN.md
Jacek Pyziak 5e5d3d068a refactor(shop-statuses): migrate to DI, restructure docs into docs/ folder (0.268)
- Migrate ShopStatuses module to Domain + DI architecture
- Add ShopStatusRepository, ShopStatusesController with color picker
- Convert front\factory\ShopStatuses to facade
- Add FormFieldType::COLOR with HTML5 color picker
- Move documentation files to docs/ folder (PROJECT_STRUCTURE, REFACTORING_PLAN, CHANGELOG, FORM_EDIT_SYSTEM, TESTING, DATABASE_STRUCTURE)
- Tests: 254 tests, 736 assertions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:43:31 +01:00

9.2 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

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-13: Cache, Product, Banner, Settings, Dictionaries, ProductArchive, Filemanager, Users, Pages, Integrations, ShopPromotion, ShopCoupon, ShopStatuses

Nastepne: 14. Order 15. Category 16. 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
│   │   ├── 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
│           ├── ShopPromotionControllerTest.php
│           ├── ShopStatusesControllerTest.php
│           └── UsersControllerTest.php
└── Integration/

Łącznie: 254 testów, 736 asercji

Pelna dokumentacja testow: TESTING.md


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