refactor(shop-statuses): migrate to DI, restructure docs into docs/ folder (0.268)
- Migrate ShopStatuses module to Domain + DI architecture - Add ShopStatusRepository, ShopStatusesController with color picker - Convert front\factory\ShopStatuses to facade - Add FormFieldType::COLOR with HTML5 color picker - Move documentation files to docs/ folder (PROJECT_STRUCTURE, REFACTORING_PLAN, CHANGELOG, FORM_EDIT_SYSTEM, TESTING, DATABASE_STRUCTURE) - Tests: 254 tests, 736 assertions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
315
docs/CHANGELOG.md
Normal file
315
docs/CHANGELOG.md
Normal file
@@ -0,0 +1,315 @@
|
||||
# Changelog shopPRO
|
||||
|
||||
Logi zmian z migracji na Domain-Driven Architecture. Najnowsze na gorze.
|
||||
|
||||
---
|
||||
|
||||
## 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-14*
|
||||
410
docs/DATABASE_STRUCTURE.md
Normal file
410
docs/DATABASE_STRUCTURE.md
Normal file
@@ -0,0 +1,410 @@
|
||||
# Struktura bazy danych shopPRO
|
||||
|
||||
Plik aktualizowany na bieżąco przy zmianach w kodzie.
|
||||
ORM: Medoo (`$mdb`), prefix tabel: `pp_`
|
||||
|
||||
## pp_shop_products
|
||||
Główna tabela produktów.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| parent_id | FK do produktu nadrzędnego (kombinacje) - NULL dla produktów głównych |
|
||||
| price_brutto | Cena brutto |
|
||||
| price_brutto_promo | Cena promocyjna brutto |
|
||||
| quantity | Stan magazynowy |
|
||||
| status | Status: 1 = aktywny, 0 = nieaktywny |
|
||||
| archive | Archiwum: 1 = zarchiwizowany, 0 = aktywny |
|
||||
| promoted | Czy promowany |
|
||||
| vat | Stawka VAT |
|
||||
| ean | Kod EAN |
|
||||
| sku | Kod SKU |
|
||||
| apilo_product_id | ID produktu w Apilo |
|
||||
| apilo_product_name | Nazwa produktu w Apilo |
|
||||
|
||||
**Używane w:** `Domain\Product\ProductRepository`, `admin\factory\ShopProduct`
|
||||
|
||||
## pp_shop_products_langs
|
||||
Tłumaczenia produktów (per język).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| product_id | FK do pp_shop_products |
|
||||
| lang_id | ID języka (np. 'pl') |
|
||||
| name | Nazwa produktu |
|
||||
|
||||
**Używane w:** `Domain\Product\ProductRepository::getName()`
|
||||
|
||||
## pp_shop_products_images
|
||||
Zdjęcia produktów.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| product_id | FK do pp_shop_products |
|
||||
| src | Ścieżka do pliku |
|
||||
| alt | Tekst alternatywny |
|
||||
|
||||
## pp_shop_products_categories
|
||||
Przypisanie produktów do kategorii.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| product_id | FK do pp_shop_products |
|
||||
|
||||
**Używane w:** `admin\factory\ShopProduct::product_delete()`
|
||||
|
||||
## pp_banners
|
||||
Banery.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| name | Nazwa banera |
|
||||
| status | 0/1 |
|
||||
| date_start | Data rozpoczęcia |
|
||||
| date_end | Data zakończenia |
|
||||
| home_page | Czy na stronie głównej 0/1 |
|
||||
|
||||
**Używane w:** `Domain\Banner\BannerRepository`
|
||||
|
||||
## pp_banners_langs
|
||||
Tłumaczenia banerów.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| id_banner | FK do pp_banners |
|
||||
| id_lang | ID języka |
|
||||
| src | Ścieżka do grafiki |
|
||||
| url | URL docelowy |
|
||||
| html | Kod HTML |
|
||||
| text | Tekst |
|
||||
|
||||
**Używane w:** `Domain\Banner\BannerRepository`
|
||||
|
||||
## pp_articles
|
||||
Artykuły.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| status | -1 = archiwum, 0 = nieaktywny, 1 = aktywny |
|
||||
|
||||
**Używane w:** `admin\Controllers\ArticlesArchiveController`, `Domain\Article\ArticleRepository::find()`, `Domain\Article\ArticleRepository::listArchivedForAdmin()`
|
||||
|
||||
## pp_articles_pages
|
||||
Strony artykułów.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| article_id | FK do pp_articles |
|
||||
| page_id | FK do strony (pp_pages) |
|
||||
| o | Kolejność |
|
||||
|
||||
**Używane w:** `Domain\Article\ArticleRepository::find()`, `Domain\Article\ArticleRepository::deleteNonassignedImages()`
|
||||
|
||||
## pp_articles_langs
|
||||
Tłumaczenia artykułów.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| article_id | FK do pp_articles |
|
||||
| lang_id | ID języka (np. 'pl') |
|
||||
| title | Tytuł artykułu |
|
||||
| seo_link | Link SEO artykułu |
|
||||
|
||||
**Używane w:** `Domain\Article\ArticleRepository::find()`, `Domain\Article\ArticleRepository::deleteNonassignedFiles()`
|
||||
|
||||
## pp_articles_images
|
||||
Zdjęcia artykułów.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| article_id | FK do pp_articles |
|
||||
| src | Ścieżka do pliku |
|
||||
| o | Kolejność |
|
||||
| id | PK (używane też do sortowania DESC) |
|
||||
|
||||
**Używane w:** `Domain\Article\ArticleRepository::find()`
|
||||
|
||||
## pp_articles_files
|
||||
Pliki artykułów.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| article_id | FK do pp_articles |
|
||||
| src | Ścieżka do pliku |
|
||||
| name | Nazwa wyświetlana załącznika (opcjonalna) |
|
||||
| to_delete | Flaga miękkiego usuwania (0/1) |
|
||||
| o | Kolejność załączników (używana przez sortowanie drag&drop w adminie) |
|
||||
|
||||
**Używane w:** `Domain\Article\ArticleRepository::find()`, `Domain\Article\ArticleRepository::saveFilesOrder()`
|
||||
|
||||
## pp_units
|
||||
Jednostki/slowniki (np. jednostki produktu).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
|
||||
**Używane w:** `Domain\Dictionaries\DictionariesRepository`, `admin\controls\ShopProduct`
|
||||
|
||||
## pp_units_langs
|
||||
Tlumaczenia jednostek (per jezyk).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| unit_id | FK do pp_units |
|
||||
| lang_id | ID jezyka (np. 'pl') |
|
||||
| text | Nazwa jednostki |
|
||||
|
||||
**Używane w:** `Domain\Dictionaries\DictionariesRepository`
|
||||
|
||||
## pp_users
|
||||
Uzytkownicy panelu administratora.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| login | Login / e-mail uzytkownika |
|
||||
| password | Hash hasla (legacy: md5) |
|
||||
| status | Status konta: 1 = aktywny, 0 = zablokowany |
|
||||
| admin | Flaga dostepu do panelu admin |
|
||||
| error_logged_count | Licznik nieudanych logowan |
|
||||
| last_logged | Data ostatniego poprawnego logowania |
|
||||
| last_error_logged | Data ostatniej nieudanej proby logowania |
|
||||
| twofa_enabled | Czy wlaczone 2FA (0/1) |
|
||||
| twofa_email | E-mail do wysylki kodu 2FA |
|
||||
| twofa_code_hash | Hash aktualnego kodu 2FA |
|
||||
| twofa_expires_at | Data waznosci kodu 2FA |
|
||||
| twofa_sent_at | Data ostatniej wysylki kodu 2FA |
|
||||
| twofa_failed_attempts | Liczba nieudanych prob 2FA |
|
||||
|
||||
**Uzywane w:** `Domain\User\UserRepository`, `admin\Controllers\UsersController`, `admin\factory\Users`
|
||||
|
||||
**Aktualizacja 2026-02-12:** uzycia `pp_users` sa prowadzone przez `Domain\\User\\UserRepository` (legacy `admin\\factory\\Users` usunieto).
|
||||
|
||||
## pp_langs
|
||||
Jezyki panelu i frontendu.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK (2-literowe ID jezyka, np. pl, en) |
|
||||
| name | Nazwa jezyka |
|
||||
| status | 1 = aktywny, 0 = nieaktywny |
|
||||
| start | 1 = domyslny jezyk |
|
||||
| o | Kolejnosc |
|
||||
|
||||
**Uzywane w:** `Domain\\Languages\\LanguagesRepository`, `admin\\Controllers\\LanguagesController`, `admin\\factory\\Languages`, `front\\factory\\Languages`
|
||||
|
||||
## pp_langs_translations
|
||||
Slownik tlumaczen panelu/frontendu.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| text | Klucz/tekst bazowy |
|
||||
| <lang_id> | Kolumny dynamiczne per jezyk (np. pl, en) |
|
||||
|
||||
**Uzywane w:** `Domain\\Languages\\LanguagesRepository`, `admin\\Controllers\\LanguagesController`, `front\\factory\\Languages`
|
||||
|
||||
**Aktualizacja 2026-02-12:** modul jezykow i tlumaczen (`pp_langs`, `pp_langs_translations`) obslugiwany przez `Domain\\Languages\\LanguagesRepository`.
|
||||
|
||||
## pp_layouts
|
||||
Szablony layoutow (HTML/CSS/JS + flagi domyslne).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| name | Nazwa szablonu |
|
||||
| html | Kod HTML |
|
||||
| css | Kod CSS |
|
||||
| js | Kod JS |
|
||||
| m_html | Kod HTML mobilny |
|
||||
| m_css | Kod CSS mobilny |
|
||||
| m_js | Kod JS mobilny |
|
||||
| status | Domyslny layout stron (0/1) |
|
||||
| categories_default | Domyslny layout kategorii (0/1) |
|
||||
|
||||
**Uzywane w:** `Domain\\Layouts\\LayoutsRepository`, `admin\\Controllers\\LayoutsController`, `front\\factory\\Layouts`
|
||||
|
||||
## pp_layouts_pages
|
||||
Przypisanie layoutow do stron CMS.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| layout_id | FK do pp_layouts |
|
||||
| page_id | FK do pp_pages |
|
||||
|
||||
**Uzywane w:** `Domain\\Layouts\\LayoutsRepository`, `front\\factory\\Layouts`
|
||||
|
||||
## pp_layouts_categories
|
||||
Przypisanie layoutow do kategorii sklepu.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| layout_id | FK do pp_layouts |
|
||||
| category_id | FK do pp_shop_categories |
|
||||
|
||||
**Uzywane w:** `Domain\\Layouts\\LayoutsRepository`, `front\\factory\\Layouts`
|
||||
|
||||
**Aktualizacja 2026-02-12 (ver. 0.256):** modul `/admin/layouts` korzysta z `Domain\\Layouts\\LayoutsRepository` (DI kontroler + fasada legacy).
|
||||
|
||||
## pp_newsletter
|
||||
Adresy e-mail zapisane do newslettera.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| email | Adres e-mail subskrybenta |
|
||||
| hash | Hash potwierdzenia/wypisu |
|
||||
| status | 1 = potwierdzony, 0 = oczekujacy |
|
||||
|
||||
**Uzywane w:** `Domain\\Newsletter\\NewsletterRepository`, `front\\factory\\Newsletter`
|
||||
|
||||
## pp_newsletter_send
|
||||
Kolejka wysylki newslettera.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| email | Adres docelowy |
|
||||
| dates | Zakres dat artykulow (tekst) |
|
||||
| id_template | FK do `pp_newsletter_templates` (NULL gdy brak szablonu) |
|
||||
|
||||
**Uzywane w:** `Domain\\Newsletter\\NewsletterRepository`, `front\\factory\\Newsletter::newsletter_send()`
|
||||
|
||||
## pp_newsletter_templates
|
||||
Szablony tresci e-maili (uzytkownik + administracyjne/systemowe).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| name | Nazwa/klucz szablonu |
|
||||
| text | Tresc HTML szablonu |
|
||||
| is_admin | 1 = szablon administracyjny/systemowy, 0 = szablon uzytkownika |
|
||||
|
||||
**Uzywane w:** `Domain\\Newsletter\\NewsletterRepository`, `admin\\Controllers\\NewsletterController`, `front\\factory\\Newsletter`
|
||||
|
||||
**Aktualizacja 2026-02-12 (ver. 0.257):** modul `/admin/newsletter` korzysta z `Domain\\Newsletter\\NewsletterRepository` (DI kontroler + fasada legacy).
|
||||
|
||||
## pp_scontainers
|
||||
Kontenery statyczne (modul /admin/scontainers).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| status | 1 = aktywny, 0 = nieaktywny |
|
||||
| show_title | 1 = pokaz tytul, 0 = ukryj tytul |
|
||||
|
||||
**Uzywane w:** `Domain\Scontainers\ScontainersRepository`, `admin\Controllers\ScontainersController`, `front\factory\Scontainers`
|
||||
|
||||
## pp_scontainers_langs
|
||||
Tlumaczenia kontenerow statycznych (per jezyk).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| container_id | FK do pp_scontainers |
|
||||
| lang_id | ID jezyka (np. pl, en) |
|
||||
| title | Tytul kontenera |
|
||||
| text | Tresc HTML kontenera |
|
||||
|
||||
**Uzywane w:** `Domain\Scontainers\ScontainersRepository`, `front\factory\Scontainers`
|
||||
|
||||
**Aktualizacja 2026-02-12 (ver. 0.259):** modul `/admin/scontainers` korzysta z `Domain\Scontainers\ScontainersRepository` (DI kontroler + fasada legacy).
|
||||
|
||||
**Aktualizacja 2026-02-12 (ver. 0.260):** modul `/admin/articles_archive` korzysta z `Domain\Article\ArticleRepository` (`listArchivedForAdmin`, `restore`, `deletePermanently`) przez `admin\Controllers\ArticlesArchiveController`.
|
||||
|
||||
## pp_shop_coupon
|
||||
Kody rabatowe sklepu (modul `/admin/shop_coupon`).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| name | Kod kuponu (UNIQUE) |
|
||||
| status | Status: 1 = aktywny, 0 = nieaktywny |
|
||||
| send | Czy kupon zostal wyslany (0/1) |
|
||||
| used | Czy kupon zostal wykorzystany (0/1) |
|
||||
| date_used | Data wykorzystania kuponu (NULL gdy brak) |
|
||||
| used_count | Licznik uzyc kuponu |
|
||||
| type | Typ kuponu (obecnie: 1 = rabat procentowy na koszyk) |
|
||||
| amount | Wartosc kuponu (np. procent) |
|
||||
| one_time | Czy kupon jednorazowy (0/1) |
|
||||
| include_discounted_product | Czy obejmuje rowniez produkty przecenione (0/1) |
|
||||
| categories | JSON z ID kategorii objetych kuponem (NULL = bez ograniczenia) |
|
||||
|
||||
**Uzywane w:** `Domain\Coupon\CouponRepository`, `admin\Controllers\ShopCouponController`, `shop\Coupon`, `front\factory\ShopCoupon`, `front\factory\ShopOrder`
|
||||
|
||||
**Aktualizacja 2026-02-13 (ver. 0.266):** modul `/admin/shop_coupon` korzysta z `Domain\Coupon\CouponRepository` przez `admin\Controllers\ShopCouponController`. Usunieto legacy klasy `admin\controls\ShopCoupon` i `admin\factory\ShopCoupon`.
|
||||
|
||||
## pp_shop_promotion
|
||||
Promocje sklepu (modul `/admin/shop_promotion`).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| name | Nazwa promocji |
|
||||
| status | Status: 1 = aktywna, 0 = nieaktywna |
|
||||
| condition_type | Typ warunku promocji (slownik w `shop\Promotion::$condition_type`) |
|
||||
| discount_type | Typ rabatu (slownik w `shop\Promotion::$discount_type`) |
|
||||
| amount | Wartosc rabatu (np. procent) |
|
||||
| date_from | Data startu promocji (NULL = aktywna od razu) |
|
||||
| date_to | Data konca promocji (NULL = bez daty konca) |
|
||||
| categories | JSON z ID kategorii grupy I |
|
||||
| condition_categories | JSON z ID kategorii grupy II |
|
||||
| include_coupon | Czy laczyc z kuponami rabatowymi (0/1) |
|
||||
| include_product_promo | Czy uwzgledniac produkty przecenione (0/1) |
|
||||
| min_product_count | Minimalna liczba produktow (dla wybranych warunkow) |
|
||||
| price_cheapest_product | Cena najtanszego produktu (dla wybranych warunkow) |
|
||||
|
||||
**Uzywane w:** `Domain\Promotion\PromotionRepository`, `admin\Controllers\ShopPromotionController`, `shop\Promotion`, `front\factory\ShopPromotion`
|
||||
|
||||
**Aktualizacja 2026-02-13:** modul `/admin/shop_promotion` korzysta z `Domain\Promotion\PromotionRepository` przez `admin\Controllers\ShopPromotionController`. Usunieto legacy klasy `admin\controls\ShopPromotion` i `admin\factory\ShopPromotion`.
|
||||
|
||||
**Aktualizacja 2026-02-13 (ver. 0.265):** dodano obsluge `date_from` (repozytorium, formularz admin, lista admin, filtr aktywnych promocji na froncie) oraz poprawke zapisu edycji promocji po `id`.
|
||||
|
||||
## pp_shop_apilo_settings
|
||||
Ustawienia integracji Apilo (key-value).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| name | Klucz ustawienia (np. client-id, access-token) |
|
||||
| value | Wartosc ustawienia |
|
||||
|
||||
**Uzywane w:** `Domain\Integrations\IntegrationsRepository`, `admin\Controllers\IntegrationsController`, `admin\factory\Integrations`
|
||||
|
||||
## pp_shop_shoppro_settings
|
||||
Ustawienia integracji ShopPRO (key-value).
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK |
|
||||
| name | Klucz ustawienia (np. domain, db_name) |
|
||||
| value | Wartosc ustawienia |
|
||||
|
||||
**Uzywane w:** `Domain\Integrations\IntegrationsRepository`, `admin\Controllers\IntegrationsController`, `admin\factory\Integrations`
|
||||
|
||||
**Aktualizacja 2026-02-13:** modul `/admin/integrations/` korzysta z `Domain\Integrations\IntegrationsRepository` (DI kontroler + fasada legacy). Usunieto integracje Sellasist i Baselinker.
|
||||
|
||||
## pp_shop_statuses
|
||||
Statusy zamowien sklepu (modul `/admin/shop_statuses`). Statusy sa predefiniowane - brak dodawania/usuwania, mozliwa edycja koloru i mapowania Apilo.
|
||||
|
||||
| Kolumna | Opis |
|
||||
|---------|------|
|
||||
| id | PK (zaczyna sie od 0!) |
|
||||
| status | Nazwa statusu (read-only) |
|
||||
| color | Kolor statusu (hex, np. #ff0000) |
|
||||
| o | Kolejnosc wyswietlania |
|
||||
| apilo_status_id | ID statusu w Apilo (NULL gdy brak mapowania) |
|
||||
| baselinker_status_id | DEPRECATED (usuniety w ver. 0.263) |
|
||||
| sellasist_status_id | DEPRECATED (usuniety w ver. 0.263) |
|
||||
|
||||
**Uzywane w:** `Domain\ShopStatus\ShopStatusRepository`, `admin\Controllers\ShopStatusesController`, `front\factory\ShopStatuses`, `shop\Order`, `cron.php`
|
||||
|
||||
**Aktualizacja 2026-02-14 (ver. 0.267):** modul `/admin/shop_statuses` korzysta z `Domain\ShopStatus\ShopStatusRepository` przez `admin\Controllers\ShopStatusesController`. Usunieto legacy klasy `admin\controls\ShopStatuses` i `admin\factory\ShopStatuses`. `front\factory\ShopStatuses` dziala jako fasada do repozytorium.
|
||||
172
docs/FORM_EDIT_SYSTEM.md
Normal file
172
docs/FORM_EDIT_SYSTEM.md
Normal file
@@ -0,0 +1,172 @@
|
||||
# Form Edit System - Dokumentacja użycia
|
||||
|
||||
## Architektura
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Controller │
|
||||
│ ┌─────────────────┐ ┌─────────────────┐ │
|
||||
│ │ edit() │ │ save() │ │
|
||||
│ │ - buduje VM │ │ - walidacja │ │
|
||||
│ │ - renderuje │ │ - zapis │ │
|
||||
│ └────────┬────────┘ └─────────────────┘ │
|
||||
└───────────┼─────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ FormEditViewModel │
|
||||
│ - title, formId, data, fields, tabs, actions │
|
||||
│ - validationErrors, persist, languages │
|
||||
└───────────┬─────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ components/form-edit.php (szablon) │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ FormFieldRenderer - renderuje każde pole │ │
|
||||
│ │ ├─ input, select, textarea, switch │ │
|
||||
│ │ ├─ date, datetime, editor, image │ │
|
||||
│ │ └─ lang_section (zagnieżdżone pola) │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Pliki systemu
|
||||
|
||||
| Plik | Opis |
|
||||
|------|------|
|
||||
| `autoload/admin/ViewModels/Forms/FormFieldType.php` | Stale typow pol |
|
||||
| `autoload/admin/ViewModels/Forms/FormField.php` | Factory methods per typ |
|
||||
| `autoload/admin/ViewModels/Forms/FormTab.php` | Zakladki |
|
||||
| `autoload/admin/ViewModels/Forms/FormAction.php` | Akcje (zapisz, anuluj) |
|
||||
| `autoload/admin/ViewModels/Forms/FormEditViewModel.php` | ViewModel formularza |
|
||||
| `autoload/admin/Support/Forms/FormValidator.php` | Walidacja pol |
|
||||
| `autoload/admin/Support/Forms/FormRequestHandler.php` | Obsluga POST + persist |
|
||||
| `autoload/admin/Support/Forms/FormFieldRenderer.php` | Renderowanie HTML |
|
||||
| `admin/templates/components/form-edit.php` | Uniwersalny szablon |
|
||||
|
||||
## Przykład użycia w kontrolerze
|
||||
|
||||
```php
|
||||
use admin\ViewModels\Forms\FormEditViewModel;
|
||||
use admin\ViewModels\Forms\FormField;
|
||||
use admin\ViewModels\Forms\FormTab;
|
||||
use admin\ViewModels\Forms\FormAction;
|
||||
use admin\Support\Forms\FormRequestHandler;
|
||||
|
||||
class BannerController
|
||||
{
|
||||
public function edit(): string
|
||||
{
|
||||
$banner = $this->repository->find($id);
|
||||
$languages = \admin\factory\Languages::languages_list();
|
||||
|
||||
$viewModel = new FormEditViewModel(
|
||||
formId: 'banner-edit',
|
||||
title: 'Edycja banera',
|
||||
data: $banner,
|
||||
tabs: [
|
||||
new FormTab('settings', 'Ustawienia', 'fa-wrench'),
|
||||
new FormTab('content', 'Zawartość', 'fa-file'),
|
||||
],
|
||||
fields: [
|
||||
// Zakładka Ustawienia
|
||||
FormField::text('name', [
|
||||
'label' => 'Nazwa',
|
||||
'tab' => 'settings',
|
||||
'required' => true,
|
||||
]),
|
||||
FormField::switch('status', [
|
||||
'label' => 'Aktywny',
|
||||
'tab' => 'settings',
|
||||
]),
|
||||
FormField::date('date_start', [
|
||||
'label' => 'Data rozpoczęcia',
|
||||
'tab' => 'settings',
|
||||
]),
|
||||
|
||||
// Sekcja językowa w zakładce Zawartość
|
||||
FormField::langSection('translations', 'content', [
|
||||
FormField::image('src', ['label' => 'Obraz']),
|
||||
FormField::text('url', ['label' => 'Url']),
|
||||
FormField::editor('text', ['label' => 'Treść']),
|
||||
]),
|
||||
],
|
||||
actions: [
|
||||
FormAction::save('/admin/banners/save', '/admin/banners'),
|
||||
FormAction::cancel('/admin/banners'),
|
||||
],
|
||||
languages: $languages,
|
||||
persist: true,
|
||||
);
|
||||
|
||||
return \Tpl::view('components/form-edit', ['form' => $viewModel]);
|
||||
}
|
||||
|
||||
public function save(): void
|
||||
{
|
||||
$formHandler = new FormRequestHandler();
|
||||
$viewModel = $this->buildFormViewModel(); // jak w edit()
|
||||
|
||||
$result = $formHandler->handleSubmit($viewModel, $_POST);
|
||||
|
||||
if (!$result['success']) {
|
||||
// Błędy walidacji - zapisane automatycznie do sesji
|
||||
echo json_encode(['success' => false, 'errors' => $result['errors']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Sukces - persist wyczyszczony automatycznie
|
||||
$this->repository->save($result['data']);
|
||||
echo json_encode(['success' => true]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Dostępne typy pól
|
||||
|
||||
| Typ | Metoda | Opcje |
|
||||
|-----|--------|-------|
|
||||
| `text` | `FormField::text(name, ['label' => '...', 'required' => true])` | placeholder, help |
|
||||
| `number` | `FormField::number(name, [...])` | - |
|
||||
| `email` | `FormField::email(name, [...])` | walidacja formatu |
|
||||
| `password` | `FormField::password(name, [...])` | - |
|
||||
| `date` | `FormField::date(name, [...])` | datetimepicker |
|
||||
| `datetime` | `FormField::datetime(name, [...])` | datetimepicker z czasem |
|
||||
| `switch` | `FormField::switch(name, [...])` | checked (bool) |
|
||||
| `select` | `FormField::select(name, ['options' => [...]])` | options: [key => label] |
|
||||
| `textarea` | `FormField::textarea(name, ['rows' => 4])` | rows |
|
||||
| `editor` | `FormField::editor(name, ['toolbar' => 'MyTool'])` | CKEditor |
|
||||
| `image` | `FormField::image(name, ['filemanager' => true])` | filemanager URL |
|
||||
| `file` | `FormField::file(name, [...])` | filemanager |
|
||||
| `hidden` | `FormField::hidden(name, value)` | - |
|
||||
| `color` | `FormField::color(name, ['label' => '...'])` | HTML5 color picker + text input |
|
||||
| `lang_section` | `FormField::langSection(name, 'tab', [fields])` | pola per język |
|
||||
|
||||
## Walidacja
|
||||
|
||||
Walidacja jest automatyczna na podstawie właściwości pól:
|
||||
- `required` - pole wymagane
|
||||
- `type` = `email` - walidacja formatu e-mail
|
||||
- `type` = `number` - walidacja liczby
|
||||
- `type` = `date` - walidacja formatu YYYY-MM-DD
|
||||
|
||||
Dla sekcji językowych walidacja jest powtarzana dla każdego aktywnego języka.
|
||||
|
||||
## Persist (zapamiętywanie danych)
|
||||
|
||||
Gdy `persist = true`:
|
||||
1. Przy błędzie walidacji dane są zapisywane w `$_SESSION['form_persist'][$formId]`
|
||||
2. Formularz automatycznie przywraca dane z sesji przy ponownym wyświetleniu
|
||||
3. Po udanym zapisie sesja jest czyszczona automatycznie przez `FormRequestHandler`
|
||||
|
||||
## Przerabianie istniejących formularzy
|
||||
|
||||
1. **Kontroler** - zamień `view\Xxx::edit()` na `FormEditViewModel`
|
||||
2. **Repository** - dostosuj `save()` do formatu z `FormRequestHandler` (lub dodaj wsparcie dla obu formatów)
|
||||
3. **Szablon** - usuń stary szablon lub zostaw jako fallback
|
||||
4. **Testy** - zaktualizuj testy jeśli zmienił się format danych
|
||||
|
||||
---
|
||||
*Dokument aktualizowany: 2026-02-14*
|
||||
254
docs/PROJECT_STRUCTURE.md
Normal file
254
docs/PROJECT_STRUCTURE.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# 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`
|
||||
|
||||
#### Apilo
|
||||
- **Aktualizacja pojedynczego produktu:** synchronizacja cen i stanow
|
||||
- Czestotliwosc: Co 10 minut
|
||||
- **Synchronizacja cennika:** masowa aktualizacja cen z Apilo
|
||||
- Czestotliwosc: Co 1 godzine
|
||||
|
||||
**Uwaga:** Integracje Sellasist i Baselinker zostaly usuniete w ver. 0.263.
|
||||
|
||||
## 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
|
||||
│ │ ├── Controllers/ # Nowe kontrolery DI
|
||||
│ │ ├── controls/ # Kontrolery legacy (fallback)
|
||||
│ │ └── factory/ # Fabryki/helpery
|
||||
│ ├── Domain/ # Repozytoria/logika domenowa
|
||||
│ ├── front/ # Klasy frontendu
|
||||
│ │ └── factory/ # Fabryki/helpery
|
||||
│ └── shop/ # Klasy sklepu
|
||||
├── docs/ # Dokumentacja techniczna
|
||||
├── 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`:
|
||||
- `apilo_product_id`, `apilo_product_name`, `apilo_get_data_date`
|
||||
- Tabele ustawien:
|
||||
- `pp_shop_apilo_settings` (key-value)
|
||||
- `pp_shop_shoppro_settings` (key-value)
|
||||
|
||||
Pelna dokumentacja tabel: `DATABASE_STRUCTURE.md`
|
||||
|
||||
## 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
|
||||
│ ├── Banner/
|
||||
│ │ └── BannerRepository.php
|
||||
│ ├── Settings/
|
||||
│ │ └── SettingsRepository.php
|
||||
│ ├── Cache/
|
||||
│ │ └── CacheRepository.php
|
||||
│ ├── Article/
|
||||
│ │ └── ArticleRepository.php
|
||||
│ ├── User/
|
||||
│ │ └── UserRepository.php
|
||||
│ ├── Languages/
|
||||
│ │ └── LanguagesRepository.php
|
||||
│ ├── Layouts/
|
||||
│ │ └── LayoutsRepository.php
|
||||
│ ├── Newsletter/
|
||||
│ │ └── NewsletterRepository.php
|
||||
│ ├── Scontainers/
|
||||
│ │ └── ScontainersRepository.php
|
||||
│ ├── Dictionaries/
|
||||
│ │ └── DictionariesRepository.php
|
||||
│ ├── Pages/
|
||||
│ │ └── PagesRepository.php
|
||||
│ ├── Integrations/
|
||||
│ │ └── IntegrationsRepository.php
|
||||
│ ├── Promotion/
|
||||
│ │ └── PromotionRepository.php
|
||||
│ ├── Coupon/
|
||||
│ │ └── CouponRepository.php
|
||||
│ ├── ShopStatus/
|
||||
│ │ └── ShopStatusRepository.php
|
||||
│ └── ...
|
||||
├── admin/
|
||||
│ ├── Controllers/ # Nowe kontrolery (namespace \admin\Controllers\)
|
||||
│ ├── 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
|
||||
// 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
|
||||
|
||||
Pelna dokumentacja testow: `TESTING.md`
|
||||
|
||||
---
|
||||
*Dokument aktualizowany: 2026-02-14*
|
||||
276
docs/REFACTORING_PLAN.md
Normal file
276
docs/REFACTORING_PLAN.md
Normal file
@@ -0,0 +1,276 @@
|
||||
# Plan Refaktoryzacji shopPRO - Domain-Driven Architecture
|
||||
|
||||
## Cel
|
||||
Stopniowe przeniesienie logiki biznesowej do architektury warstwowej:
|
||||
- **Domain/** - logika biznesowa (core)
|
||||
- **Admin/** - warstwa administratora
|
||||
- **Frontend/** - warstwa użytkownika
|
||||
- **Shared/** - współdzielone narzędzia
|
||||
|
||||
## Docelowa struktura
|
||||
|
||||
```
|
||||
autoload/
|
||||
├── Domain/ # Logika biznesowa (CORE) - namespace \Domain\
|
||||
│ ├── Product/
|
||||
│ │ ├── ProductRepository.php
|
||||
│ │ ├── ProductService.php # (przyszłość)
|
||||
│ │ └── ProductCacheService.php # (przyszłość)
|
||||
│ ├── Banner/
|
||||
│ │ └── BannerRepository.php
|
||||
│ ├── Settings/
|
||||
│ │ └── SettingsRepository.php
|
||||
│ ├── Cache/
|
||||
│ │ └── CacheRepository.php
|
||||
│ ├── Order/
|
||||
│ ├── Category/
|
||||
│ └── ...
|
||||
│
|
||||
├── admin/ # Warstwa administratora (istniejący katalog!)
|
||||
│ ├── Controllers/ # Nowe kontrolery - namespace \admin\Controllers\
|
||||
│ ├── controls/ # Stare kontrolery (legacy fallback)
|
||||
│ ├── factory/ # Stare helpery (legacy)
|
||||
│ └── view/ # Widoki (statyczne - OK bez zmian)
|
||||
│
|
||||
├── Frontend/ # Warstwa użytkownika (przyszłość)
|
||||
│ ├── Controllers/
|
||||
│ └── Services/
|
||||
│
|
||||
├── Shared/ # Współdzielone narzędzia
|
||||
│ ├── Cache/
|
||||
│ │ ├── CacheHandler.php
|
||||
│ │ └── RedisConnection.php
|
||||
│ └── Helpers/
|
||||
│ └── S.php
|
||||
│
|
||||
└── [LEGACY] # Stare klasy (stopniowo deprecated)
|
||||
├── shop/
|
||||
├── admin/factory/
|
||||
└── front/factory/
|
||||
```
|
||||
|
||||
### WAŻNE: Konwencja namespace → katalog (Linux case-sensitive!)
|
||||
- `\Domain\` → `autoload/Domain/` (duże D - nowy katalog)
|
||||
- `\admin\Controllers\` → `autoload/admin/Controllers/` (małe a - istniejący katalog)
|
||||
- NIE używać `\Admin\` (duże A) bo na serwerze Linux katalog to `admin/` (małe a)
|
||||
|
||||
## Zasady migracji
|
||||
|
||||
### 1. Stopniowość
|
||||
- Przenosimy **jedną funkcję na raz**
|
||||
- Zachowujemy kompatybilność wsteczną
|
||||
- Stare klasy działają jako fasady do nowych
|
||||
|
||||
### 2. Dependency Injection zamiast statycznych metod
|
||||
```php
|
||||
// ❌ STARE - statyczne
|
||||
class Product {
|
||||
public static function getQuantity($id) {
|
||||
global $mdb;
|
||||
return $mdb->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ NOWE - instancje z DI
|
||||
class ProductRepository {
|
||||
private $db;
|
||||
|
||||
public function __construct($db) {
|
||||
$this->db = $db;
|
||||
}
|
||||
|
||||
public function getQuantity($id) {
|
||||
return $this->db->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Fasady dla kompatybilności
|
||||
```php
|
||||
// Stara klasa wywołuje nową
|
||||
namespace shop;
|
||||
|
||||
class Product {
|
||||
public static function getQuantity($id) {
|
||||
global $mdb;
|
||||
$repo = new \Domain\Product\ProductRepository($mdb);
|
||||
return $repo->getQuantity($id);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Proces migracji funkcji
|
||||
|
||||
### Krok 1: Wybór funkcji
|
||||
- Wybierz prostą funkcję statyczną
|
||||
- Sprawdź jej zależności
|
||||
- Przeanalizuj gdzie jest używana
|
||||
|
||||
### Krok 2: Stworzenie nowej struktury
|
||||
- Utwórz folder `Domain/{Module}/`
|
||||
- Stwórz odpowiednią klasę (Repository/Service/Entity)
|
||||
- Przenieś logikę
|
||||
|
||||
### Krok 3: Znalezienie użyć
|
||||
```bash
|
||||
grep -r "Product::getQuantity" .
|
||||
```
|
||||
|
||||
### Krok 4: Aktualizacja wywołań
|
||||
- Opcja A: Bezpośrednie wywołanie nowej klasy
|
||||
- Opcja B: Fasada w starej klasie (zalecane na początek)
|
||||
|
||||
### Krok 5: Testy
|
||||
- Napisz test jednostkowy dla nowej funkcji
|
||||
- Sprawdź czy stare wywołania działają
|
||||
|
||||
## Status migracji
|
||||
|
||||
### ✅ Zmigrowane moduły
|
||||
| # | Modul | Wersja | Zakres |
|
||||
|---|-------|--------|--------|
|
||||
| 1 | Cache | 0.237 | CacheHandler, RedisConnection, clear_product_cache |
|
||||
| 2 | Product | 0.238-0.252 | getQuantity, getPrice, getName, archive/unarchive |
|
||||
| 3 | Banner | 0.239 | find, delete, save, kontroler DI |
|
||||
| 4 | Settings | 0.240/0.250 | saveSettings, getSettings, kontroler DI |
|
||||
| 5 | Dictionaries | 0.251 | listForAdmin, find, save, delete, kontroler DI |
|
||||
| 6 | ProductArchive | 0.252 | kontroler DI, table-list |
|
||||
| 7 | Filemanager | 0.252 | kontroler DI, fix Invalid Key |
|
||||
| 8 | Users | 0.253 | CRUD, logon, 2FA, kontroler DI |
|
||||
| 9 | Languages | 0.254 | languages + translations, kontroler DI |
|
||||
| 10 | Layouts | 0.256 | find, save, delete, menusWithPages, categoriesTree |
|
||||
| 11 | Newsletter | 0.257-0.258 | subskrybenci, szablony, ustawienia |
|
||||
| 12 | Scontainers | 0.259 | listForAdmin, find, save, delete |
|
||||
| 13 | ArticlesArchive | 0.260 | restore, deletePermanently |
|
||||
| 14 | Articles | 0.261 | pelna migracja (CRUD, AJAX, galeria, pliki) |
|
||||
| 15 | Pages | 0.262 | menu/page CRUD, drzewo stron, AJAX |
|
||||
| 16 | Integrations | 0.263 | Apilo/ShopPRO, cleanup Sellasist/Baselinker |
|
||||
| 17 | ShopPromotion | 0.264-0.265 | listForAdmin, find, save, delete, categoriesTree |
|
||||
| 18 | ShopCoupon | 0.266 | listForAdmin, find, save, delete, categoriesTree |
|
||||
| 19 | ShopStatuses | 0.267 | listForAdmin, find, save, color picker |
|
||||
|
||||
### Product - szczegolowy status
|
||||
- ✅ getQuantity (ver. 0.238)
|
||||
- ✅ getPrice (ver. 0.239)
|
||||
- ✅ getName (ver. 0.239)
|
||||
- ✅ archive / unarchive (ver. 0.241/0.252)
|
||||
- [ ] is_product_on_promotion
|
||||
- [ ] getFromCache
|
||||
- [ ] getProductImg
|
||||
|
||||
### 📋 Do zrobienia
|
||||
- Order
|
||||
- Category
|
||||
- ShopAttribute
|
||||
- ShopProduct (factory)
|
||||
|
||||
## Kolejność refaktoryzacji (priorytet)
|
||||
|
||||
1-13: ✅ Cache, Product, Banner, Settings, Dictionaries, ProductArchive, Filemanager, Users, Pages, Integrations, ShopPromotion, ShopCoupon, ShopStatuses
|
||||
|
||||
Nastepne:
|
||||
14. **Order**
|
||||
15. **Category**
|
||||
16. **ShopAttribute**
|
||||
|
||||
## Form Edit System
|
||||
|
||||
Nowy uniwersalny system formularzy edycji:
|
||||
- ✅ Klasy ViewModel: `FormFieldType`, `FormField`, `FormTab`, `FormAction`, `FormEditViewModel`
|
||||
- ✅ Walidacja: `FormValidator` z obsługą reguł per pole i sekcje językowe
|
||||
- ✅ Persist: `FormRequestHandler` - zapamiętywanie danych przy błędzie walidacji
|
||||
- ✅ Renderer: `FormFieldRenderer` - renderowanie wszystkich typów pól
|
||||
- ✅ Szablon: `admin/templates/components/form-edit.php` - uniwersalny layout
|
||||
- Wspierane typy pól: text, number, email, password, date, datetime, switch, select, textarea, editor, image, file, hidden, lang_section, color
|
||||
- Obsługa zakładek (vertical) i sekcji językowych (horizontal)
|
||||
- **Do zrobienia**: Przerobić pozostałe kontrolery/formularze (Product, Category, Pages, itd.)
|
||||
|
||||
Pelna dokumentacja: `docs/FORM_EDIT_SYSTEM.md`
|
||||
|
||||
## Zasady kodu
|
||||
|
||||
### 1. SOLID Principles
|
||||
- **S**ingle Responsibility - jedna klasa = jedna odpowiedzialność
|
||||
- **O**pen/Closed - otwarty na rozszerzenia, zamknięty na modyfikacje
|
||||
- **L**iskov Substitution - podklasy mogą zastąpić nadklasy
|
||||
- **I**nterface Segregation - wiele małych interfejsów
|
||||
- **D**ependency Inversion - zależności od abstrakcji
|
||||
|
||||
### 2. Nazewnictwo
|
||||
- **Entity** - `Product.php` (reprezentuje obiekt domenowy)
|
||||
- **Repository** - `ProductRepository.php` (dostęp do danych)
|
||||
- **Service** - `ProductService.php` (logika biznesowa)
|
||||
- **Controller** - `ProductController.php` (obsługa requestów)
|
||||
|
||||
### 3. Type Hinting
|
||||
```php
|
||||
// ✅ DOBRE
|
||||
public function getQuantity(int $id): ?int {
|
||||
return $this->db->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
}
|
||||
|
||||
// ❌ ZŁE
|
||||
public function getQuantity($id) {
|
||||
return $this->db->get('pp_shop_products', 'quantity', ['id' => $id]);
|
||||
}
|
||||
```
|
||||
|
||||
## Narzędzia pomocnicze
|
||||
|
||||
### Autoloader (produkcja)
|
||||
Autoloader w 9 entry pointach obsługuje dwie konwencje:
|
||||
1. `autoload/{namespace}/class.{ClassName}.php` (legacy)
|
||||
2. `autoload/{namespace}/{ClassName}.php` (PSR-4, fallback)
|
||||
|
||||
Entry pointy: `index.php`, `ajax.php`, `api.php`, `cron.php`, `cron-turstmate.php`, `download.php`, `admin/index.php`, `admin/ajax.php`, `cron/cron-xml.php`
|
||||
|
||||
### Static Analysis
|
||||
```bash
|
||||
composer require --dev phpstan/phpstan
|
||||
vendor/bin/phpstan analyse autoload/Domain
|
||||
```
|
||||
|
||||
## Testowanie
|
||||
|
||||
### Framework: PHPUnit
|
||||
```bash
|
||||
composer test
|
||||
```
|
||||
|
||||
### Struktura testów
|
||||
```
|
||||
tests/
|
||||
├── Unit/
|
||||
│ ├── Domain/
|
||||
│ │ ├── Article/ArticleRepositoryTest.php
|
||||
│ │ ├── Banner/BannerRepositoryTest.php
|
||||
│ │ ├── Cache/CacheRepositoryTest.php
|
||||
│ │ ├── Coupon/CouponRepositoryTest.php
|
||||
│ │ ├── Dictionaries/DictionariesRepositoryTest.php
|
||||
│ │ ├── Integrations/IntegrationsRepositoryTest.php
|
||||
│ │ ├── Product/ProductRepositoryTest.php
|
||||
│ │ ├── Promotion/PromotionRepositoryTest.php
|
||||
│ │ ├── Settings/SettingsRepositoryTest.php
|
||||
│ │ ├── ShopStatus/ShopStatusRepositoryTest.php
|
||||
│ │ └── User/UserRepositoryTest.php
|
||||
│ └── admin/
|
||||
│ └── Controllers/
|
||||
│ ├── ArticlesControllerTest.php
|
||||
│ ├── DictionariesControllerTest.php
|
||||
│ ├── IntegrationsControllerTest.php
|
||||
│ ├── ProductArchiveControllerTest.php
|
||||
│ ├── SettingsControllerTest.php
|
||||
│ ├── ShopCouponControllerTest.php
|
||||
│ ├── ShopPromotionControllerTest.php
|
||||
│ ├── ShopStatusesControllerTest.php
|
||||
│ └── UsersControllerTest.php
|
||||
└── Integration/
|
||||
```
|
||||
**Łącznie: 254 testów, 736 asercji**
|
||||
|
||||
Pelna dokumentacja testow: `TESTING.md`
|
||||
|
||||
---
|
||||
*Rozpoczęto: 2025-02-05*
|
||||
*Ostatnia aktualizacja: 2026-02-14*
|
||||
*Changelog zmian: `docs/CHANGELOG.md`*
|
||||
351
docs/TESTING.md
Normal file
351
docs/TESTING.md
Normal file
@@ -0,0 +1,351 @@
|
||||
# Testowanie shopPRO
|
||||
|
||||
## Szybki start
|
||||
|
||||
### Pelny zestaw testow
|
||||
```bash
|
||||
composer test
|
||||
```
|
||||
|
||||
Alternatywnie (Windows):
|
||||
```bash
|
||||
./test.ps1
|
||||
./test.bat
|
||||
./test-simple.bat
|
||||
./test-debug.bat
|
||||
```
|
||||
|
||||
Alternatywnie (Git Bash):
|
||||
```bash
|
||||
./test.sh
|
||||
```
|
||||
|
||||
### Konkretny plik testowy
|
||||
```bash
|
||||
./test.ps1 tests/Unit/Domain/Product/ProductRepositoryTest.php
|
||||
./test.ps1 tests/Unit/admin/Controllers/ArticlesControllerTest.php
|
||||
```
|
||||
|
||||
### Konkretny test (`--filter`)
|
||||
```bash
|
||||
./test.ps1 --filter testGetQuantityReturnsCorrectValue
|
||||
```
|
||||
|
||||
## Aktualny stan suite
|
||||
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (254 tests, 736 assertions)
|
||||
```
|
||||
|
||||
## Struktura testow
|
||||
|
||||
```text
|
||||
tests/
|
||||
|-- bootstrap.php
|
||||
|-- Unit/
|
||||
| |-- Domain/
|
||||
| | |-- Article/ArticleRepositoryTest.php
|
||||
| | |-- Banner/BannerRepositoryTest.php
|
||||
| | |-- Cache/CacheRepositoryTest.php
|
||||
| | |-- Coupon/CouponRepositoryTest.php
|
||||
| | |-- Dictionaries/DictionariesRepositoryTest.php
|
||||
| | |-- Integrations/IntegrationsRepositoryTest.php
|
||||
| | |-- Product/ProductRepositoryTest.php
|
||||
| | |-- Promotion/PromotionRepositoryTest.php
|
||||
| | |-- Settings/SettingsRepositoryTest.php
|
||||
| | |-- ShopStatus/ShopStatusRepositoryTest.php
|
||||
| | `-- User/UserRepositoryTest.php
|
||||
| `-- admin/
|
||||
| `-- Controllers/
|
||||
| |-- ArticlesControllerTest.php
|
||||
| |-- DictionariesControllerTest.php
|
||||
| |-- IntegrationsControllerTest.php
|
||||
| |-- ProductArchiveControllerTest.php
|
||||
| |-- SettingsControllerTest.php
|
||||
| |-- ShopCouponControllerTest.php
|
||||
| |-- ShopPromotionControllerTest.php
|
||||
| |-- ShopStatusesControllerTest.php
|
||||
| `-- UsersControllerTest.php
|
||||
`-- Integration/
|
||||
```
|
||||
|
||||
## Tryby uruchamiania
|
||||
|
||||
### 1. TestDox (czytelna lista)
|
||||
```bash
|
||||
./test.bat
|
||||
```
|
||||
Uruchamia:
|
||||
```bash
|
||||
C:\xampp\php\php.exe phpunit.phar --testdox
|
||||
```
|
||||
|
||||
### 2. Standard (kropki)
|
||||
```bash
|
||||
./test-simple.bat
|
||||
```
|
||||
Uruchamia:
|
||||
```bash
|
||||
C:\xampp\php\php.exe phpunit.phar
|
||||
```
|
||||
|
||||
### 3. Debug (pelne logowanie)
|
||||
```bash
|
||||
./test-debug.bat
|
||||
```
|
||||
Uruchamia:
|
||||
```bash
|
||||
C:\xampp\php\php.exe phpunit.phar --debug
|
||||
```
|
||||
|
||||
### 4. PowerShell (najbardziej niezawodne)
|
||||
```bash
|
||||
./test.ps1
|
||||
```
|
||||
- najpierw probuje `php` z PATH
|
||||
- jesli brak, probuje m.in. `C:\xampp\php\php.exe`
|
||||
- zawsze dodaje `--do-not-cache-result`
|
||||
|
||||
## Interpretacja wynikow
|
||||
|
||||
```text
|
||||
. = test przeszedl
|
||||
E = error (blad wykonania)
|
||||
F = failure (niezgodna asercja)
|
||||
```
|
||||
|
||||
Przyklad sukcesu:
|
||||
```text
|
||||
................................................................. 65 / 82 ( 79%)
|
||||
................. 82 / 82 (100%)
|
||||
|
||||
OK (82 tests, 181 assertions)
|
||||
```
|
||||
|
||||
## Dodawanie nowych testow
|
||||
|
||||
1. Dodaj plik w odpowiednim module, np. `tests/Unit/Domain/<Module>/<Class>Test.php`.
|
||||
2. Rozszerz `PHPUnit\Framework\TestCase`.
|
||||
3. Nazwy metod zaczynaj od `test`.
|
||||
4. Trzymaj sie wzorca AAA: Arrange, Act, Assert.
|
||||
|
||||
## Mockowanie (przyklad)
|
||||
|
||||
```php
|
||||
$mockDb = $this->createMock(\medoo::class);
|
||||
$mockDb->method('get')->willReturn(42);
|
||||
|
||||
$repo = new ProductRepository($mockDb);
|
||||
$value = $repo->getQuantity(123);
|
||||
|
||||
$this->assertEquals(42, $value);
|
||||
```
|
||||
|
||||
## Przydatne informacje
|
||||
|
||||
- Konfiguracja PHPUnit: `phpunit.xml`
|
||||
- Bootstrap testow: `tests/bootstrap.php`
|
||||
- Dodatkowy opis: `tests/README.md`
|
||||
|
||||
## Aktualizacja suite
|
||||
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (119 tests, 256 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/User/UserRepositoryTest.php` (25 testow: CRUD, logon, 2FA verify/send, checkLogin, updateById)
|
||||
- `tests/Unit/admin/Controllers/UsersControllerTest.php` (12 testow: kontrakty + normalizeUser)
|
||||
|
||||
Aktualizacja po migracji widokow Users (2026-02-12):
|
||||
```text
|
||||
OK (120 tests, 262 assertions)
|
||||
```
|
||||
|
||||
## Aktualizacja suite (finalizacja Users)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (120 tests, 262 assertions)
|
||||
```
|
||||
|
||||
Aktualizacja po migracji Languages (2026-02-12):
|
||||
```text
|
||||
OK (130 tests, 301 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Languages/LanguagesRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/LanguagesControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.254)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (130 tests, 301 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Languages/LanguagesRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/LanguagesControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.255)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (130 tests, 303 assertions)
|
||||
```
|
||||
|
||||
## Aktualizacja suite (release 0.256)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (141 tests, 336 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Layouts/LayoutsRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/LayoutsControllerTest.php`
|
||||
|
||||
Zaktualizowane testy 2026-02-12:
|
||||
- `tests/Unit/Domain/Languages/LanguagesRepositoryTest.php` (defaultLanguageId)
|
||||
- `tests/Unit/admin/Controllers/ArticlesControllerTest.php` (konstruktor + LayoutsRepository)
|
||||
|
||||
## Aktualizacja suite (release 0.257)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (150 tests, 372 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Newsletter/NewsletterRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/NewsletterControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.258)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (150 tests, 372 assertions)
|
||||
```
|
||||
|
||||
## Aktualizacja suite (release 0.259)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (158 tests, 397 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Scontainers/ScontainersRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/ScontainersControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.260)
|
||||
Ostatnio zweryfikowano: 2026-02-12
|
||||
|
||||
```text
|
||||
OK (165 tests, 424 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-12:
|
||||
- `tests/Unit/Domain/Article/ArticleRepositoryTest.php` (rozszerzenie o testy `restore`, `deletePermanently`, `listArchivedForAdmin`)
|
||||
- `tests/Unit/admin/Controllers/ArticlesArchiveControllerTest.php`
|
||||
|
||||
## Aktualizacja suite (release 0.261)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (176 tests, 439 assertions)
|
||||
```
|
||||
|
||||
Nowe testy/rozszerzenia 2026-02-13:
|
||||
- `tests/Unit/Domain/Article/ArticleRepositoryTest.php` (nowe przypadki dla `pagesSummaryForArticles`, `updateImageAlt`, `markFileToDelete`)
|
||||
- `tests/Unit/admin/Controllers/ArticlesControllerTest.php` (nowe kontrakty dla akcji `imageAltChange`, `fileNameChange`, `imageDelete`, `fileDelete`)
|
||||
|
||||
## Aktualizacja suite (release 0.261)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (178 tests, 443 assertions)
|
||||
```
|
||||
|
||||
Nowe testy/rozszerzenia 2026-02-13:
|
||||
- `tests/Unit/Domain/Article/ArticleRepositoryTest.php` (nowe przypadki dla `saveFilesOrder`)
|
||||
|
||||
## Aktualizacja suite (Pages migration)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (186 tests, 478 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-13:
|
||||
- `tests/Unit/Domain/Pages/PagesRepositoryTest.php`
|
||||
- `tests/Unit/admin/Controllers/PagesControllerTest.php`
|
||||
|
||||
Zaktualizowane testy 2026-02-13:
|
||||
- `tests/Unit/admin/Controllers/ArticlesControllerTest.php` (konstruktor z `Domain\\Pages\\PagesRepository`)
|
||||
|
||||
## Aktualizacja suite (Integrations refactor, ver. 0.263)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (212 tests, 577 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-13:
|
||||
- `tests/Unit/Domain/Integrations/IntegrationsRepositoryTest.php` (16 testow: getSettings, getSetting, saveSetting, linkProduct, unlinkProduct, getProductSku, apiloGetAccessToken, invalid provider, settings table mapping)
|
||||
- `tests/Unit/admin/Controllers/IntegrationsControllerTest.php` (10 testow: kontrakty metod, return types, brak metod sellasist/baselinker)
|
||||
|
||||
Zaktualizowane pliki:
|
||||
- `tests/bootstrap.php` (dodany stub `S::remove_special_chars()`)
|
||||
|
||||
## Aktualizacja suite (ShopPromotion refactor, ver. 0.264)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (222 tests, 609 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-13:
|
||||
- `tests/Unit/Domain/Promotion/PromotionRepositoryTest.php` (6 testow: find default, save insert, delete, whitelist sortowania, drzewo kategorii)
|
||||
- `tests/Unit/admin/Controllers/ShopPromotionControllerTest.php` (4 testy: kontrakty metod i DI konstruktora)
|
||||
|
||||
## Aktualizacja suite (ShopPromotion fix + date_from, ver. 0.265)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (222 tests, 614 assertions)
|
||||
```
|
||||
|
||||
Zmiany testowe 2026-02-13:
|
||||
- rozszerzenie `tests/Unit/Domain/Promotion/PromotionRepositoryTest.php` o asercje `date_from`
|
||||
|
||||
## Aktualizacja suite (ShopCoupon refactor, ver. 0.266)
|
||||
Ostatnio zweryfikowano: 2026-02-13
|
||||
|
||||
```text
|
||||
OK (235 tests, 682 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-13:
|
||||
- `tests/Unit/Domain/Coupon/CouponRepositoryTest.php` (8 testow: find default/normalize, save insert/update, delete, whitelist sortowania, drzewo kategorii)
|
||||
- `tests/Unit/admin/Controllers/ShopCouponControllerTest.php` (5 testow: kontrakty metod, aliasy legacy, DI konstruktora)
|
||||
|
||||
Ponowna weryfikacja po poprawkach UI (drzewko + checkboxy): 2026-02-13
|
||||
- `OK (235 tests, 682 assertions)`
|
||||
|
||||
## Aktualizacja suite (ShopStatuses refactor, ver. 0.267)
|
||||
Ostatnio zweryfikowano: 2026-02-14
|
||||
|
||||
```text
|
||||
OK (254 tests, 736 assertions)
|
||||
```
|
||||
|
||||
Nowe testy dodane 2026-02-14:
|
||||
- `tests/Unit/Domain/ShopStatus/ShopStatusRepositoryTest.php` (9 testow: find z ID=0, find null apilo, save update, save z ID=0, empty apilo sets null, reject negative ID, getApiloStatusId, getByIntegrationStatusId, allStatuses, whitelist sortowania)
|
||||
- `tests/Unit/admin/Controllers/ShopStatusesControllerTest.php` (5 testow: kontrakty metod, brak aliasow legacy, return types, DI konstruktora)
|
||||
125
docs/UPDATE_INSTRUCTIONS.md
Normal file
125
docs/UPDATE_INSTRUCTIONS.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Instrukcja tworzenia aktualizacji shopPRO
|
||||
|
||||
## Struktura aktualizacji
|
||||
|
||||
Aktualizacje znajdują się w folderze `updates/0.XX/` gdzie XX oznacza dziesiątki wersji.
|
||||
|
||||
### Pliki aktualizacji:
|
||||
- `ver_X.XXX.zip` - paczka ZIP ze zmienionymi plikami (BEZ folderu wersji, bezpośrednio struktura katalogów)
|
||||
- `ver_X.XXX_sql.txt` - opcjonalny plik z zapytaniami SQL (jeśli wymagane zmiany w bazie)
|
||||
- `ver_X.XXX_files.txt` - opcjonalny plik z listą plików do **USUNIĘCIA** przy aktualizacji (format: `F: ../sciezka/do/pliku.php`)
|
||||
- `changelog.php` - historia zmian
|
||||
- `versions.php` - konfiguracja wersji (zmienna `$current_ver`)
|
||||
|
||||
### Zasada pakowania plików
|
||||
- Do paczek aktualizacji **nie dodajemy plików `*.md`** (dokumentacja jest tylko wewnętrzna/deweloperska).
|
||||
- Do paczek aktualizacji **nie dodajemy `updates/changelog.php`** (to plik serwisowy po stronie repozytorium aktualizacji, nie runtime klienta).
|
||||
- Do paczek aktualizacji **nie dodajemy głównego `.htaccess` z katalogu projektu** (ten plik wdrażamy osobno, poza ZIP aktualizacji).
|
||||
|
||||
## Procedura tworzenia nowej aktualizacji
|
||||
|
||||
### 1. Określ numer wersji
|
||||
Sprawdź ostatnią wersję w `temp/` i zwiększ o 1.
|
||||
|
||||
### 2. Utwórz folder tymczasowy ze strukturą w katalogu temp
|
||||
```bash
|
||||
mkdir -p temp/temp_XXX/sciezka/do/pliku
|
||||
```
|
||||
|
||||
**WAŻNE:** W archiwum ZIP NIE powinno być folderu z nazwą wersji (np. ver_0.234/).
|
||||
Struktura ZIP powinna zaczynać się bezpośrednio od katalogów projektu (admin/, autoload/, itp.).
|
||||
|
||||
### 3. Skopiuj zmienione pliki do folderu tymczasowego
|
||||
```bash
|
||||
cp sciezka/do/pliku.php temp/temp_XXX/sciezka/do/pliku.php
|
||||
```
|
||||
|
||||
### 4. Utwórz plik ZIP z zawartości folderu (nie z samego folderu!)
|
||||
```powershell
|
||||
cd temp/temp_XXX
|
||||
powershell -Command "Compress-Archive -Path '*' -DestinationPath '../ver_X.XXX.zip' -Force"
|
||||
```
|
||||
|
||||
### 5. Usuń folder tymczasowy
|
||||
```bash
|
||||
rm -rf temp/temp_XXX
|
||||
```
|
||||
|
||||
### 6. Zaktualizuj changelog.php
|
||||
Dodaj wpis na początku pliku:
|
||||
```html
|
||||
<b>ver. X.XXX - DD.MM.YYYY</b><br />
|
||||
- NEW/FIX/UPDATE - opis zmiany
|
||||
<hr>
|
||||
```
|
||||
|
||||
Prefiksy:
|
||||
- `NEW` - nowa funkcjonalność
|
||||
- `FIX` - naprawa błędu
|
||||
- `UPDATE` - aktualizacja istniejącej funkcjonalności
|
||||
|
||||
### 7. Zaktualizuj versions.php
|
||||
Zmień wartość `$current_ver` na nowy numer wersji (bez przedrostka 0.):
|
||||
```php
|
||||
$current_ver = 234; // dla wersji 0.234
|
||||
```
|
||||
|
||||
### 8. (Opcjonalnie) Utwórz plik SQL
|
||||
Jeśli aktualizacja wymaga zmian w bazie danych, utwórz plik `ver_X.XXX_sql.txt` z zapytaniami SQL.
|
||||
|
||||
### 9. (Opcjonalnie) Utwórz plik z listą plików do usunięcia
|
||||
Jeśli aktualizacja wymaga usunięcia przestarzałych plików, utwórz plik `ver_X.XXX_files.txt`:
|
||||
```
|
||||
F: ../sciezka/do/pliku1.php
|
||||
F: ../sciezka/do/pliku2.php
|
||||
```
|
||||
**UWAGA:** Pliki wymienione w tym pliku zostaną USUNIĘTE z systemu podczas aktualizacji.
|
||||
|
||||
## Przykład - aktualizacja 0.234
|
||||
|
||||
Zmienione pliki:
|
||||
- `autoload/admin/controls/class.ShopOrder.php`
|
||||
- `admin/templates/shop-order/order-details.php`
|
||||
|
||||
Opis: Dodanie przycisku do zaznaczania zamówienia jako wysłane do trustmate.io
|
||||
|
||||
### Komendy:
|
||||
|
||||
```bash
|
||||
# Utwórz strukturę w folderze tymczasowym
|
||||
mkdir -p temp/temp_234/autoload/admin/controls
|
||||
mkdir -p temp/temp_234/admin/templates/shop-order
|
||||
|
||||
# Skopiuj pliki
|
||||
cp autoload/admin/controls/class.ShopOrder.php temp/temp_234/autoload/admin/controls/
|
||||
cp admin/templates/shop-order/order-details.php temp/temp_234/admin/templates/shop-order/
|
||||
|
||||
# Utwórz ZIP z ZAWARTOŚCI folderu (ważne: wejdź do folderu i spakuj '*')
|
||||
cd temp/temp_234
|
||||
powershell -Command "Compress-Archive -Path '*' -DestinationPath '../ver_0.234.zip' -Force"
|
||||
|
||||
# Wróć i usuń folder tymczasowy
|
||||
cd ..
|
||||
rm -rf temp_234
|
||||
```
|
||||
|
||||
### Poprawna struktura ZIP:
|
||||
```
|
||||
ver_0.234.zip
|
||||
├── admin/
|
||||
│ └── templates/
|
||||
│ └── shop-order/
|
||||
│ └── order-details.php
|
||||
└── autoload/
|
||||
└── admin/
|
||||
└── controls/
|
||||
└── class.ShopOrder.php
|
||||
```
|
||||
|
||||
### NIEPOPRAWNA struktura (do uniknięcia):
|
||||
```
|
||||
ver_0.234.zip
|
||||
└── ver_0.234/ <-- tego folderu NIE powinno być!
|
||||
├── admin/
|
||||
└── autoload/
|
||||
```
|
||||
Reference in New Issue
Block a user