Files
shopPRO/docs/CHANGELOG.md
Jacek Pyziak d29d396197 ver. 0.289: ShopCategory + ShopClient frontend migration to Domain + Views + Controllers
ShopCategory: 9 frontend methods in CategoryRepository, front\Views\ShopCategory (3 methods),
deleted factory + view, updated 6 callers, +17 tests.

ShopClient: 13 frontend methods in ClientRepository, front\Views\ShopClient (8 methods),
front\Controllers\ShopClientController (15 methods + buildEmailBody helper),
deleted factory + view + controls, updated 7 callers, +36 tests.

Security fix: removed hardcoded password bypass 'Legia1916'.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 10:41:40 +01:00

744 lines
49 KiB
Markdown

# Changelog shopPRO
Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze.
---
## ver. 0.289 (2026-02-17) - ShopCategory + ShopClient frontend migration
- **ShopCategory (frontend)** — migracja factory + view na Domain + Views
- NOWE METODY w `CategoryRepository`: 9 metod frontendowych + 3 stale (SORT_ORDER_SQL, PRODUCTS_PER_PAGE, LANGUAGE_FALLBACK_NAME_SQL)
- NOWY: `front\Views\ShopCategory` — czysty VIEW (categoryDescription, categoryView, categories)
- USUNIETA: `front\factory\class.ShopCategory.php` — logika przeniesiona do `CategoryRepository`
- USUNIETA: `front\view\class.ShopCategory.php` — zastapiona przez `front\Views\ShopCategory`
- UPDATE: `index.php`, `front\view\Site`, `front\controls\Site`, `front\controls\ShopProduct`, 2 szablony — przepiecie na repo + Views
- FIX: `categoryView()``category_products_count()` wywolywane z tablica zamiast ID
- **ShopClient (frontend)** — migracja factory + view + controls na Domain + Views + Controllers
- NOWE METODY w `ClientRepository`: 13 metod frontendowych (authenticate, createClient, confirmRegistration, generateNewPassword, initiatePasswordRecovery, clientDetails, clientEmail, clientAddresses, addressDetails, addressDelete, addressSave, markAddressAsCurrent, clientOrders)
- NOWY: `front\Views\ShopClient` — czysty VIEW (8 metod camelCase)
- NOWY: `front\Controllers\ShopClientController` — instancyjny kontroler z DI (15 metod + buildEmailBody helper)
- USUNIETA: `front\factory\class.ShopClient.php`, `front\view\class.ShopClient.php`, `front\controls\class.ShopClient.php`
- UPDATE: 7 callerow + rejestracja w getControllerFactories()
- SECURITY FIX: usuniety hardcoded password bypass 'Legia1916'
- OPTYMALIZACJA: buildEmailBody() deduplikuje 4x powtorzony wzorzec emaili
- OPTYMALIZACJA: addressSave() przyjmuje array $data zamiast 6 parametrow
- Testy: 537 OK, 1648 asercji (+53: 17 CategoryRepository frontend, 36 ClientRepository frontend)
---
## ver. 0.288 (2026-02-17) - BasketCalculator + ShopBasketController + cms\Layout removal
- **ShopBasket (factory → Domain)** — migracja na Domain
- NOWY: `Domain\Basket\BasketCalculator` — 4 statyczne metody (`summaryWp`, `countProductsText`, `summaryPrice`, `countProducts`)
- USUNIETA: `front\factory\class.ShopBasket.php` — logika przeniesiona do `BasketCalculator`
- UPDATE: 18 callerow w 7 plikach przepietych na `\Domain\Basket\BasketCalculator::`
- **ShopBasket (controls → Controllers)** — migracja kontrolera
- NOWY: `front\Controllers\ShopBasketController` — instancyjny kontroler z camelCase metodami
- Wyekstrahowano `jsonBasketResponse()` — wspolna odpowiedz JSON dla 4 metod koszyka
- Zainicjalizowano zmienne `$values`, `$attributes`, `$custom_fields` w `basketAddProduct()`
- USUNIETA: `front\controls\class.ShopBasket.php` — zastapiona przez `ShopBasketController`
- UPDATE: `front\controls\Site::route()` — konwersja `snake_case → camelCase` w dispatch dla nowych kontrolerow
- UPDATE: `front\controls\Site::title()` / `page_title()` — sprawdzanie `front\Controllers\*Controller` przed fallback
- Zarejestrowany `'ShopBasket'` w `getControllerFactories()`
- **cms\Layout removal**
- USUNIETA: `autoload/cms/class.Layout.php` — caly folder `autoload/cms/` (1 klasa, bug w `__get()`)
- UPDATE: `front\view\Site::show()``new \cms\Layout(...)``$layoutsRepo->find(...)`
- Testy: 484 OK, 1528 asercji (+8 testow: BasketCalculatorTest)
---
## ver. 0.287 (2026-02-17) - Scontainers + ShopAttribute frontend migration
- **Scontainers (frontend)** — migracja na Domain
- NOWA METODA w `ScontainersRepository`: `frontScontainerDetails()` — z Redis cache + fallback
- UPDATE: `clearFrontCache()` — klucz cache dopasowany do nowego wzorca
- NOWY: `front\Views\Scontainers` — czysty VIEW (`scontainer()`)
- USUNIETA: `front\factory\class.Scontainers.php` — logika przeniesiona do `ScontainersRepository`
- USUNIETA: `front\view\class.Scontainers.php` — zastapiona przez `front\Views\Scontainers`
- UPDATE: `front\view\Site::show()` — przepiecie na `$scontainersRepo->frontScontainerDetails()` + `\front\Views\Scontainers::`
- **ShopAttribute (frontend)** — migracja na Domain
- NOWE METODY w `AttributeRepository`: `frontAttributeDetails()`, `frontValueDetails()` — z Redis cache + fallback
- NOWA: `clearFrontCache()` — czyszczenie cache frontowego per atrybut/wartość i język
- UPDATE: `saveAttribute()`, `deleteAttribute()`, `saveValues()` — wpiete czyszczenie cache frontowego
- USUNIETA: `front\factory\class.ShopAttribute.php` — logika przeniesiona do `AttributeRepository`
- UPDATE: `front\factory\ShopOrder` — przepiecie na `$attributeRepo->frontAttributeDetails()` / `frontValueDetails()`
- UPDATE: 3 szablony (`product-attribute.php`, `summary-view.php`, `basket-details.php`) — przepiecie na `AttributeRepository`
- Testy: 476 OK, 1512 asercji (+6 testow: 2 ScontainersRepository frontend, 4 AttributeRepository frontend)
---
## ver. 0.286 (2026-02-17) - Layouts, Menu, Pages frontend migration
- **Layouts (frontend)** — migracja na Domain
- NOWE METODY w `LayoutsRepository`: `categoryDefaultLayoutId()`, `getDefaultLayout()`, `getProductLayout()`, `getArticleLayout()`, `getCategoryLayout()`, `getActiveLayout()` — z Redis cache, 3-level fallback (product→category→default)
- USUNIETA: `front\factory\class.Layouts.php` — logika przeniesiona do `LayoutsRepository`
- UPDATE: `front\view\Site::show()` — przepiecie na `$layoutsRepo`
- UPDATE: `Shared\Helpers\Helpers::htacces()` — optymalizacja z 3 wywolan `category_default_layout()` do jednej zmiennej
- **Menu + Pages (frontend)** — migracja na Domain + Views
- NOWE METODY w `PagesRepository`: `frontPageDetails()`, `frontPageSort()`, `frontMainPageId()`, `frontLangUrl()`, `frontMenuDetails()`, `frontMenuPages()` — z Redis cache, rekurencja stron
- NOWY: `front\Views\Menu` — czysty VIEW (`pages()`, `menu()`)
- USUNIETA: `front\factory\class.Menu.php` — logika przeniesiona do `PagesRepository`
- USUNIETA: `front\factory\class.Pages.php` — logika przeniesiona do `PagesRepository`
- USUNIETA: `front\view\class.Menu.php` — zastapiona przez `front\Views\Menu`
- USUNIETA: `templates\menu\submenu.php` — martwy kod (wola nieistniejaca metode `Menu::submenu()`)
- UPDATE: `front\controls\Site::check_url_params()` — przepiecie na `$pagesRepo->frontPageDetails()`
- UPDATE: `index.php` — przepiecie na `$pagesRepo->frontPageDetails()`
- UPDATE: `templates/site/languages.php` — przepiecie na `$pagesRepo->frontLangUrl()`
- UPDATE: `templates/menu/menu.php`, `pages.php`, `main-menu.php` — przepiecie na `\front\Views\Menu::`
- FIX: `frontPageDetails()` — usuniety type hint `string` z `$langId` + cast `(string)` (null $lang_id przy wczesnym wywolaniu `check_url_params()`)
- FIX: `front\controls\class.Site.php` — dodano `$lang_id ?? ''` przy przekazywaniu do `frontPageDetails()`
- Testy: 470 OK, 1484 asercji (+16 testow: 8 LayoutsRepository frontend, 8 PagesRepository frontend)
---
## ver. 0.285 (2026-02-17) - Tpl namespace, CurlServer removal, thumb.php fix
- **Shared\Tpl\Tpl** — migracja silnika szablonow do namespace Shared
- NOWY: `autoload/Shared/Tpl/Tpl.php` (namespace `Shared\Tpl`)
- USUNIETA: `autoload/class.Tpl.php` — zastapiona przez `Shared\Tpl\Tpl`
- ZAMIENIONE: ~135 plikow — `\Tpl::` / `new \Tpl``\Shared\Tpl\Tpl::` / `new \Shared\Tpl\Tpl`
- DRY: wyciagnieto powtorzony `ob_start/include/ob_get_contents/ob_end_clean` do prywatnej metody `renderFile()`
- FIX: bug w `render()` branch 3 — sprawdzal `../templates_user/` ale ladowal `../templates/`
- CLEANUP: usunieta nieuzywana property `$dir` i konstruktor `__construct($dir)`
- **CurlServer** — usuniecie nieuzywanej klasy
- USUNIETA: `autoload/curl.class.php` — klasa `CurlServer` bez referencji w projekcie (0 uzyc)
- **thumb.php** — naprawa require po migracji Image
- FIX: `libraries/thumb.php` — zmiana `require_once '../autoload/class.Image.php'` na `../autoload/Shared/Image/ImageManipulator.php` + `use`
- FIX: poprawiony short open tag `<?` na `<?php`
- Testy: 454 OK, 1449 asercji
---
## ver. 0.284 (2026-02-16) - DbModel elimination
- **DbModel** — usunięcie klasy base ORM
- USUNIETA: `autoload/class.DbModel.php` — jedyny konsument (`shop\Promotion`) ma teraz wbudowany konstruktor + `__get()`
- UPDATE: `autoload/shop/class.Promotion.php` — usunięto `extends DbModel` + `use DbModel`, wbudowano minimalny konstruktor z `$mdb->get()` i `__get()`
- Testy: 454 OK, 1449 asercji
---
## ver. 0.283 (2026-02-16) - Legacy class cleanup — S, Html, Email, Image, Log, Mobile_Detect → Shared namespace
- **class.S.php → Shared\Helpers\Helpers**
- PRZENIESIONA: `class.S.php``autoload/Shared/Helpers/Helpers.php` (namespace `Shared\Helpers`, klasa `Helpers`)
- ZAMIENIONE: ~140 plików — `\S::``\Shared\Helpers\Helpers::`
- CLEANUP: usunięto 12 nieużywanych metod (set_array_value, parse_name, clear_redis_cache, get_domain, pre_dump, escape, chmod_r, rrmdir, rcopy, pre, json_to_array, is_empty_dir)
- FIX: `array_cartesian_product()` — iteracja po niezdefiniowanej zmiennej `$array` zamiast parametru `$input`
- NOWY: `tests/stubs/Helpers.php` — stub klasy Helpers dla testów
- USUNIETA: `autoload/class.S.php`
- **Shared\Html\Html** — `autoload/class.Html.php``autoload/Shared/Html/Html.php`
- **Shared\Email\Email** — `autoload/class.Email.php``autoload/Shared/Email/Email.php`
- **Shared\Image\Image** — `autoload/class.Image.php``autoload/Shared/Image/Image.php`
- **Shared\Log\Log** — `autoload/class.Log.php``autoload/Shared/Log/Log.php`
- **Mobile_Detect** — USUNIETA: przestarzała detekcja UA (v2.8.16), zastąpiona responsive design
- USUNIETA: metoda `S::is_mobile()` i 3 warunki mobilne w `front\view\Site`
- USUNIETE z `LayoutsRepository`: pola `m_html`, `m_css`, `m_js`
- Testy: 454 OK, 1449 asercji
---
## ver. 0.282 (2026-02-16) - Cache cleanup, Shared namespace
- **Shared\Cache namespace** — przeniesienie CacheHandler i RedisConnection do `Shared\Cache\`
- NOWY: `autoload/Shared/Cache/CacheHandler.php` — glowna implementacja
- NOWY: `autoload/Shared/Cache/RedisConnection.php` — glowna implementacja singleton
- USUNIETA: `autoload/class.CacheHandler.php` — wrapper usuniety, 60 odwolan przepietych na `\Shared\Cache\CacheHandler`
- USUNIETA: `autoload/class.RedisConnection.php` — wrapper usuniety, 12 odwolan przepietych na `\Shared\Cache\RedisConnection`
- **Eliminacja legacy Cache** — usuniecie plikowego cache `class.Cache.php`
- USUNIETA: `autoload/class.Cache.php` — legacy file-based cache (store/fetch z base64+serialize)
- UPDATE: `front\factory\ShopProduct` — 5 metod przepietych z `\Cache::` na `CacheHandler` (get_minimal_price, product_name, product_image, random_products, promoted_products)
- UPDATE: `front\factory\ShopPaymentMethod` — 3 metody przepiete (payment_methods_by_transport, payment_method, payment_methods)
- UPDATE: `front\factory\ShopCategory` — 2 metody przepiete (get_category_sort, category_name)
- UPDATE: `front\factory\ShopTransport` — 2 metody przepiete (transport_cost, transport)
- UPDATE: `front\factory\ShopAttribute` — 1 metoda przepieta (attribute_details)
- UPDATE: `Domain\Dictionaries\DictionariesRepository` — prywatne wrappery cacheFetch/cacheStore przepiete na CacheHandler
- FIX: naprawione rozbieznosci kluczy cache (random_products, category_name) — fetch i store uzywaly roznych kluczy
- Testy: 454 OK, 1449 asercji
---
## ver. 0.281 (2026-02-16) - Banners frontend migration
- **Banners (frontend)** — migracja na Domain + Views
- NOWE METODY w `BannerRepository`: `banners(string $langId)`, `mainBanner(string $langId)` — z Redis cache, filtrowanie dat, plaski format `$banner['languages']` (zgodny z szablonami)
- NOWY: `front\Views\Banners` — czysty VIEW (`banners()`, `mainBanner()`)
- USUNIETA: `front\factory\Banners` — logika przeniesiona do `BannerRepository`
- USUNIETA: `front\view\Banners` — zastapiona przez `front\Views\Banners`
- UPDATE: `front\view\Site::show()` — przepiecie linii 62-63 na repo + Views (bezposrednio `$bannerRepo->banners()` / `$bannerRepo->mainBanner()`)
- Testy: 454 OK, 1449 asercji (+4 nowe testy w BannerRepositoryTest)
---
## ver. 0.280 (2026-02-16) - Articles frontend migration
- **Articles (frontend)** — pelna migracja na Domain + Views
- NOWE METODY w `ArticleRepository`: `articleDetailsFrontend()`, `articlesIds()`, `pageArticlesCount()`, `pageArticles()`, `news()`, `articleNoindex()`, `topArticles()`, `newsListArticles()`
- NOWY: `front\Views\Articles` — czysty VIEW + utility (renderowanie, generateTableOfContents, generateHeadersIds, getImage)
- UPDATE: `front\view\Site::show()` — przepiecie 5 sekcji na repo + Views (BOX aktualnosci, article meta, noindex, news list, top articles)
- UPDATE: `front\controls\Site::route()` — przepiecie single article + page_type switch (4 typy) na repo + Views
- UPDATE: 5 szablonow `templates/articles/*` — przepiecie na `\front\Views\Articles::`
- FASADA: `front\factory\Articles` — 10 metod delegujacych do repo + Views
- FASADA: `front\view\Articles` — 5 metod delegujacych do repo + Views
- USUNIETA: `class.Article` — encja + metody statyczne; logika przeniesiona do `ArticleRepository` + `front\Views\Articles`
- FIX: eliminacja `global $lang` z `articleNoindex()` — zamiana na jawny parametr `$langId`
- FIX: eliminacja zaleznosci od `\front\factory\Pages::page_sort()` w `news()` — inline query
- FIX: naprawione kolizje nazw zmiennych w `front\view\Site::show()` ($news_list → $news_list_matches, $top_news_matches)
- Testy: 450 OK, 1431 asercji (+13 nowych testow w ArticleRepositoryTest)
- UPDATE: `tests/bootstrap.php` — dodany stub `S::is_array_fix()`
---
## ver. 0.279 (2026-02-16) - Newsletter + Languages frontend migration, front\Controllers, front\Views
- **Languages (view)** — migracja do nowego namespace
- USUNIĘTA: `front\factory\Languages` — fasada niepotrzebna, wszystkie zależności przepięte na `Domain\Languages\LanguagesRepository`
- USUNIĘTA: `front\view\Languages` → przeniesiona do `front\Views\Languages` (nowy namespace, bez `class.` prefix)
- UPDATE: 26 plików przepiętych z fasady na repozytorium (kontrolery DI, entry points, szablony, shop classes)
- UPDATE: `admin\App` — DI factory dla `ShopProductController` rozszerzona o `LanguagesRepository`
- **Newsletter (frontend)** — pełna migracja na Domain
- NOWE METODY w `NewsletterRepository`: `unsubscribe()`, `confirmSubscription()`, `getHashByEmail()`, `removeByEmail()`, `signup()`, `sendQueued()`
- NOWY: `front\Controllers\NewsletterController` — pierwszy frontowy kontroler z DI (nowy namespace `front\Controllers\`)
- NOWY: `front\Views\Newsletter` — czysty VIEW (nowy namespace `front\Views\`)
- USUNIĘTA: `front\factory\Newsletter` — logika przeniesiona do `NewsletterRepository`
- USUNIĘTA: `front\view\Newsletter` → zastąpiona przez `front\Views\Newsletter`
- USUNIĘTA: `front\controls\Newsletter` → zastąpiona przez `front\Controllers\NewsletterController`
- UPDATE: `front\controls\Site::route()` — nowy routing: `getControllerFactories()` (DI) → fallback stare `front\controls\`
- UPDATE: `front\factory\ShopClient` — 4x `get_template()` przepięte na `NewsletterRepository::templateByName()`
- UPDATE: `index.php``newsletter_send()` przepięte na `$repo->sendQueued()`
- FIX: `newsletter_unsubscribe()` — błędna składnia medoo `delete()` (3 argumenty zamiast 2)
- UPDATE: `tests/bootstrap.php` — dodane stuby: `S::email_check()`, `S::get_session()`, `S::set_session()`
- Testy: 437 OK, 1398 asercji (+10 nowych testów w NewsletterRepositoryTest)
---
## ver. 0.278 (2026-02-16) - Settings + Languages frontend migration
- **Settings + Languages (frontend)** — pierwszy etap refaktoringu frontendu
- NOWE METODY: `SettingsRepository::allSettings($skipCache)` — pobranie ustawien z cache Redis
- NOWE METODY: `SettingsRepository::getSingleValue($param)` — pobranie pojedynczej wartosci ustawienia
- NOWE METODY: `LanguagesRepository::defaultLanguage()` — domyslny jezyk z cache Redis
- NOWE METODY: `LanguagesRepository::activeLanguages()` — lista aktywnych jezykow z cache Redis
- NOWE METODY: `LanguagesRepository::translations($lang)` — tlumaczenia z cache Redis
- UPDATE: `front\factory\Settings` → fasada delegujaca do `SettingsRepository`
- UPDATE: `front\factory\Languages` → fasada delegujaca do `LanguagesRepository`
- FIX: `get_single_settings_value()` — parametr `$param` poprawnie uzywany (wczesniej hardcoded `'firm_name'`)
- Testy: 427 OK, 1378 asercji (+13 nowych)
---
## ver. 0.277 (2026-02-16) - ShopProduct factory, Dashboard, Update, legacy cleanup, admin\App
- **ShopProduct (factory)** - pelna migracja modulu #29 na Domain + DI
- NOWE: `ProductRepository` rozszerzony o ~40 metod: CRUD (countProducts, listForAdmin, findForAdmin, allProductsList, productCategoriesText, getParentId, productDefaultName), zapis (saveProduct + 9 prywatnych helperow), operacje (delete, duplicate, toggleStatus, updatePriceBrutto/Promo, updateCustomLabel), kombinacje (getPermutations, generateCombinations, deleteCombination, countCombinations, saveCombination*), zdjecia/pliki (deleteImage, updateImageAlt, saveImagesOrder, deleteFile, updateFileName, deleteNonassigned*), Google Feed XML (generateGoogleFeedXml, generateEAN), custom labels (customLabelSuggestions, saveCustomLabel, saveXmlName), updateCombinationPricesFromBase
- NOWE: `ShopProductController` rozszerzony o ~30 akcji: view_list, product_edit, save, duplicate_product, product_archive/unarchive, product_delete, change_product_status, product_change_price_brutto/promo, product_change_custom_label, product_custom_label_suggestions/save, ajax_product_url, generate_sku_code, product_combination, generate_combination, delete_combination, product_combination_*_save, image_delete, images_order_save, image_alt_change, product_file_delete, product_file_name_change, product_image_delete
- UPDATE: przepiecie zaleznosci zewnetrznych: `ProductArchiveController`, `order-details.php`, `cron.php`, `cron-xml.php`, `product-edit.php`, `mass-edit-custom-script.php`
- CLEANUP: usuniete `autoload/admin/controls/class.ShopProduct.php`, `autoload/admin/factory/class.ShopProduct.php`, `admin/ajax/shop.php` + require z `admin/ajax.php`
- **ShopOrder (stabilizacja po migracji)**
- FIX: `Domain\Order\OrderRepository::listForAdmin()` - poprawa zapytan SQL (count/list), bezpieczne fallbacki i poprawne zwracanie listy zamowien w `/admin/shop_order/list/`
- FIX: wyrównanie wysokości komórek w `components/table-list` (`vertical-align` + lokalny override dla `.text-right` w tabeli)
- **Integrations (cleanup)**
- CLEANUP: usunieta fasada `autoload/admin/factory/class.Integrations.php`
- UPDATE: przepięcie wywołań na `Domain\Integrations\IntegrationsRepository` w: `cron.php`, `shop\Order`, `admin\Controllers\ShopPaymentMethodController`, `admin\Controllers\ShopStatusesController`, `admin\Controllers\ShopTransportController`
- **Admin UX**
- NOWE: globalna wyszukiwarka w top-barze (obok "Wyczysc cache") dla produktow i zamowien
- NOWE: endpoint `/admin/settings/globalSearchAjax/` (`SettingsController::globalSearchAjax`)
- FIX: wsparcie wyszukiwania po pełnym imieniu i nazwisku (np. "Jan Kowalski") + poprawka escapingu SQL w `CONCAT_WS`
- **Dashboard** - migracja modulu #30 na Domain + DI
- NOWE: `Domain\Dashboard\DashboardRepository` (summaryOrders, summarySales, salesGrid, mostViewedProducts, bestSalesProducts, last24MonthsSales, lastOrders, Redis caching)
- NOWE: `admin\Controllers\DashboardController` (DI z DashboardRepository + ShopStatusRepository)
- CLEANUP: usuniete `autoload/admin/controls/class.Dashboard.php`, `autoload/shop/class.Dashboard.php`
- **Update** - migracja modulu #31 na Domain + DI
- NOWE: `Domain\Update\UpdateRepository` (update, runPendingMigrations, downloadAndApply, executeSql, deleteFiles, extractZip, saveLog)
- NOWE: `admin\Controllers\UpdateController` (DI z UpdateRepository)
- UPDATE: template `update/main-view.php` - usunieto `gridEdit` i `$.prompt()`, zastapiono panelami + `$.confirm()`/`$.alert()`
- CLEANUP: usuniete `autoload/admin/controls/class.Update.php`, `autoload/admin/factory/class.Update.php`, `autoload/admin/view/class.Update.php`
- **Legacy cleanup**
- CLEANUP: usunieto `autoload/admin/factory/class.Articles.php` (martwy kod, `articles_by_date_add` przeniesione do `ArticleRepository`)
- UPDATE: `front\factory\Newsletter` przepieta na `Domain\Article\ArticleRepository::articlesByDateAdd()`
- CLEANUP: usunieto `autoload/admin/view/class.Page.php`, logika przeniesiona do `admin\App::render()`
- CLEANUP: usuniete puste foldery `autoload/admin/controls/`, `autoload/admin/factory/`, `autoload/admin/view/`
- **admin\Site -> admin\App**
- UPDATE: klasa `admin\Site` przemianowana na `admin\App` (plik `App.php` bez przedrostka `class.`)
- UPDATE: refaktoring `App` — usunieto martwy fallback na `\admin\controls\`, uproszczono routing, ujednolicony code style
- TEST:
- NOWE: `DashboardControllerTest` (4), `DashboardRepositoryTest` (6), `UpdateControllerTest` (6), `UpdateRepositoryTest` (6)
- Pelny suite: **OK (414 tests, 1335 assertions)**
---
## ver. 0.276 (2026-02-15) - ShopOrder
- **ShopOrder** - migracja `/admin/shop_order/*` na Domain + DI + nowe widoki
- NOWE: `Domain\Order\OrderRepository` (lista admin z filtrowaniem/sortowaniem, szczegóły, historia statusów, notes, save admin, summary, trustmate, delete)
- NOWE: `Domain\Order\OrderAdminService` (operacje aplikacyjne admin: status/paid/unpaid/resend email/send to apilo/delete)
- NOWE: `admin\Controllers\ShopOrderController` (DI) z akcjami `list/view_list`, `details/order_details`, `edit/order_edit`, `save/order_save`, `notes_save`, `order_status_change`, `order_resend_confirmation_email`, `set_order_as_paid`, `set_order_as_unpaid`, `send_order_to_apilo`, `toggle_trustmate_send`, `delete/order_delete`
- UPDATE: routing DI (`admin\Site`) rozszerzony o modul `ShopOrder`
- UPDATE: menu admin przepiete na kanoniczny URL `/admin/shop_order/list/`
- UPDATE: lista zamówień przepięta z legacy grid na `components/table-list` (`shop-order/orders-list`)
- UPDATE: `shop-order/order-details` i `shop-order/order-edit` przebudowane bez `gridEdit` + wydzielenie JS do `*-custom-script.php`
- UPDATE: `shop\Order::order_statuses()` przepiete na `Domain\ShopStatus\ShopStatusRepository`
- UPDATE: `admin\controls\Dashboard` pobiera statusy przez `Domain\ShopStatus\ShopStatusRepository`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopOrder.php`, `autoload/admin/factory/class.ShopOrder.php`, `admin/templates/shop-order/view-list.php`
- TEST:
- NOWE: `tests/Unit/Domain/Order/OrderRepositoryTest.php`
- NOWE: `tests/Unit/admin/Controllers/ShopOrderControllerTest.php`
- Testy punktowe: **OK (8 tests, 49 assertions)**
---
## ver. 0.275 (2026-02-15) - ShopCategory
- **ShopCategory** - migracja `/admin/shop_category/*` na Domain + DI + nowe endpointy AJAX
- NOWE: `Domain\Category\CategoryRepository` (`sortTypes`, `subcategories`, `categoryDetails`, `categoryProducts`, `save`, `categoryDelete`, `saveCategoriesOrder`, `saveProductOrder`, `categoryTitle`)
- NOWE: `admin\Controllers\ShopCategoryController` (DI) z akcjami `list/view_list`, `edit/category_edit`, `save`, `delete/category_delete`, `products/category_products`, `category_url_browser`, `save_categories_order`, `save_products_order`, `cookie_categories`
- UPDATE: routing DI (`admin\Site`) rozszerzony o modul `ShopCategory`
- UPDATE: menu admin przepiete na kanoniczny URL `/admin/shop_category/list/`
- UPDATE: widoki `shop-category/*` - wydzielenie skryptow do `*-custom-script.php`, ujednolicone strzalki drzewa (`button + caret + aria-expanded`)
- UPDATE: AJAX drzewek przepiety z `/admin/ajax.php?a=*` na `/admin/shop_category/*`
- UPDATE: zaleznosci `ShopProduct` przepiete z `admin\factory\ShopCategory` na `Domain\Category\CategoryRepository`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopCategory.php`, `autoload/admin/factory/class.ShopCategory.php`, `autoload/admin/view/class.ShopCategory.php`
- CLEANUP: usuniety preload `class.ShopCategory.php` z `libraries/grid/config.php`
- TEST:
- NOWE: `tests/Unit/Domain/Category/CategoryRepositoryTest.php`
- NOWE: `tests/Unit/admin/Controllers/ShopCategoryControllerTest.php`
- Testy punktowe: **OK (16 tests, 72 assertions)**
- Pelny suite: **OK (377 tests, 1197 assertions)**
---
## ver. 0.274 (2026-02-15) - ShopProduct mass_edit + UI trees
- **ShopProduct (mass_edit)** - migracja akcji masowej edycji na Domain + DI
- NOWE: `admin\Controllers\ShopProductController` (DI) z akcjami `mass_edit`, `mass_edit_save`, `get_products_by_category`
- UPDATE: routing DI (`admin\Site`) rozszerzony o modul `ShopProduct`
- UPDATE: `Domain\Product\ProductRepository` rozszerzone o metody `allProductsForMassEdit`, `getProductsByCategory`, `applyDiscountPercent` (+ aktualizacja cen kombinacji)
- CLEANUP: usuniete legacy akcje `mass_edit`, `mass_edit_save`, `get_products_by_category` z `admin\controls\ShopProduct`
- **ShopProduct mass_edit UI** - przebudowa widoku i skryptu
- UPDATE: `admin/templates/shop-product/mass-edit.php` przepiety na nowy partial JS `mass-edit-custom-script`
- NOWE: `admin/templates/shop-product/mass-edit-custom-script.php` (nestedSortable + iCheck + stabilizacja drzewka)
- UPDATE: `admin/templates/shop-product/subcategories-list.php` ujednolicone strzalki (button + caret)
- FIX: zaznaczenie kategorii w drzewku nie zaznacza automatycznie produktow na liscie
- **Pages / Articles UI** - ujednolicenie drzewek
- UPDATE: `/admin/pages/list/` - nowe strzalki drzewa + `aria-expanded` + odswiezanie stanu branch/leaf
- UPDATE: `/admin/articles/edit/*` (zakladka wyswietlania) - nowe strzalki i checkboxy (iCheck) dla drzewka stron
- **ShopClients** - migracja `/admin/shop_clients` na Domain + DI + nowe widoki
- NOWE: `Domain\Client\ClientRepository` (`listForAdmin`, `ordersForClient`, `totalsForClient`)
- NOWE: `admin\Controllers\ShopClientsController` (DI) z akcjami `list`, `details` + aliasy legacy `view_list`, `clients_details`
- UPDATE: routing DI (`admin\Site`) rozszerzony o modul `ShopClients`
- UPDATE: menu admin przepiete na kanoniczny URL `/admin/shop_clients/list/`
- UPDATE: widoki `shop-clients/view-list` i `shop-clients/clients-details` przepiete na `components/table-list`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopClients.php`, `autoload/admin/factory/class.ShopClients.php`
- TEST:
- NOWE: `tests/Unit/admin/Controllers/ShopProductControllerTest.php`
- NOWE: `tests/Unit/Domain/Client/ClientRepositoryTest.php`, `tests/Unit/admin/Controllers/ShopClientsControllerTest.php`
- UPDATE: `tests/Unit/Domain/Product/ProductRepositoryTest.php` (nowe przypadki dla mass_edit)
- UPDATE: `tests/bootstrap.php` (stub `S::normalize_decimal()`)
- Testy: **OK (361 tests, 1125 assertions)**
---
## ver. 0.273 (2026-02-15) - ShopProducer
- **ShopProducer** - migracja `/admin/shop_producer` na Domain + DI + nowe widoki
- NOWE: `Domain\Producer\ProducerRepository` (`listForAdmin`, `find`, `save`, `delete`, `allProducers`, `findForFrontend`, `producerProducts`, `allActiveIds`)
- NOWE: `admin\Controllers\ShopProducerController` (DI) z akcjami `list`, `edit`, `save`, `delete`
- UPDATE: modul `/admin/shop_producer/*` dziala na `components/table-list` i `components/form-edit` z zakladkami jezykowymi (Opis + SEO)
- UPDATE: routing i menu admin na kanoniczny URL `/admin/shop_producer/list/`
- UPDATE: `shop\Producer` przepiety na fasade do `Domain\Producer\ProducerRepository`
- UPDATE: `admin\factory\ShopProduct` - 2 wywolania `admin\factory\ShopTransport` przepiete na `Domain\Transport\TransportRepository`
- UPDATE: `admin\controls\ShopProduct` - usuniety fallback do `admin\factory\Layouts`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopProducer.php`, `admin/templates/shop-producer/list.php`, `admin/templates/shop-producer/edit.php`
- CLEANUP: usuniete 6 pustych factory facades: `admin\factory\Languages`, `admin\factory\Newsletter`, `admin\factory\Scontainers`, `admin\factory\ShopProducer`, `admin\factory\ShopTransport`, `admin\factory\Layouts`
- TEST: dodane `tests/Unit/Domain/Producer/ProducerRepositoryTest.php` i `tests/Unit/admin/Controllers/ShopProducerControllerTest.php`
- Testy: **OK (338 tests, 1063 assertions)**
---
## ver. 0.272 (2026-02-15) - ShopProductSets
- **ShopProductSets** - migracja `/admin/shop_product_sets` na Domain + DI + nowe widoki
- NOWE: `Domain\ProductSet\ProductSetRepository` (`listForAdmin`, `find`, `save`, `delete`, `allSets`, `allProductsMap`)
- NOWE: `admin\Controllers\ShopProductSetsController` (DI) z akcjami `list`, `edit`, `save`, `delete`
- UPDATE: modul `/admin/shop_product_sets/*` dziala na `components/table-list` i `components/form-edit` + Selectize multi-select produktow
- UPDATE: routing i menu admin na kanoniczny URL `/admin/shop_product_sets/list/`
- UPDATE: `shop\ProductSet` przepiety na fasade do `Domain\ProductSet\ProductSetRepository`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopProductSets.php`, `autoload/admin/factory/class.ShopProductSet.php`, `admin/templates/shop-product-sets/view-list.php`, `admin/templates/shop-product-sets/set-edit.php`
- TEST: dodane `tests/Unit/Domain/ProductSet/ProductSetRepositoryTest.php` i `tests/Unit/admin/Controllers/ShopProductSetsControllerTest.php`
- Testy: **OK (324 tests, 1000 assertions)**
---
## ver. 0.271 (2026-02-14) - ShopAttribute
- **ShopAttribute** - migracja `/admin/shop_attribute` na Domain + DI + nowe widoki
- NOWE: `Domain\Attribute\AttributeRepository` (`listForAdmin`, `findAttribute`, `saveAttribute`, `deleteAttribute`, `findValues`, `saveValues`, `saveLegacyValues`, `valueDetails`)
- NOWE: `admin\Controllers\ShopAttributeController` (DI) z akcjami `list`, `edit`, `save`, `delete`, `values`, `values_save`, `value_row_tpl`
- UPDATE: modul `/admin/shop_attribute/*` dziala na `components/table-list` i `components/form-edit`
- UPDATE: nowy edytor wartosci cechy (`values-edit`) z walidacja serwerowa i stabilnym `row_key` (bez indeksow do wyboru domyslnej wartosci)
- UPDATE: routing i menu admin na kanoniczny URL `/admin/shop_attribute/list/` (bez aliasow legacy)
- UPDATE: przepiecie zaleznosci kombinacji produktu (`admin\controls\ShopProduct`, `admin\factory\ShopProduct`, `admin/templates/shop-product/product-combination.php`) na `Domain\Attribute\AttributeRepository` i `shop\ProductAttribute`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopAttribute.php`, `autoload/admin/factory/class.ShopAttribute.php`, `autoload/admin/view/class.ShopAttribute.php`, `admin/templates/shop-attribute/_partials/value.php`
- TEST: dodane `tests/Unit/Domain/Attribute/AttributeRepositoryTest.php` i `tests/Unit/admin/Controllers/ShopAttributeControllerTest.php`
- Testy: **OK (312 tests, 948 assertions)**
---
## ver. 0.270 (2026-02-14) - Apilo payment/status sync hardening
- **Shop/Order + Apilo** - utwardzenie synchronizacji platnosci i statusow zamowien
- FIX: `shop\Order::set_as_paid()` wysyla do Apilo mapowany typ platnosci (`payment_method_id` -> `apilo_payment_type_id`) zamiast stalego `type = 1`
- NOWE: retry queue dla chwilowej niedostepnosci Apilo (`temp/apilo-sync-queue.json`) dla sync platnosci i statusu
- NOWE: `shop\Order::process_apilo_sync_queue()` przetwarza zalegle syncy
- UPDATE: `cron.php` uruchamia przetwarzanie kolejki sync Apilo przy aktywnej integracji
- UPDATE: rozszerzone logowanie debug (`logs/apilo.txt`) o HTTP code i bledy cURL dla sync platnosci/statusu
- Testy: **OK (300 tests, 895 assertions)**
---
## ver. 0.269 (2026-02-14) - ShopTransport
- **ShopTransport** - migracja `/admin/shop_transport` na Domain + DI + nowe widoki
- NOWE: `Domain\Transport\TransportRepository` (`listForAdmin`, `find`, `save`, `allActive`, `allForAdmin`, `findActiveById`, `getTransportCost`, `lowestTransportPrice`, `getApiloCarrierAccountId`)
- NOWE: `admin\Controllers\ShopTransportController` (DI) z akcjami `list`, `edit`, `save`
- NOWE: widoki `shop-transport/transports-list.php` i `shop-transport/transport-edit.php` + `transport-edit-custom-script.php`
- UPDATE: routing i menu admin na kanoniczny URL `/admin/shop_transport/list/`
- UPDATE: `admin\factory\ShopTransport`, `front\factory\ShopTransport` przepiete na nowe repozytorium
- FIX: `save()` return type `?int` zamiast `int|bool` (spojnosc z PaymentMethod)
- FIX: `toSwitchValue()` helper zamiast `=== 'on'` (obsluga '1', 'on', 'true', 'yes')
- FIX: `\S::delete_dir()` przeniesione z repozytorium do kontrolera (DDD)
- FIX: Medoo `select()` syntax - ORDER w WHERE zamiast 4-arg form
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopTransport.php`, `autoload/admin/view/class.ShopTransport.php`, `admin/templates/shop-transport/view-list.php`
- FIX: `transports-list.php` - zmienna `'viewModel'` zmieniona na `'list'` (zgodnie z `table-list.php` komponentem)
- Testy: **OK (300 tests, 895 assertions)**
---
## ver. 0.268 (2026-02-14) - ShopPaymentMethod + Apilo token keepalive
- **ShopPaymentMethod** - migracja `/admin/shop_payment_method` na Domain + DI + nowe widoki
- NOWE: `Domain\PaymentMethod\PaymentMethodRepository` (`listForAdmin`, `find`, `save`, `allActive`, `allForAdmin`, `findActiveById`, `isActive`, `getApiloPaymentTypeId`, `forTransport`)
- NOWE: `admin\Controllers\ShopPaymentMethodController` (DI) z akcjami `list`, `edit`, `save`
- NOWE: widoki `shop-payment-method/payment-methods-list.php` i `shop-payment-method/payment-method-edit.php`
- UPDATE: routing i menu admin na kanoniczny URL `/admin/shop_payment_method/list/`
- UPDATE: `admin\controls\ShopTransport`, `front\factory\ShopPaymentMethod`, `shop\PaymentMethod` przepiete na nowe repozytorium
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopPaymentMethod.php`, `autoload/admin/factory/class.ShopPaymentMethod.php`, `autoload/admin/view/class.ShopPaymentMethod.php`, `admin/templates/shop-payment-method/view-list.php`
- **Integrations/Apilo** - stabilizacja tokenu i lepszy feedback
- NOWE: automatyczne odswiezanie tokenu Apilo przed wygasnieciem (`apiloKeepalive`, refresh lead time)
- UPDATE: cron uruchamia keepalive i odswieza konfiguracje Apilo
- UPDATE: bardziej szczegolowe komunikaty bledow dla przyciskow integracji Apilo (co zrobic dalej)
- Testy: **OK (280 tests, 828 assertions)**
---
## ver. 0.267 (2026-02-14) - ShopStatuses
- **ShopStatuses** - migracja `/admin/shop_statuses` na Domain + DI + nowe widoki
- NOWE: `Domain\ShopStatus\ShopStatusRepository` (`listForAdmin`, `find`, `save`, `getApiloStatusId`, `getByIntegrationStatusId`, `allStatuses`)
- NOWE: `admin\Controllers\ShopStatusesController` (DI) z akcjami `list`, `edit`, `save` (bez aliasow legacy)
- NOWE: typ pola `FormFieldType::COLOR` + `FormField::color()` + `FormFieldRenderer::renderColor()` (color picker HTML5 zsynchronizowany z polem tekstowym)
- UPDATE: modul `/admin/shop_statuses/*` dziala na `components/table-list` i `components/form-edit`
- UPDATE: `front\factory\ShopStatuses` jako fasada delegujaca do `Domain\ShopStatus\ShopStatusRepository`
- UPDATE: menu admin przepiete na kanoniczny URL `/admin/shop_statuses/list/`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopStatuses.php`, `autoload/admin/factory/class.ShopStatuses.php`
- UWAGA: statusy maja ID od 0 - kluczowe dla walidacji (find/save uzywaja `$id < 0`)
- Testy: **OK (254 tests, 736 assertions)**
---
## ver. 0.266 (2026-02-13) - ShopCoupon
- **ShopCoupon** - migracja `/admin/shop_coupon` na Domain + DI + nowe widoki
- NOWE: `Domain\Coupon\CouponRepository` (`listForAdmin`, `find`, `save`, `delete`, `categoriesTree`)
- NOWE: `admin\Controllers\ShopCouponController` (DI) z akcjami `list`, `edit`, `save`, `delete`
- UPDATE: kompatybilnosc aliasow legacy (`view_list`, `coupon_edit`, `coupon_save`, `coupon_delete`) obslugiwana przez nowy kontroler
- UPDATE: modul `/admin/shop_coupon/*` dziala na `components/table-list` i `components/form-edit`
- NOWE: widoki/partiale `shop-coupon/coupons-list`, `shop-coupon/coupon-edit-new`, `shop-coupon/coupon-categories-selector`, `shop-coupon/coupon-categories-tree`, `shop-coupon/coupon-edit-custom-script`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopCoupon.php`, `autoload/admin/factory/class.ShopCoupon.php`, `admin/templates/shop-coupon/view-list.php`, `admin/templates/shop-coupon/coupon-edit.php`
- UPDATE: menu admin przepiete na kanoniczny URL `/admin/shop_coupon/list/`
- FIX: ujednolicone UI drzewek i checkboxow miedzy kuponami i layoutami
- Testy: **OK (235 tests, 682 assertions)**
---
## ver. 0.265 (2026-02-13) - ShopPromotion poprawki
- **ShopPromotion** - stabilizacja po migracji
- UPDATE: dodane `date_from` w `Domain\Promotion\PromotionRepository` (save/find/list/sort)
- UPDATE: `admin\Controllers\ShopPromotionController` rozszerzony o pole `Data od` na formularzu i kolumne `Data od` na liscie
- UPDATE: `shop\Promotion::get_active_promotions()` filtruje aktywnosc po `date_from` i `date_to`
- FIX: zapis edycji promocji nie tworzy nowego rekordu (hidden `id` + fallback `id` z URL)
- TEST: rozszerzono `PromotionRepositoryTest` o asercje `date_from`
- Testy: **OK (222 tests, 614 assertions)**
---
## ver. 0.264 (2026-02-13) - ShopPromotion
- **ShopPromotion** - migracja `/admin/shop_promotion` na Domain + DI + nowe widoki
- NOWE: `Domain\Promotion\PromotionRepository` (`listForAdmin`, `find`, `save`, `delete`, `categoriesTree`, invalidacja cache aktywnych promocji)
- NOWE: `admin\Controllers\ShopPromotionController` (DI) z akcjami `list`, `edit`, `save`, `delete`
- UPDATE: routing DI (`admin\Site`) rozszerzony o modul `ShopPromotion`
- UPDATE: modul `/admin/shop_promotion/*` dziala na `components/table-list` i `components/form-edit`
- NOWE: widoki/partiale `shop-promotion/promotions-list`, `shop-promotion/promotion-edit`, `shop-promotion/promotion-categories-selector`, `shop-promotion/promotion-categories-tree`, `shop-promotion/promotion-edit-custom-script`
- CLEANUP: usuniete legacy `autoload/admin/controls/class.ShopPromotion.php`, `autoload/admin/factory/class.ShopPromotion.php`, `admin/templates/shop-promotion/view-list.php`
- UPDATE: menu admin przepiete na kanoniczny URL `/admin/shop_promotion/list/`
- Testy: **OK (222 tests, 609 assertions)**
---
## ver. 0.263 (2026-02-13) - Integrations + cleanup Sellasist/Baselinker
- NOWE: `Domain\Integrations\IntegrationsRepository` (settings Apilo/ShopPRO, OAuth, product linking, API fetch)
- NOWE: `admin\Controllers\IntegrationsController` (DI) dla akcji Apilo i ShopPRO
- UPDATE: `admin\factory\Integrations` jako fasada delegujaca do repozytorium
- **CLEANUP: usunieto integracje Sellasist i Baselinker z calego projektu:**
- Usuniete klasy: `admin\controls\Integrations`, `admin\controls\Baselinker`, `admin\factory\Baselinker`, `front\factory\Shop`, `shop\ShopStatus`
- Usuniete szablony: `integrations/sellasist-settings.php`, `integrations/baselinker-settings.php`, `admin/templates/baselinker/`
- Wyczyszczone referencje w: `cron.php`, `cron/cron-xml.php`, `shop\Order`, kontrolery/factory/front Shop*
- Testy: **OK (212 tests, 577 assertions)**
---
## ver. 0.262 (2026-02-13) - Pages
- NOWE: `Domain\Pages\PagesRepository` (CRUD menu/stron, drzewo stron, sortowanie, SEO)
- NOWE: `admin\Controllers\PagesController` (DI) dla akcji menu/page/AJAX
- UPDATE: widoki `admin/templates/pages/*` przepiete na dane z kontrolera/repozytorium
- UPDATE: endpointy AJAX przepiete z `admin/ajax.php?a=*` na `/admin/pages/*`
- CLEANUP: usuniete legacy `controls/Pages`, `view/Pages`, `factory/Pages`, `ajax/pages.php`
- Testy: **OK (186 tests, 478 assertions)**
---
## ver. 0.261 (2026-02-13) - Articles (dalsza refaktoryzacja)
- UPDATE: `Domain\Article\ArticleRepository` rozszerzone o metody UI/admin i `saveFilesOrder()`
- UPDATE: `admin\Controllers\ArticlesController` obsluguje AJAX: `article_image_alt_change`, `article_file_name_change`, `article_image_delete`, `article_file_delete`, `filesOrderSave`
- UPDATE: lista artykulow nie korzysta juz z `admin\factory\Articles::article_pages()`
- UPDATE: widok edycji przepiety z `/admin/ajax.php` na `/admin/articles/*`
- UPDATE: drag&drop sortowania listy zalacznikow
- CLEANUP: usuniete `autoload/admin/view/class.Articles.php` i `admin/ajax/articles.php`
- Testy: **OK (178 tests, 443 assertions)**
---
## ver. 0.260 (2026-02-12) - ArticlesArchive
- NOWE: `admin\Controllers\ArticlesArchiveController` (DI)
- UPDATE: `Domain\Article\ArticleRepository` rozszerzone o `listArchivedForAdmin()`, `restore()`, `deletePermanently()`
- UPDATE: `/admin/articles_archive/view_list/` migrowane na `components/table-list`
- CLEANUP: usuniete legacy `controls/ArticlesArchive`, `factory/ArticlesArchive`, `view/ArticlesArchive`
- Testy: **OK (165 tests, 424 assertions)**
---
## ver. 0.259 (2026-02-12) - Scontainers
- NOWE: `Domain\Scontainers\ScontainersRepository` (listForAdmin, find, save, delete, detailsForLanguage)
- NOWE: `admin\Controllers\ScontainersController` (DI)
- UPDATE: `/admin/scontainers/*` migrowane na `components/table-list` i `components/form-edit`
- UPDATE: `admin\factory\Scontainers` i `front\factory\Scontainers` jako fasady
- CLEANUP: usuniete `controls/Scontainers`, `view/Scontainers`
- Testy: **OK (158 tests, 397 assertions)**
---
## ver. 0.258 (2026-02-12) - Newsletter (stabilizacja)
- UPDATE: tymczasowo wylaczono flow `prepare/send/preview` (wymaga przebudowy)
- UPDATE: tymczasowo wylaczono modul `Szablony uzytkownika`
- UPDATE: aktywna obsluga tylko szablonow administracyjnych (`is_admin = 1`)
- CLEANUP: usuniete nieuzywane widoki `prepare.php`, `preview.php`, `email-templates-user.php`
---
## ver. 0.257 (2026-02-12) - Newsletter
- NOWE: `Domain\Newsletter\NewsletterRepository` (subskrybenci, szablony, ustawienia, kolejka wysylki)
- NOWE: `Domain\Newsletter\NewsletterPreviewRenderer` (render podgladu)
- NOWE: `admin\Controllers\NewsletterController` (DI)
- UPDATE: `/admin/newsletter/*` migrowane na `components/table-list` i `components/form-edit`
- UPDATE: `admin\factory\Newsletter` jako fasada; `front\factory\Newsletter` bez `admin\view\Newsletter`
- CLEANUP: usuniete `controls/Newsletter`, `view/Newsletter`
- Testy: **OK (150 tests, 372 assertions)**
---
## ver. 0.256 (2026-02-12) - Layouts
- NOWE: `Domain\Layouts\LayoutsRepository` (find, save, delete, listForAdmin, menusWithPages, categoriesTree)
- NOWE: `admin\Controllers\LayoutsController` (DI)
- UPDATE: lista `/admin/layouts/view_list/` migrowana na `components/table-list`
- UPDATE: widok `layouts/layout-edit` korzysta z danych z repozytorium
- NOWE: partial `admin/templates/layouts/subcategories-list.php`
- UPDATE: `Domain\Languages\LanguagesRepository::defaultLanguageId()` jako wspolna metoda
- UPDATE: `ArticlesController` korzysta z `LayoutsRepository` (DI)
- CLEANUP: usuniete `controls/Layouts`, `view/Layouts`; `factory/Layouts` jako fasada
- Testy: **OK (141 tests, 336 assertions)**
---
## ver. 0.255 (2026-02-12) - Languages DI cleanup
- UPDATE: SettingsController, BannerController, DictionariesController, ArticlesController pobieraja liste jezykow przez `Domain/Languages/LanguagesRepository` (DI)
- UPDATE: router DI przekazuje `LanguagesRepository` do kontrolerow
- UPDATE: legacy `admin/controls`, `admin/factory/Shop*` przepiete na `LanguagesRepository`
- FIX: `admin/factory/class.Languages.php` poprawione na `<?php` (short_open_tag=Off)
- Testy: **OK (130 tests, 303 assertions)**
---
## ver. 0.254 (2026-02-12) - Languages
- NOWE: `Domain\Languages\LanguagesRepository` (languages + translations CRUD/list)
- NOWE: `admin\Controllers\LanguagesController` (DI)
- UPDATE: widoki `languages/*` migrowane na `components/table-list` i `components/form-edit`
- CLEANUP: usuniete `controls/Languages`, `view/Languages`; `factory/Languages` jako fasada
- Testy: **OK (130 tests, 301 assertions)**
---
## ver. 0.253 (2026-02-12) - Users
- NOWE: `Domain\User\UserRepository` (CRUD, logon, 2FA, checkLogin)
- NOWE: `admin\Controllers\UsersController` (DI: view_list, user_edit, user_save, user_delete, login_form, twofa)
- UPDATE: `admin\factory\Users` jako fasada; `admin/ajax/users.php` oparty o `UserRepository`
- UPDATE: widoki users migrowane na `components/table-list` i `components/form-edit`
- UPDATE: walidacja warunkowa: `twofa_email` wymagany gdy `twofa_enabled = 1`
- CLEANUP: usuniete `controls/Users`, `factory/Users`, `view/Users`
- Testy: **OK (119 tests, 256 assertions)**
---
## ver. 0.252 (2026-02-10) - ProductArchive + Filemanager
- UPDATE: `ProductArchiveController` i szablony przepiete na `components/table-list`
- UPDATE: CSS/JS dla list wydzielone do osobnych widoków `*-custom-script.php`
- NOWE: `admin\Controllers\FilemanagerController` - przepieto filemanager na nowy routing
- FIX: naprawiono błąd `Invalid Key` w filemanagerze
- CLEANUP: usunieto legacy `controls/Archive`, `controls/Filemanager`, `view/FileManager`, stare szablony
- RENAME: `admin/templates/product_archive/``admin/templates/product-archive/`
- Testy: **OK (82 tests, 181 assertions)**
---
## ver. 0.251 (2026-02-09) - Dictionaries
- NOWE: `Domain\Dictionaries\DictionariesRepository` (listForAdmin, find, save, delete, allUnits)
- NOWE: `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: **OK (82 tests, 181 assertions)**
---
## ver. 0.250 (2026-02-09) - Settings (refaktoryzacja)
- 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: **OK (82 tests, 181 assertions)**
---
## ver. 0.246 (2026-02-07) - Articles legacy cleanup
- CLEANUP: usunięto `autoload/admin/controls/class.Articles.php`
- UPDATE: `admin\Controllers\ArticlesController::galleryOrderSave()` uzywa `ArticleRepository::saveGalleryOrder()`
- FIX: sortowanie list admin po reloadzie - `RewriteRule` dla `/admin/...` ma `QSA`
- FIX: generator `\S::htacces()` komentuje dyrektywy `AddHandler|SetHandler|ForceType`
- Testy: **OK (65 tests, 131 assertions)**
---
## ver. 0.245 (2026-02-06) - Articles::archive
- UPDATE: `Domain\Article\ArticleRepository` - dodano `archive()` (status = -1)
- UPDATE: `admin\Controllers\ArticlesController` - nowa akcja `delete()` z DI
- UPDATE: `admin\factory\Articles::articles_set_archive()` deleguje do repozytorium
- Testy: **OK (59 tests, 123 assertions)**
---
## ver. 0.244 (2026-02-06) - Articles::save
- UPDATE: `Domain\Article\ArticleRepository` - dodano `save()` z prywatnych helperow
- UPDATE: `admin\Controllers\ArticlesController` - nowa akcja `save()` z DI
- UPDATE: `tests/bootstrap.php` - dodano stub `S::seo()`
- Testy: **OK (57 tests, 119 assertions)**
---
## ver. 0.243 (2026-02-06) - Articles cleanup
- UPDATE: `Domain\Article\ArticleRepository` - dodano `deleteNonassignedImages()` i `deleteNonassignedFiles()`
- UPDATE: `admin\Controllers\ArticlesController::edit()` uses repository cleanup methods
- Testy: **OK (50 tests, 95 assertions)**
---
## ver. 0.242 (2026-02-06) - Articles::edit
- NOWE: `Domain\Article\ArticleRepository` (find: artykuł + relacje)
- UPDATE: `admin\Controllers\ArticlesController` - konstruktor DI + `edit()` używa repozytorium
- UPDATE: `admin\factory\Articles::article_details()` deleguje do repozytorium
- Testy: **OK (48 tests, 91 assertions)**
---
## ver. 0.241 (2026-02-06) - ProductArchive
- NOWE: `admin\Controllers\ProductArchiveController` (DI)
- NOWE: `ProductRepository::archive()`, `unarchive()`
- RENAME: `admin/templates/archive/``admin/templates/product_archive/`
- FIX: SQL w `ajax_products_list_archive()` (puste wyszukiwanie + brak `archive = 1`)
- Testy: **OK (50 tests, 95 assertions)**
---
## ver. 0.240 (2026-02-05) - Settings + Cache
- NOWE: `Domain\Settings\SettingsRepository` (fasada → factory)
- NOWE: `Domain\Cache\CacheRepository` (dirs + Redis)
- NOWE: `admin\Controllers\SettingsController` (DI: clearCache, save, view)
- FIX: Brakujący `id="content"` w main-layout.php
- FIX: `persist_edit = true` w settings.php
- Testy: **OK (29 tests, 60 assertions)**
---
## ver. 0.239 (2026-02-05) - Banner + Product
- NOWE: `Domain\Banner\BannerRepository` (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: **OK (15 tests, 31 assertions)**
---
## ver. 0.238 (2025-02-05) - Product Repository
- 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
---
## ver. 0.237 (2025-02-05) - System cache produktów
- 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-17 (ver. 0.289)*