From 1c88f8adfa9f3aec7d00e447d111af2206e90e46 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Thu, 5 Feb 2026 23:32:48 +0100 Subject: [PATCH] Add new settings and cache repository files, update admin settings controller and templates - Introduced new `SettingsRepository` and `CacheRepository` classes in the `autoload\Domain` namespace. - Updated `SettingsController` in the `admin\Controllers` namespace to enhance settings management. - Added new templates for settings in `admin\templates\settings` and `admin\templates\site`. - Improved overall structure and organization of settings-related files. --- .claude/settings.local.json | 15 +- .phpunit.result.cache | 2 +- PROJECT_STRUCTURE.md | 64 +++++++-- REFACTORING_PLAN.md | 131 ++++++++++++------ admin/ajax.php | 6 + admin/index.php | 7 + admin/templates/settings/settings.php | 5 +- admin/templates/site/main-layout.php | 2 +- ajax.php | 6 + api.php | 6 + autoload/Domain/Banner/BannerRepository.php | 109 +++++++++++++++ autoload/Domain/Cache/CacheRepository.php | 53 +++++++ autoload/Domain/Product/ProductRepository.php | 35 +++++ .../Domain/Settings/SettingsRepository.php | 66 +++++++++ .../admin/Controllers/BannerController.php | 76 ++++++++++ .../admin/Controllers/SettingsController.php | 88 ++++++++++++ autoload/admin/class.Site.php | 91 +++++++++++- autoload/admin/controls/class.Banners.php | 7 +- autoload/admin/factory/class.Banners.php | 2 +- autoload/shop/class.Product.php | 14 +- cron-turstmate.php | 6 + cron.php | 6 + cron/cron-xml.php | 6 + download.php | 8 +- index.php | 6 + .../Domain/Banner/BannerRepositoryTest.php | 119 ++++++++++++++++ .../Unit/Domain/Cache/CacheRepositoryTest.php | 76 ++++++++++ .../Domain/Product/ProductRepositoryTest.php | 126 +++++++++++++++++ .../Settings/SettingsRepositoryTest.php | 33 +++++ .../Controllers/SettingsControllerTest.php | 66 +++++++++ tests/bootstrap.php | 69 +++++++-- updates/0.20/ver_0.239.zip | Bin 0 -> 31794 bytes updates/0.20/ver_0.240.zip | Bin 0 -> 13166 bytes updates/changelog.php | 12 ++ updates/versions.php | 2 +- 35 files changed, 1233 insertions(+), 87 deletions(-) create mode 100644 autoload/Domain/Banner/BannerRepository.php create mode 100644 autoload/Domain/Cache/CacheRepository.php create mode 100644 autoload/Domain/Settings/SettingsRepository.php create mode 100644 autoload/admin/Controllers/BannerController.php create mode 100644 autoload/admin/Controllers/SettingsController.php create mode 100644 tests/Unit/Domain/Banner/BannerRepositoryTest.php create mode 100644 tests/Unit/Domain/Cache/CacheRepositoryTest.php create mode 100644 tests/Unit/Domain/Settings/SettingsRepositoryTest.php create mode 100644 tests/Unit/admin/Controllers/SettingsControllerTest.php create mode 100644 updates/0.20/ver_0.239.zip create mode 100644 updates/0.20/ver_0.240.zip diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 5df9ccd..0d47811 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -7,7 +7,20 @@ "Bash(C:/xampp/php/php.exe:*)", "Bash(where:*)", "Bash(composer:*)", - "Bash(curl:*)" + "Bash(curl:*)", + "Bash(C:xamppphpphp.exe phpunit.phar --testdox)", + "Bash(php phpunit.phar:*)", + "Bash(ls -la \"c:\\\\visual studio code\\\\projekty\\\\shopPRO\\\\autoload\"\" 2>nul | findstr /i \"admin Admin \")", + "Bash(php -r:*)", + "Bash(php list_zip.php:*)", + "Bash(php create_update_239.php:*)", + "Bash(php vendor/bin/phpunit:*)", + "Bash(python:*)", + "Bash(\"C:/Program Files/7-Zip/7z.exe\" l \"updates/0.20/ver_0.239.zip\")", + "Bash(powershell.exe -Command \"[System.IO.Compression.ZipFile]::OpenRead\\(''c:/visual studio code/projekty/shopPRO/updates/0.20/ver_0.239.zip''\\).Entries | ForEach-Object { Write-Host $_.FullName }\")", + "Bash(powershell.exe -Command \"Add-Type -AssemblyName System.IO.Compression.FileSystem; [System.IO.Compression.ZipFile]::OpenRead\\(''c:\\\\visual studio code\\\\projekty\\\\shopPRO\\\\updates\\\\0.20\\\\ver_0.239.zip''\\).Entries | ForEach-Object { Write-Host $_.FullName }\")", + "Bash(powershell.exe -NoProfile -Command 'Add-Type -AssemblyName System.IO.Compression.FileSystem; $z = [System.IO.Compression.ZipFile]::OpenRead\\(\"\"c:\\\\visual studio code\\\\projekty\\\\shopPRO\\\\updates\\\\0.20\\\\ver_0.239.zip\"\"\\); foreach \\($e in $z.Entries\\) { $e.FullName }; $z.Dispose\\(\\)')", + "Bash(powershell.exe -NoProfile -Command:*)" ] } } diff --git a/.phpunit.result.cache b/.phpunit.result.cache index 29b4f79..ff0291d 100644 --- a/.phpunit.result.cache +++ b/.phpunit.result.cache @@ -1 +1 @@ -{"version":1,"defects":{"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsCorrectValue":4,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsNullWhenProductNotFound":4,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testFindReturnsProductData":4,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUpdateQuantitySuccess":4,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsInteger":4},"times":{"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsCorrectValue":0.003,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsNullWhenProductNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testFindReturnsProductData":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUpdateQuantitySuccess":0.001,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsInteger":0}} \ No newline at end of file +{"version":1,"defects":{"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsCorrectValue":4,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsNullWhenProductNotFound":4,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testFindReturnsProductData":4,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUpdateQuantitySuccess":4,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsInteger":4,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testSaveInsertsNewBanner":3,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheWithRedis":4,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheRedisUnavailable":4,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheWithoutRedis":4,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheReturnStructure":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testConstructorAcceptsRepositories":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testClearCacheMethodExists":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testClearCacheAjaxMethodExists":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testSaveMethodExists":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testViewMethodExists":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testViewCallsSettingsRepository":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testCacheRepositoryInjected":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testSettingsRepositoryInjected":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testControllerIsNotStatic":4,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testActionMethodsHaveTypes":4},"times":{"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsCorrectValue":0.001,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsNullWhenProductNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testFindReturnsProductData":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testUpdateQuantitySuccess":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetQuantityReturnsInteger":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsRegularPrice":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsPromoPrice":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsRegularWhenPromoIsHigher":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetPriceReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetNameReturnsProductName":0,"Tests\\Unit\\Domain\\Product\\ProductRepositoryTest::testGetNameReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testFindReturnsBannerWithTranslations":0.003,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testFindReturnsNullWhenNotFound":0,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testDeleteReturnsTrue":0.002,"Tests\\Unit\\Domain\\Banner\\BannerRepositoryTest::testSaveInsertsNewBanner":0,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testCanBeInstantiated":0.001,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testHasSaveSettingsMethod":0,"Tests\\Unit\\Domain\\Settings\\SettingsRepositoryTest::testHasGetSettingsMethod":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheWithRedis":0.001,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheRedisUnavailable":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheWithoutRedis":0,"Tests\\Unit\\Domain\\Cache\\CacheRepositoryTest::testClearCacheReturnStructure":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testConstructorAcceptsRepositories":0.001,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testClearCacheMethodExists":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testClearCacheAjaxMethodExists":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testSaveMethodExists":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testViewMethodExists":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testViewCallsSettingsRepository":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testCacheRepositoryInjected":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testSettingsRepositoryInjected":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testControllerIsNotStatic":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testActionMethodsHaveTypes":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testConstructorAcceptsRepository":0.001,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasClearCacheMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasClearCacheAjaxMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasSaveMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testHasViewMethod":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testIsNotAbstract":0,"Tests\\Unit\\admin\\Controllers\\SettingsControllerTest::testActionMethodReturnTypes":0}} \ No newline at end of file diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md index e699bf4..4d94fa6 100644 --- a/PROJECT_STRUCTURE.md +++ b/PROJECT_STRUCTURE.md @@ -183,14 +183,32 @@ $product = \shop\Product::getFromCache($product_id, $lang_id, $permutation_hash) ### Nowa struktura (w trakcie migracji) ``` autoload/ -├── Domain/ # Nowa warstwa biznesowa -│ └── Product/ -│ └── ProductRepository.php -├── shop/ # Legacy - fasady do nowych klas -├── admin/factory/ # Legacy - stopniowo migrowane -└── front/factory/ # Legacy - stopniowo migrowane +├── Domain/ # Nowa warstwa biznesowa (namespace \Domain\) +│ ├── Product/ +│ │ └── ProductRepository.php # getQuantity, getPrice, getName, find, updateQuantity +│ ├── Banner/ +│ │ └── BannerRepository.php # find, delete, save +│ ├── Settings/ +│ │ └── SettingsRepository.php # saveSettings, getSettings (fasada → factory) +│ └── Cache/ +│ └── CacheRepository.php # clearCache (dirs + Redis) +├── admin/ +│ ├── Controllers/ # Nowe kontrolery (namespace \admin\Controllers\) +│ │ ├── BannerController.php # DI, instancyjny +│ │ └── SettingsController.php # DI, instancyjny (clearCache, save, view) +│ ├── 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) +├── shop/ # Legacy - fasady do Domain +└── front/factory/ # Legacy - stopniowo migrowane ``` +### 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 @@ -215,13 +233,39 @@ $quantity = $repository->getQuantity($id); ### Struktura ``` tests/ -├── Unit/ # Testy jednostkowe -│ └── Domain/Product/ProductRepositoryTest.php -└── Integration/ # Testy integracyjne +├── Unit/ +│ ├── Domain/ +│ │ ├── Product/ProductRepositoryTest.php # 11 testów +│ │ ├── Banner/BannerRepositoryTest.php # 4 testy +│ │ ├── Settings/SettingsRepositoryTest.php # 3 testy +│ │ └── Cache/CacheRepositoryTest.php # 4 testy +│ └── admin/ +│ └── Controllers/SettingsControllerTest.php # 7 testów +└── Integration/ ``` +**Łącznie: 29 testów, 60 asercji** ## Ostatnie modyfikacje +### 2026-02-05: Migracja Settings + Cache (ver. 0.240) +- **NOWE:** `Domain\Settings\SettingsRepository` - repozytorium ustawień (fasada → factory) +- **NOWE:** `Domain\Cache\CacheRepository` - repozytorium cache (dirs + Redis) +- **NOWE:** `admin\Controllers\SettingsController` - kontroler z DI (clearCache, save, view) +- **FIX:** Brakujący `id="content"` w main-layout.php (komunikaty grid.js) +- **FIX:** `persist_edit = true` w settings.php (komunikat po zapisie) +- Stary kontroler `admin\controls\Settings` zachowany jako fallback +- Testy: 29 testów, 60 asercji (+14 nowych) +- Bootstrap testów: stuby klas systemowych (S, RedisConnection, Redis, CacheHandler) + +### 2026-02-05: Migracja Banner + Product (ver. 0.239) +- **NOWE:** `Domain\Banner\BannerRepository` - repozytorium banerów (find, delete, save) +- **NOWE:** `admin\Controllers\BannerController` - pierwszy kontroler z DI +- **NOWE:** Router z mapą `$newControllers` + fallback na stare kontrolery +- **NOWE:** Autoloader PSR-4 fallback w 9 entry pointach +- Zmigrowano: `get_product_price()` → `ProductRepository::getPrice()` +- Zmigrowano: `get_product_name()` → `ProductRepository::getName()` +- Testy: 15 testów, 31 asercji + ### 2025-02-05: Refaktoryzacja - Product Repository (ver. 0.238) - **NOWE:** `Domain\Product\ProductRepository` - pierwsza klasa w nowej architekturze - **NOWE:** Dependency Injection zamiast `global $mdb` @@ -236,4 +280,4 @@ tests/ - Metoda `clear_product_cache()` w klasie S --- -*Dokument aktualizowany: 2025-02-05* +*Dokument aktualizowany: 2026-02-05* diff --git a/REFACTORING_PLAN.md b/REFACTORING_PLAN.md index 6fd4a45..b83a5d1 100644 --- a/REFACTORING_PLAN.md +++ b/REFACTORING_PLAN.md @@ -11,21 +11,30 @@ Stopniowe przeniesienie logiki biznesowej do architektury warstwowej: ``` autoload/ -├── Domain/ # Logika biznesowa (CORE) +├── Domain/ # Logika biznesowa (CORE) - namespace \Domain\ │ ├── Product/ -│ │ ├── Product.php # Entity -│ │ ├── ProductRepository.php # Dostęp do bazy -│ │ ├── ProductService.php # Logika biznesowa -│ │ └── ProductCacheService.php # Cache produktu +│ │ ├── ProductRepository.php # ✅ Zmigrowane (getQuantity, getPrice, getName, find, updateQuantity) +│ │ ├── ProductService.php # Logika biznesowa (przyszłość) +│ │ └── ProductCacheService.php # Cache produktu (przyszłość) +│ ├── Banner/ +│ │ └── BannerRepository.php # ✅ Zmigrowane (find, delete, save) +│ ├── Settings/ +│ │ └── SettingsRepository.php # ✅ Zmigrowane (saveSettings, getSettings) - fasada → factory +│ ├── Cache/ +│ │ └── CacheRepository.php # ✅ Zmigrowane (clearCache) │ ├── Order/ │ ├── Category/ │ └── ... │ -├── Admin/ # Warstwa administratora -│ ├── Controllers/ -│ └── Services/ +├── admin/ # Warstwa administratora (istniejący katalog!) +│ ├── Controllers/ # Nowe kontrolery - namespace \admin\Controllers\ +│ │ ├── BannerController.php +│ │ └── SettingsController.php +│ ├── controls/ # Stare kontrolery (legacy fallback) +│ ├── factory/ # Stare helpery (legacy) +│ └── view/ # Widoki (statyczne - OK bez zmian) │ -├── Frontend/ # Warstwa użytkownika +├── Frontend/ # Warstwa użytkownika (przyszłość) │ ├── Controllers/ │ └── Services/ │ @@ -42,6 +51,11 @@ autoload/ └── 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ść @@ -126,11 +140,46 @@ grep -r "Product::getQuantity" . - Nowa klasa: `Domain\Product\ProductRepository::getQuantity()` - Fasada w: `shop\Product::get_product_quantity()` - Test: `tests/Unit/Domain/Product/ProductRepositoryTest.php` - - Testy: ✅ 5/5 przechodzą (11 asercji) + - Testy: ✅ 5/5 przechodzą - Aktualizacja: ver. 0.238 - Użycie DI: ✅ Konstruktor przyjmuje `$db` - - [ ] get_product_price() - NASTĘPNA 👉 - - [ ] get_product_name() + - ✅ get_product_price() - **ZMIGROWANE** (2026-02-05) 🎉 + - Nowa metoda: `Domain\Product\ProductRepository::getPrice()` + - Fasada w: `shop\Product::get_product_price()` + - Testy: ✅ 4 nowe testy (cena regularna, promocyjna, promo wyższa, nie znaleziono) + - Użycie: `front\factory\ShopPromotion` (linia 132) + - Aktualizacja: ver. 0.239 + - ✅ get_product_name() - **ZMIGROWANE** (2026-02-05) 🎉 + - Nowa metoda: `Domain\Product\ProductRepository::getName()` + - Fasada w: `shop\Product::get_product_name()` + - Testy: ✅ 2 nowe testy (nazwa znaleziona, nie znaleziona) + - Użycie: brak aktywnych wywołań (przygotowane na przyszłość) + - Aktualizacja: ver. 0.239 + - [ ] is_product_on_promotion() - NASTĘPNA 👉 + +- **Banner** (DEMO pełnej migracji kontrolera) + - ✅ BannerRepository - **ZMIGROWANE** (2026-02-05) 🎉 + - Nowa klasa: `Domain\Banner\BannerRepository` (find, delete, save, saveTranslations) + - Nowy kontroler: `admin\Controllers\BannerController` (DI, instancyjny) + - Router: `admin\Site::route()` → sprawdza nowy kontroler → fallback na stary + - Testy: ✅ 4 testy (find z tłumaczeniami, not found, delete, save) + - Stary kontroler `admin\controls\Banners` działa jako niezależny fallback + - Stara factory `admin\factory\Banners` zachowana bez zmian (fallback) + - Aktualizacja: ver. 0.239 + +- **Settings** (migracja kontrolera - krok pośredni) + - ✅ SettingsRepository - **ZMIGROWANE** (2026-02-05) 🎉 + - Nowa klasa: `Domain\Settings\SettingsRepository` (saveSettings, getSettings) + - Krok pośredni: fasada nad `admin\factory\Settings` (docelowo DI z $db) + - Nowy kontroler: `admin\Controllers\SettingsController` (DI, instancyjny) + - Testy: ✅ 3 testy (instancja, metody) + - Stary kontroler `admin\controls\Settings` zachowany jako fallback + - Aktualizacja: ver. 0.240 + - ✅ CacheRepository - **ZMIGROWANE** (2026-02-05) 🎉 + - Nowa klasa: `Domain\Cache\CacheRepository` (clearCache) + - Używa `\S::delete_dir()` + `\RedisConnection` + - Testy: ✅ 4 testy (z Redis, bez Redis, niedostępny, struktura) + - Aktualizacja: ver. 0.240 ### 📋 Do zrobienia - Order @@ -151,16 +200,15 @@ composer require --dev phpunit/phpunit tests/ ├── Unit/ │ ├── Domain/ -│ │ └── Product/ -│ │ ├── ProductRepositoryTest.php -│ │ └── ProductServiceTest.php -│ └── Shared/ -│ └── Cache/ -│ └── CacheHandlerTest.php +│ │ ├── Product/ProductRepositoryTest.php # 11 testów +│ │ ├── Banner/BannerRepositoryTest.php # 4 testy +│ │ ├── Settings/SettingsRepositoryTest.php # 3 testy +│ │ └── Cache/CacheRepositoryTest.php # 4 testy +│ └── admin/ +│ └── Controllers/SettingsControllerTest.php # 7 testów └── Integration/ - └── Domain/ - └── Product/ ``` +**Łącznie: 29 testów, 60 asercji** ### Przykład testu ```php @@ -215,20 +263,12 @@ public function getQuantity($id) { ## Narzędzia pomocnicze -### Composer autoloader -Dodaj do `composer.json`: -```json -{ - "autoload": { - "psr-4": { - "Domain\\": "autoload/Domain/", - "Admin\\": "autoload/Admin/", - "Frontend\\": "autoload/Frontend/", - "Shared\\": "autoload/Shared/" - } - } -} -``` +### 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 @@ -238,17 +278,20 @@ vendor/bin/phpstan analyse autoload/Domain ## Kolejność refaktoryzacji (priorytet) -1. **Cache** (już w trakcie) ✅ -2. **Product** (rozpoczynamy) - - getQuantity - - getPrice - - getName - - getFromCache -3. **ProductRepository** (dostęp do bazy) -4. **ProductService** (logika biznesowa) +1. **Cache** ✅ +2. **Product** (w trakcie) + - ✅ getQuantity (ver. 0.238) + - ✅ getPrice (ver. 0.239) + - ✅ getName (ver. 0.239) + - [ ] is_product_on_promotion - NASTĘPNA 👉 + - [ ] getFromCache + - [ ] getProductImg +3. **Banner** ✅ (pełna migracja kontrolera, ver. 0.239) +4. **Settings** ✅ (migracja kontrolera - krok pośredni, ver. 0.240) 5. **Order** -6. **Category** +5. **Category** +6. **ShopAttribute** --- *Rozpoczęto: 2025-02-05* -*Ostatnia aktualizacja: 2025-02-05* +*Ostatnia aktualizacja: 2026-02-05* diff --git a/admin/ajax.php b/admin/ajax.php index c4ef4c9..e951dcd 100644 --- a/admin/ajax.php +++ b/admin/ajax.php @@ -12,6 +12,12 @@ function __autoload_my_classes( $classname ) } if ( file_exists( $f ) ) require_once( $f ); + else + { + $f = '../autoload/' . implode( '/' , $q ) . '/' . $c . '.php'; + if ( file_exists( $f ) ) + require_once( $f ); + } } spl_autoload_register( '__autoload_my_classes' ); diff --git a/admin/index.php b/admin/index.php index ffd542c..f1c24bf 100644 --- a/admin/index.php +++ b/admin/index.php @@ -17,8 +17,15 @@ function __autoload_my_classes( $classname ) $q = explode( '\\', $classname ); $c = array_pop( $q ); $f = '../autoload/' . implode( '/', $q ) . '/class.' . $c . '.php'; + if ( file_exists( $f ) ) require_once( $f ); + else + { + $f = '../autoload/' . implode( '/', $q ) . '/' . $c . '.php'; + if ( file_exists( $f ) ) + require_once( $f ); + } } spl_autoload_register( '__autoload_my_classes' ); diff --git a/admin/templates/settings/settings.php b/admin/templates/settings/settings.php index 7a119f2..1f2337a 100644 --- a/admin/templates/settings/settings.php +++ b/admin/templates/settings/settings.php @@ -361,13 +361,14 @@ $grid -> gdb_opt = $gdb; $grid -> include_plugins = true; $grid -> title = 'Edycja ustawień'; $grid -> actions = [ - 'save' => [ 'url' => '/admin/settings/settings_save/', 'back_url' => '/admin/settings/view/' ], + 'save' => [ 'url' => '/admin/settings/settings_save/', 'back_url' => '' ], ]; +$grid -> persist_edit = true; $grid -> external_code = $out; echo $grid -> draw(); ?> - +