Files
shopPRO/docs/REFACTORING_PLAN.md

14 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, 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

  • 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
│   │   ├── 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