440 lines
23 KiB
Markdown
440 lines
23 KiB
Markdown
# Struktura Projektu shopPRO
|
||
|
||
Dokumentacja struktury projektu shopPRO do szybkiego odniesienia.
|
||
|
||
## System Cache (Redis)
|
||
|
||
### Klasy odpowiedzialne za cache
|
||
|
||
#### RedisConnection
|
||
- **Plik:** `autoload/class.RedisConnection.php`
|
||
- **Opis:** Singleton zarządzający połączeniem z Redis
|
||
- **Metody:**
|
||
- `getInstance()` - pobiera instancję połączenia
|
||
- `getConnection()` - zwraca obiekt Redis
|
||
|
||
#### CacheHandler
|
||
- **Plik:** `autoload/class.CacheHandler.php`
|
||
- **Opis:** Handler do obsługi cache Redis
|
||
- **Metody:**
|
||
- `get($key)` - pobiera wartość z cache
|
||
- `set($key, $value, $ttl = 86400)` - zapisuje wartość do cache
|
||
- `exists($key)` - sprawdza czy klucz istnieje
|
||
- `delete($key)` - usuwa pojedynczy klucz
|
||
- `deletePattern($pattern)` - usuwa klucze według wzorca
|
||
|
||
#### Klasa S (pomocnicza)
|
||
- **Plik:** `autoload/class.S.php`
|
||
- **Metody cache:**
|
||
- `clear_redis_cache()` - czyści cały cache Redis (flushAll)
|
||
- `clear_product_cache(int $product_id)` - czyści cache konkretnego produktu
|
||
|
||
### Wzorce kluczy Redis
|
||
|
||
#### Produkty
|
||
```
|
||
shop\product:{product_id}:{lang_id}:{permutation_hash}
|
||
```
|
||
- Przechowuje zserializowany obiekt produktu
|
||
- TTL: 24 godziny (86400 sekund)
|
||
- Klasa: `shop\Product::getFromCache()` - `autoload/shop/class.Product.php:121`
|
||
|
||
#### Opcje ilościowe produktu
|
||
```
|
||
\shop\Product::get_product_permutation_quantity_options:{product_id}:{permutation}
|
||
```
|
||
- Przechowuje informacje o ilości i komunikatach magazynowych
|
||
- Klasa: `shop\Product::get_product_permutation_quantity_options()` - `autoload/shop/class.Product.php:549`
|
||
|
||
#### Zestawy produktów
|
||
```
|
||
\shop\Product::product_sets_when_add_to_basket:{product_id}
|
||
```
|
||
- Przechowuje produkty często kupowane razem
|
||
- Klasa: `shop\Product::product_sets_when_add_to_basket()` - `autoload/shop/class.Product.php:316`
|
||
|
||
## Integracje z systemami zewnętrznymi (CRON)
|
||
|
||
### Plik: `cron.php`
|
||
|
||
#### Sellasist
|
||
- **Aktualizacja produktów:** Linia 111-149
|
||
- **Funkcje:** Aktualizacja cen i stanów magazynowych
|
||
- **Częstotliwość:** Co 10 minut
|
||
- **Czyszczenie cache:** Linia 146
|
||
|
||
#### Apilo
|
||
- **Aktualizacja pojedynczego produktu:** Linia 152-176
|
||
- Częstotliwość: Co 10 minut
|
||
- Czyszczenie cache: Linia 173
|
||
|
||
- **Synchronizacja cennika:** Linia 179-218
|
||
- Częstotliwość: Co 1 godzinę
|
||
- Czyszczenie cache: Linia 212
|
||
|
||
#### Baselinker
|
||
- **Aktualizacja produktów:** Linia 220-289
|
||
- **Funkcje:** Ceny, stany magazynowe, wagi
|
||
- **Częstotliwość:** Co 24 godziny (1440 minut)
|
||
- **Czyszczenie cache:** Linia 278
|
||
|
||
## 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
|
||
│ │ ├── controls/ # Kontrolery
|
||
│ │ └── factory/ # Fabryki/helpery
|
||
│ ├── front/ # Klasy frontendu
|
||
│ │ └── factory/ # Fabryki/helpery
|
||
│ └── shop/ # Klasy sklepu
|
||
├── libraries/ # Biblioteki zewnętrzne
|
||
├── temp/ # Cache tymczasowy
|
||
├── thumbs/ # Miniatury zdjęć
|
||
└── cron.php # Zadania CRON
|
||
|
||
```
|
||
|
||
## Baza danych
|
||
|
||
### 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
|
||
|
||
### Tabele integracji
|
||
- Kolumny w `pp_shop_products`:
|
||
- `sellasist_product_id`, `sellasist_get_data_date`
|
||
- `apilo_product_id`, `apilo_get_data_date`
|
||
- `baselinker_product_id`, `baselinker_get_data_date`
|
||
|
||
## Konfiguracja
|
||
|
||
### Redis
|
||
- Konfiguracja: `config.php` (zmienna `$config['redis']`)
|
||
- Parametry: host, port, password
|
||
|
||
### Autoload
|
||
- Funkcja: `__autoload_my_classes()` w `cron.php:6`
|
||
- Wzorzec: `autoload/{namespace}/class.{ClassName}.php`
|
||
|
||
## Klasy pomocnicze
|
||
|
||
### \S (autoload/class.S.php)
|
||
Główna klasa helper 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
|
||
|
||
### Medoo
|
||
- Plik: `libraries/medoo/medoo.php`
|
||
- Zmienna: `$mdb`
|
||
- ORM do operacji na bazie danych
|
||
|
||
## Najważniejsze wzorce
|
||
|
||
### 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\` - helpery/fabryki frontend
|
||
- `\shop\` - klasy sklepu (Product, Order, itp.)
|
||
|
||
### Cachowanie produktów
|
||
```php
|
||
// Pobranie produktu z cache
|
||
$product = \shop\Product::getFromCache($product_id, $lang_id, $permutation_hash);
|
||
|
||
// Czyszczenie cache produktu
|
||
\S::clear_product_cache($product_id);
|
||
|
||
// Czyszczenie całego cache
|
||
\S::clear_redis_cache();
|
||
```
|
||
|
||
## Refaktoryzacja do Domain-Driven Architecture
|
||
|
||
### Nowa struktura (w trakcie migracji)
|
||
```
|
||
autoload/
|
||
├── Domain/ # Nowa warstwa biznesowa (namespace \Domain\)
|
||
│ ├── Product/
|
||
│ │ └── ProductRepository.php # getQuantity, getPrice, getName, find, updateQuantity, archive, unarchive
|
||
│ ├── 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)
|
||
│ │ ├── ProductArchiveController.php # DI, instancyjny (list, unarchive)
|
||
│ │ └── UsersController.php # DI, instancyjny (view_list, user_edit, user_save, user_delete, login_form, twofa)
|
||
│ ├── 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
|
||
```
|
||
|
||
#### Aktualny stan migracji (uzupełnienie)
|
||
- Dodane repozytorium: `Domain\Dictionaries\DictionariesRepository`
|
||
- Dodane kontrolery DI: `admin\Controllers\DictionariesController`, `admin\Controllers\FilemanagerController`, `admin\Controllers\UsersController`
|
||
- Dodane repozytorium: `Domain\User\UserRepository`
|
||
- `Domain\Settings\SettingsRepository` działa bezpośrednio na DB (bez delegacji do `admin\factory\Settings`)
|
||
|
||
### 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
|
||
|
||
### Struktura
|
||
```
|
||
tests/
|
||
├── 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
|
||
│ └── ProductArchiveControllerTest.php # 6 testów
|
||
└── Integration/
|
||
```
|
||
Aktualnie w suite są też testy modułów `Dictionaries`, `Articles` i `Users` (repozytoria + kontrolery DI).
|
||
**Łącznie: 119 tests, 256 assertions**
|
||
|
||
## Ostatnie modyfikacje
|
||
|
||
### 2026-02-10: Porządki po migracji i release 0.252 (ver. 0.252)
|
||
- **UPDATE:** `ProductArchiveController` i szablony listy archiwum przepięte na nową tabelę (`components/table-list`)
|
||
- **UPDATE:** CSS/JS dla list wydzielone do osobnych widoków `*-custom-script.php` (banery i archiwum produktów)
|
||
- **UPDATE:** dodano `admin\Controllers\FilemanagerController` i przepięto filemanager na nowy routing
|
||
- **FIX:** naprawiono błąd `Invalid Key` w filemanagerze
|
||
- **CLEANUP:** usunięto legacy pliki: `autoload/admin/controls/class.Archive.php`, `autoload/admin/controls/class.Filemanager.php`, `autoload/admin/view/class.FileManager.php`, stare szablony `admin/templates/product_archive/*`
|
||
- **RENAME:** folder szablonów `admin/templates/product_archive/` → `admin/templates/product-archive/`
|
||
- Testy: 82 tests, 181 assertions
|
||
|
||
### 2026-02-09: Migracja Dictionaries (ver. 0.251)
|
||
- **NEW:** `Domain\Dictionaries\DictionariesRepository` (listForAdmin, find, save, delete, allUnits)
|
||
- **NEW:** `admin\Controllers\DictionariesController` (lista + formularz na nowych komponentach)
|
||
- **UPDATE:** migracja słowników na `components/table-list` i `components/form-edit`
|
||
- **FIX:** obsługa `lang_id` jako string (`pl`, `en`) w zapisie tłumaczeń
|
||
- **CLEANUP:** usunięto legacy klasy Dictionaries (`admin\controls`, `admin\factory`, `front\factory`)
|
||
- Testy: 82 tests, 181 assertions
|
||
|
||
### 2026-02-09: Refaktoryzacja Settings (ver. 0.250)
|
||
- **UPDATE:** `Domain\Settings\SettingsRepository` ma bezpośredni dostęp do DB (bez delegacji do `admin\factory\Settings`)
|
||
- **UPDATE:** przepięto użycia `admin\factory\Settings` na `Domain\Settings\SettingsRepository`
|
||
- **CLEANUP:** usunięto legacy klasy Settings (`factory`, `controls`, `view`)
|
||
- Testy: 82 tests, 181 assertions
|
||
|
||
### 2026-02-07: Usuniecie legacy kontrolera Articles (ver. 0.246)
|
||
- **UPDATE:** usunieto `autoload/admin/controls/class.Articles.php`
|
||
- **UPDATE:** `admin\Controllers\ArticlesController::galleryOrderSave()` uzywa `Domain\Article\ArticleRepository::saveGalleryOrder()`
|
||
- **UPDATE:** `Domain\Article\ArticleRepository` - dodano `saveGalleryOrder(int $articleId, string $order): bool`
|
||
- **UPDATE:** `admin\factory\Articles::gallery_order_save()` deleguje do `ArticleRepository::saveGalleryOrder()` (backward compatibility)
|
||
- **FIX:** sortowanie list admin po reloadzie - `RewriteRule` dla `/admin/...` ma `QSA`
|
||
- **FIX:** generator `\S::htacces()` komentuje dyrektywy `AddHandler|SetHandler|ForceType` (kompatybilnosc hostingu)
|
||
- **UPDATE:** zrodlo generatora `libraries/htaccess.conf` dostosowane do powyzszych zmian
|
||
- **WAZNE (deploy):** w paczce aktualizacji dodac `ver_X.XXX_files.txt` z wpisem:
|
||
`F: ../autoload/admin/controls/class.Articles.php`
|
||
- Testy: 65 tests, 131 assertions
|
||
|
||
### 2026-02-06: Migracja Articles::article_delete do DI (ver. 0.245)
|
||
- **UPDATE:** `Domain\Article\ArticleRepository` - dodano `archive()` (ustawia status = -1)
|
||
- **UPDATE:** `admin\Controllers\ArticlesController` - nowa akcja `delete()` z DI
|
||
- **UPDATE:** Router `admin\Site` - dodano `'article_delete' => 'delete'` do `$actionMap`
|
||
- **UPDATE:** `admin\factory\Articles::articles_set_archive()` deleguje do `ArticleRepository::archive()`
|
||
- **UPDATE:** `admin\controls\Articles::article_delete()` oznaczone `@deprecated`
|
||
- Testy: 59 tests, 123 assertions
|
||
|
||
### 2026-02-06: Migracja Articles::article_save do DI (ver. 0.244)
|
||
- **UPDATE:** `Domain\Article\ArticleRepository` - dodano `save()` + prywatne helpery (`buildArticleRow`, `buildLangRow`, `saveTranslations`, `savePages`, `assignTempFiles`, `assignTempImages`, `deleteMarkedFiles`, `deleteMarkedImages`, `maxPageOrder`)
|
||
- **UPDATE:** `admin\Controllers\ArticlesController` - nowa akcja `save()` z DI
|
||
- **UPDATE:** Router `admin\Site` - dodano `'article_save' => 'save'` do `$actionMap`
|
||
- **UPDATE:** `admin\factory\Articles::article_save()` deleguje do `ArticleRepository::save()` (backward compatibility)
|
||
- **UPDATE:** `admin\controls\Articles::article_save()` oznaczone `@deprecated`
|
||
- **UPDATE:** `tests/bootstrap.php` - dodano stub `S::seo()`
|
||
- Testy: 57 tests, 119 assertions
|
||
|
||
### 2026-02-06: Articles cleanup moved to repository (ver. 0.243)
|
||
- **UPDATE:** `Domain\Article\ArticleRepository` - added `deleteNonassignedImages()` and `deleteNonassignedFiles()`
|
||
- **UPDATE:** `admin\Controllers\ArticlesController::edit()` uses repository cleanup methods
|
||
- **UPDATE:** `admin\factory\Articles::delete_nonassigned_images()` and `delete_nonassigned_files()` delegate to repository (backward compatibility)
|
||
- Testy: 50 tests, 95 assertions
|
||
|
||
### 2026-02-06: Migracja Articles::article_edit do DI (ver. 0.242)
|
||
- **NOWE:** `Domain\Article\ArticleRepository` - repozytorium artykułów (`find()`)
|
||
- **UPDATE:** `admin\Controllers\ArticlesController` - konstruktor DI + `edit()` używa repozytorium
|
||
- **UPDATE:** Router `admin\Site` - factory dla `ArticlesController` z `ArticleRepository`
|
||
- **UPDATE:** `admin\factory\Articles::article_details()` deleguje do `Domain\Article\ArticleRepository`
|
||
- **UPDATE:** Stare kontrolery `admin\controls\Articles|Banners|Settings` - metody przejęte przez nowe kontrolery oznaczone `@deprecated`
|
||
- Testy: 48 testów, 91 asercji
|
||
|
||
### 2026-02-06: Migracja ProductArchive (ver. 0.241)
|
||
- **NOWE:** `admin\Controllers\ProductArchiveController` - kontroler archiwum produktów z DI
|
||
- **NOWE:** `ProductRepository::archive()`, `unarchive()` - operacje archiwizacji w repozytorium
|
||
- **RENAME:** `admin/templates/archive/` → `admin/templates/product_archive/`
|
||
- **FIX:** SQL w `ajax_products_list_archive()` - puste wyszukiwanie generowało `name|ean|sku LIKE '%%'` (NULL bitwise OR filtrował wyniki)
|
||
- **FIX:** Brakujący `archive = 1` w branchu bez wyszukiwania
|
||
- **CLEANUP:** Usunięto zbędny JS z szablonu archiwum (apilo, baselinker, duplikowanie, edycja cen)
|
||
- Stary kontroler `admin\controls\Archive` zachowany jako fallback
|
||
- Testy: 50 tests, 95 assertions (+10 nowych)
|
||
|
||
### 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`
|
||
- **NOWE:** Testy jednostkowe (5 testów, 100% pokrycie)
|
||
- Zmigrowano: `get_product_quantity()` → `ProductRepository::getQuantity()`
|
||
- Kompatybilność: Stara klasa `shop\Product` działa jako fasada
|
||
|
||
### 2025-02-05: System cache produktów (ver. 0.237)
|
||
- Automatyczne czyszczenie cache produktu po aktualizacji przez CRON
|
||
- AJAX dla przycisku "Wyczyść cache" w panelu admin
|
||
- Metody `delete()` i `deletePattern()` w CacheHandler
|
||
- Metoda `clear_product_cache()` w klasie S
|
||
|
||
---
|
||
*Dokument aktualizowany: 2026-02-12*
|
||
|
||
|
||
### 2026-02-12: Migracja Users (/admin/users) (ver. 0.253)
|
||
- **NOWE:** `Domain\User\UserRepository` - repozytorium uzytkownikow (CRUD, check_login, logon, details, 2FA)
|
||
- **NOWE:** `admin\Controllers\UsersController` - kontroler DI dla akcji `view_list`, `user_edit`, `user_save`, `user_delete`, `login_form`, `twofa`
|
||
- **UPDATE:** `admin\Site` - dodany factory wpis dla modulu `Users` w mapie nowych kontrolerow
|
||
- **UPDATE:** `admin\factory\Users` - fasada deleguje logike do `Domain\User\UserRepository`
|
||
- **UPDATE:** `admin/ajax/users.php` - `check_login` korzysta bezposrednio z `UserRepository`
|
||
- **CLEANUP:** usuniety `autoload/admin/controls/class.Users.php` (brak fallback - nowy kontroler obsluguje wszystkie akcje)
|
||
- Testy: 119 tests, 256 assertions
|
||
|
||
---
|
||
*Dokument aktualizowany: 2026-02-12*
|
||
- **UPDATE:** widoki Users przeniesione z `grid/gridEdit` na `components/table-list` i `components/form-edit`
|
||
|
||
## Aktualizacja 2026-02-12 (finalizacja Users)
|
||
- Modu<64> users dzia<69>a na `Domain\\User\\UserRepository` + `admin\\Controllers\\UsersController`.
|
||
- Usuni<6E>to legacy klasy: `autoload/admin/controls/class.Users.php`, `autoload/admin/factory/class.Users.php`, `autoload/admin/view/class.Users.php`.
|
||
- Walidacja: przy w<><77>czonym 2FA pole `twofa_email` jest wymagane.
|
||
- Widoki users przeniesione na `components/table-list` i `components/form-edit`.
|
||
- **NOWE:** `Domain\\Languages\\LanguagesRepository` - repozytorium jezykow i tlumaczen (lista, zapis, usuwanie, max_order)
|
||
- **NOWE:** `admin\\Controllers\\LanguagesController` - kontroler DI (`list/view_list`, `language_*`, `translation_*`)
|
||
- **UPDATE:** modul Languages przepiety z `grid/gridEdit` na `components/table-list` i `components/form-edit`
|
||
- **CLEANUP:** usuniete legacy klasy `autoload/admin/controls/class.Languages.php`, `autoload/admin/view/class.Languages.php`
|
||
- Testy: 130 tests, 301 assertions
|
||
|
||
## Aktualizacja 2026-02-12 (Languages final)
|
||
- Dodano `Domain\\Languages\\LanguagesRepository` oraz `admin\\Controllers\\LanguagesController`.
|
||
- Modul `/admin/languages/` (jezyki + tlumaczenia) dziala na nowym routingu DI.
|
||
- Widoki jezykow przepiete na `components/table-list` i `components/form-edit`.
|
||
- Usunieto legacy: `autoload/admin/controls/class.Languages.php`, `autoload/admin/view/class.Languages.php`.
|
||
|
||
## Aktualizacja 2026-02-12 (ver. 0.255)
|
||
- UPDATE: admin/Controllers/SettingsController, BannerController, DictionariesController, ArticlesController pobieraja listy jezykow przez Domain/Languages/LanguagesRepository (DI), bez zaleznosci od admin/factory/Languages.
|
||
- UPDATE: w admin/Site fabryki DI dla Articles, Banners, Settings, Dictionaries przekazuja rowniez LanguagesRepository.
|
||
- UPDATE: legacy admin/controls/* oraz admin/factory/Shop* przepiete z admin/factory/Languages::languages_list() na bezposrednie wywolania LanguagesRepository.
|
||
- FIX: autoload/admin/factory/class.Languages.php uzywa pelnego znacznika <?php (kompatybilnosc serwerow z short_open_tag=Off).
|
||
- Testy: 130 tests, 303 assertions
|
||
## Aktualizacja 2026-02-12 (ver. 0.256)
|
||
- NOWE: `Domain\\Layouts\\LayoutsRepository` (find/save/delete/listForAdmin, menusWithPages, categoriesTree).
|
||
- NOWE: `admin\\Controllers\\LayoutsController` (DI) dla akcji `list`, `layout_edit`, `layout_save`, `layout_delete`.
|
||
- UPDATE: `/admin/layouts/view_list/` przepiete z legacy `grid` na `components/table-list` (`PaginatedTableViewModel` + `TableListRequestFactory`).
|
||
- UPDATE: `admin/templates/layouts/layout-edit.php` korzysta z danych przekazywanych z repozytorium (bez wywolan `admin\\factory\\Pages` i `admin\\factory\\ShopCategory` w widoku).
|
||
- NOWE: `admin/templates/layouts/subcategories-list.php` (rekurencyjny partial bez zaleznosci od legacy factory).
|
||
- UPDATE: `Domain\\Languages\\LanguagesRepository` ma wspolna metode `defaultLanguageId()` wykorzystywana m.in. w `LayoutsController`.
|
||
- CLEANUP: usuniete legacy klasy `autoload/admin/controls/class.Layouts.php`, `autoload/admin/view/class.Layouts.php`; `admin/factory/class.Layouts.php` dziala jako fasada do `Domain\\Layouts\\LayoutsRepository`.
|
||
- UPDATE: `admin\\Controllers\\ArticlesController` pobiera layouty przez `Domain\\Layouts\\LayoutsRepository` (DI).
|
||
- Testy: 141 tests, 336 assertions
|
||
|
||
## Aktualizacja 2026-02-12 (ver. 0.257)
|
||
- NOWE: `Domain\\Newsletter\\NewsletterRepository` (subskrybenci, szablony, ustawienia, kolejka wysylki).
|
||
- NOWE: `Domain\\Newsletter\\NewsletterPreviewRenderer` (render podgladu newslettera).
|
||
- NOWE: `admin\\Controllers\\NewsletterController` (DI) dla akcji `emails_list`, `prepare`, `send`, `preview`, `settings*`, `email_template*`.
|
||
- UPDATE: `/admin/newsletter/*` przepiete z legacy `grid/gridEdit` na `components/table-list` i `components/form-edit`.
|
||
- UPDATE: nowy endpoint podgladu `/admin/newsletter/preview/` (bez `admin/ajax.php`).
|
||
- UPDATE: `admin\\Site` ma fabryke DI dla modulu `Newsletter`.
|
||
- UPDATE: `admin\\factory\\Newsletter` dziala jako fasada do `Domain\\Newsletter\\NewsletterRepository`.
|
||
- UPDATE: `front\\factory\\Newsletter` nie korzysta z `admin\\view\\Newsletter`.
|
||
- CLEANUP: usuniete legacy klasy `autoload/admin/controls/class.Newsletter.php`, `autoload/admin/view/class.Newsletter.php`.
|
||
- Testy: 150 tests, 372 assertions
|
||
|
||
## Aktualizacja 2026-02-12 (ver. 0.258)
|
||
- UPDATE: modul `/admin/newsletter/` - tymczasowo wylaczono akcje `prepare/send/preview` (Wysylka - przygotowanie).
|
||
- UPDATE: modul `/admin/newsletter/` - tymczasowo wylaczono liste `email_templates_user` (Szablony uzytkownika).
|
||
- UPDATE: lista i edycja szablonow newslettera w panelu ograniczona do szablonow administracyjnych (`is_admin = 1`).
|
||
- CLEANUP: usuniete nieuzywane widoki: `admin/templates/newsletter/prepare.php`, `admin/templates/newsletter/preview.php`, `admin/templates/newsletter/email-templates-user.php`.
|