Commit Graph

151 Commits

Author SHA1 Message Date
fba215b372 fix: linki produktow z permutacja atrybutow w feedzie Google (v0.350)
Separator URL miedzy parami attr-val zmieniony z "/" na "_" w generatorze
feedu (ProductRepository::appendCombinationToXml). Wzorzec routingu
pp_routes rozszerzony do [0-9_-]+ w Helpers::htacces (oba warianty:
seo_link i fallback p-id-name). LayoutEngine konwertuje "_" -> "|"
przed wywolaniem ProductRepository::findCached — format DB pozostaje "|".
Partial product-attribute.php preselectuje wartosc z permutation_hash
URL (forced_value_id), co poprawia UX wejscia z linka feedu.

Suita: 834 -> 841 testow (+7), 2330 assertions.

Wymagane akcje na produkcji po deployu: regeneracja pp_routes
(Helpers::htacces), wyczyszczenie klucza pp_routes:all w Redis,
regeneracja google-feed.xml, resubmit feedu w GMC.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-30 01:58:29 +02:00
Jacek
eee22ef1c4 fix: poprawny koszt transportu na /koszyk-podsumowanie
Na podstronie /koszyk-podsumowanie transport z flaga delivery_free=1
byl pokazywany zawsze za 0,00 zl, niezaleznie od wartosci koszyka.
Teraz kontroler wylicza transport_cost_effective i free_delivery_applies
uwzgledniajac prog settings.free_delivery, a szablon uzywa tych kluczy.

- Nowa chroniona metoda ShopBasketController::calculateTransportCostForSummary
- Dodane 6 testow jednostkowych (ShopBasketControllerSummaryViewTest)
- Suita: 834 testy / 2318 assertions OK

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:50:15 +02:00
Jacek
9577d4944a feat: custom labels toggle and inline editing in product list
Adds session-based show/hide toggle for custom labels in admin product list, inline editable fields for custom_label_0..4, and label suggestions with custom entry support. Includes repository/controller updates, UI fixes, tests, and PAUL docs release updates.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 11:09:19 +02:00
Jacek
5b66720f7c fix: scontainers edit saves existing record instead of creating new
Fixes static container admin edit flow by preserving id in hiddenFields and adding route-id fallback during save.
Adds regression tests for edit/create id behavior, updates release docs (changelog/testing/CLAUDE), and appends SonarQube open issues to docs/TODO.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 22:56:14 +02:00
Jacek
1ef6dc9092 fix: Custom fields delete bug — usunięcie wszystkich pól produktu nie działało
Dodano hidden marker custom_field_name_present w formularzu edycji produktu.
Zmieniono warunek w ProductRepository z array_key_exists('custom_field_name')
na array_key_exists('custom_field_name_present') — jQuery .serialize() pomijał
klucz pustej tablicy gdy wszystkie pola usunięte. Test jednostkowy dodany.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 22:51:57 +02:00
Jacek
e7b058c275 fix: Checkout flow — summaryView redirect fix + TTL token + order logging
- Usunięty błędny guard w summaryView() blokujący kolejne zamówienia
- Token zamówienia z jednorazowego na TTL 30 min (multi-tab safe)
- Logowanie błędów zamówień do logs/logs-order-YYYY-MM-DD.log
- Redirect przy złym tokenie na /koszyk-podsumowanie zamiast /koszyk
- Double-submit guard przeniesiony przed sprawdzenie tokena

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:32:46 +01:00
Jacek
ae016e362b feat: edycja personalizacji produktu w koszyku
Nowa metoda basketUpdateCustomFields() w ShopBasketController — AJAX endpoint
z walidacją required fields, przeliczaniem product_code (MD5 hash) i merge
duplikatów. UI: przycisk "Edytuj personalizację" + formularz inline + JS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 19:45:02 +01:00
Jacek
131c26799f fix: custom fields - type/is_required przy kopiowaniu produktu + obsługa obrazków w koszyku
ProductRepository: kopiowanie custom fields uwzględnia pola type i is_required.
product-custom-fields.php: ochrona XSS, obsługa pola image, fallback typu na text.
SonarQube 0.343: nowe issues dodane do TODO.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:36:54 +01:00
Jacek
72864d18ba fix: Apilo email z danymi zamówienia + infinite retry co 30 min dla order jobów
- Email notyfikacji zawiera numer zamówienia, klienta, datę, kwotę
- Order joby (send_order, sync_payment, sync_status) ponawiane w nieskończoność co 30 min
- Rozróżnienie PONAWIANY vs TRWAŁY BŁĄD w emailu
- Cleanup stuck jobów po udanym wysłaniu zamówienia
- +2 testy infinite retry w CronJobRepositoryTest

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 11:23:02 +01:00
Jacek
b3233497f0 fix: naprawiono crash przy składaniu zamówienia z kuponem rabatowym
Fatal Error: Call to undefined method stdClass::is_one_time() w OrderRepository:793.
Zamieniono wywołania nieistniejących metod na stdClass na dostęp do właściwości
+ istniejącą metodę CouponRepository::markAsUsed().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:04:18 +01:00
Jacek
596f5baac1 refactor: wydzielenie ApiloRepository z IntegrationsRepository
IntegrationsRepository zredukowany z ~875 do ~340 linii.
Nowa klasa ApiloRepository przejmuje 19 metod apilo*.
Konsumenci (IntegrationsController, OrderAdminService, cron.php) zaktualizowani przez DI.
Suite: 818 testów, 2275 asercji.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 11:52:00 +01:00
Jacek
d6842503cb fix: duplikaty zamowien + status COD (is_cod flag)
- summaryView(): guard — redirect do istniejacego zamowienia gdy ORDER_SUBMIT_LAST_ORDER_ID w sesji
- basketSave(): try-catch wokol createFromBasket(), wyjatki logowane, koszyk zachowany
- OrderRepository: usunieto hardkodowane payment_id == 3, uzywana flaga is_cod
- PaymentMethodRepository: nowe pole is_cod w normalizacji, save() i forTransport() SQL
- ShopPaymentMethodController: switch "Platnosc przy odbiorze" w formularzu edycji
- migrations/0.338.sql: ALTER TABLE pp_shop_payment_methods ADD COLUMN is_cod

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 11:00:23 +01:00
Jacek
0677e75b25 security: faza 4 - ochrona CSRF panelu administracyjnego
- Nowa klasa \Shared\Security\CsrfToken (generate/validate/regenerate)
- Token CSRF we wszystkich formularzach edycji (form-edit.php)
- Walidacja CSRF w FormRequestHandler::handleSubmit()
- Token CSRF w formularzu logowania i formularzach 2FA
- Walidacja CSRF w App::special_actions() dla żądań POST
- Regeneracja tokenu po udanym logowaniu (bezpośrednia i przez 2FA)
- Fix XSS: htmlspecialchars na $alert w unlogged-layout.php
- 7 nowych testów CsrfTokenTest (817 testów łącznie)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 10:06:40 +01:00
Jacek
3894f34fc2 security: faza 3 - error handling w krytycznych sciezkach
- cron.php: przywrocono E_WARNING i E_DEPRECATED (wyciszono tylko E_NOTICE i E_STRICT)
- IntegrationsRepository: try-catch po zapisie tokenow Apilo - blad DB nie sklada false po cichu
- ProductRepository/ArticleRepository: error_log gdy safeUnlink wykryje sciezke poza upload/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 09:30:23 +01:00
Jacek
f994e25214 security: faza 2 - safeUnlink() i escaping XSS w szablonach artykulow
- ProductRepository: dodano safeUnlink() z walidacja realpath() - zapobiega path traversal
- ArticleRepository: to samo, 4 metody usuwania plikow zaktualizowane
- templates/articles/article-full.php: htmlspecialchars() na tytule, SERVER_NAME i $url
- templates/articles/article-entry.php: htmlspecialchars() na tytule i $url (3 miejsca)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 09:22:32 +01:00
Jacek
7c7d587886 security: faza 1 - usuniecie debug logu tpay, naprawa SQL i usun rb.php
- ShopOrderController: usunieto file_put_contents do tpay.txt (ujawnial dane platnicze)
- ShopOrderController: hardcoded sekret HotPay przeniesiony do stałej HOTPAY_HASH_SEED
- IntegrationsRepository: zastapiono raw SQL query('SELECT * FROM $table') metodą Medoo select()
- index.php + admin/index.php: usunieto RedBeanPHP (rb.php) - biblioteka byla ladowana ale nieuzywana
- libraries/rb.php: usunieto plik (536 KB, zero uzyc w kodzie aplikacji)
- Testy IntegrationsRepository zaktualizowane do nowego API (select zamiast query)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-12 09:18:37 +01:00
Jacek
fe39f49175 feat: ochrona przed podwójnym składaniem zamówienia (order submit token)
Token CSRF w sesji zapobiega duplikowaniu zamówień przy wielokrotnym
kliknięciu przycisku. Przy duplikacie przekierowanie do istniejącego
zamówienia. JS naprawiony — nasłuch na submit formularza zamiast click.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 21:50:21 +01:00
Jacek
942633dd93 feat: API produktów - nowe pola new_to_date i additional_message (v0.332)
- ProductRepository::getProductForApi() eksportuje new_to_date, additional_message,
  additional_message_required, additional_message_text
- ProductsApiController obsługuje te pola w PUT/PATCH
- Zaktualizowana dokumentacja API.md i CHANGELOG

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 22:08:12 +01:00
Jacek
92a4e1051c update 2026-03-01 00:58:14 +01:00
Jacek
4507c4595e fix: getProductLayout używał layoutu kategorii zamiast domyślnego (v0.331)
Fallback w LayoutsRepository::getProductLayout() zmieniony z
categories_default=1 na status=1 — produkty bez przypisanego layoutu
pobierają teraz właściwy domyślny szablon zamiast szablonu kategorii.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-01 00:42:41 +01:00
a8175c0944 feat: eliminate htaccess.conf, move all URL routes to pp_routes (v0.329-0.330)
- Add category_id, page_id, article_id, type columns to pp_routes (migration 0.329)
- Move routing block in index.php before checkUrlParams() with Redis cache
- Routes for categories, pages, articles now stored in pp_routes instead of .htaccess
- Delete category/page/article routes on entity delete in respective repositories
- Eliminate libraries/htaccess.conf: generate .htaccess content entirely from PHP
- Move 32 static system routes (koszyk, logowanie, newsletter, AJAX modules, etc.)
  plus dynamic language/producer routes to pp_routes with type='system'
- Invalidate pp_routes Redis cache on every htacces() regeneration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 22:06:33 +01:00
c61708448d feat: bulk delete in product archive (v0.327)
- Add bulk_delete_permanent() endpoint (POST ids[], returns JSON)
- Checkbox column + bulk action bar with count label
- Select-all in table header, confirmation dialog before delete
- 2 new tests for bulk_delete_permanent method signature

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 20:37:22 +01:00
8c642d81f1 fix: remove dead CategoryRepository param, fix N+1 queries in categories/list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 18:54:48 +01:00
8d993e7450 feat: add categories/list API endpoint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-27 18:51:26 +01:00
0d31931295 Add configuration for cron key and document code style conventions
- Added cron key to config.php for scheduled tasks.
- Created code_style_and_conventions.md to outline PHP version, file naming, DI pattern, controller wiring, Medoo ORM pitfalls, test conventions, caching, and database structure.
- Added project_overview.md detailing the purpose, tech stack, architecture, entry points, and key classes of the shopPRO project.
- Introduced suggested_commands.md for testing and system utilities commands.
- Added task_completion_checklist.md for a structured approach to completing tasks.
- Included .DS_Store files in autoload and templates directories for macOS compatibility.
2026-02-27 14:57:02 +01:00
66263440bb fix: broken SQL in update manifests — line-by-line instead of complete statements
build-update.ps1 was reading SQL migrations line-by-line, causing
multi-line CREATE TABLE/INSERT statements to be stored as fragments
in manifests. Fixed to strip comments, join lines, and split by
semicolons. Fixed ver_0.324_manifest.json with correct SQL statements.
Added try-catch in UpdateRepository to prevent fatal crashes on SQL errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:48:08 +01:00
bab273b7a5 feat: database-backed cron job queue replacing JSON file system
Replace file-based JSON cron queue with DB-backed job queue (pp_cron_jobs,
pp_cron_schedules). New Domain\CronJob module: CronJobType (constants),
CronJobRepository (CRUD, atomic fetch, retry/backoff), CronJobProcessor
(orchestration with handler registration). Priority ordering guarantees
apilo_send_order (40) runs before sync tasks (50). Includes cron.php auth
protection, race condition fix in fetchNext, API response validation,
and DI wiring across all entry points. 41 new tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:29:11 +01:00
4cbe1c2cb8 feat: add language backend configuration and update documentation
- Added `language_backend` option to project.yml for specifying the language backend (LSP or JetBrains).
- Updated CLAUDE.md with a note on downloading log files from the FTP server.
- Removed unnecessary .DS_Store files from autoload and templates directories.
- Deleted outdated log files from the logs directory.
2026-02-24 21:14:14 +01:00
5b585ceba0 ver. 0.323: fix import zdjęć, trwałe usuwanie produktów, fix API upload path
- IntegrationsRepository: refactor importu zdjęć — walidacja HTTP, curl timeouty, logi, czytelny komunikat
- ProductRepository: saveCustomFields tylko gdy klucz istnieje (partial API update), delete() czyści custom_fields
- ProductArchiveController: przycisk i metoda delete_permanent() do trwałego usunięcia z archiwum
- ProductsApiController: fix ścieżki upload (api.php działa z rootu projektu)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:05:23 +01:00
2c663e740b ver. 0.322: fix custom_fields — jawne mapowanie kluczy w ProductRepository, spójne !empty w ProductsApiController
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 14:11:50 +01:00
6cf7b46584 ver. 0.321: API produkty — obsługa custom_fields w create/update
- ProductsApiController: parsowanie custom_fields z body (name, type, is_required)
- Zaktualizowano docs/API.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:54:33 +01:00
b6ed72205b ver. 0.320: API słowniki — ensure_producer; ProductRepository — producer_name w odpowiedzi
- DictionariesApiController: nowy endpoint POST ensure_producer (znajdź lub utwórz producenta)
- ProducerRepository: metoda ensureProducerForApi()
- ProductRepository: pole producer_name w odpowiedzi GET product
- ApiRouter: wstrzyknięto ProducerRepository do DictionariesApiController
- Zaktualizowano docs/API.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 13:32:25 +01:00
e6c8bdf63f ver. 0.319: usunięcie shopPRO eksportu produktów + rozszerzenie API o custom_fields i security_information
- Usunięto shopproExportProduct() z IntegrationsRepository
- Usunięto shoppro_product_export() z IntegrationsController
- Usunięto przycisk "Eksportuj do shopPRO" z ShopProductController
- ProductRepository: dodano custom_fields i security_information do odpowiedzi API
- Zaktualizowano docs/API.md i testy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 12:29:13 +01:00
33d37d455e ver. 0.318: shopPRO export produktów + nowe API endpoints
- NEW: IntegrationsRepository::shopproExportProduct() — eksport produktu do
  zdalnej instancji shopPRO (pola główne, tłumaczenia, custom fields, zdjęcia)
- NEW: sendImageToShopproApi() — wysyłka zdjęć przez API shopPRO (base64 POST)
- REFACTOR: shopproImportProduct() — wydzielono shopproDb() i
  missingShopproSetting(); dodano security_information, producer_id,
  custom fields, alt zdjęcia
- NEW: AttributeRepository::ensureAttributeForApi() i
  ensureAttributeValueForApi() — idempotent find-or-create dla słowników
- NEW: API POST dictionaries/ensure_attribute — utwórz lub znajdź atrybut
- NEW: API POST dictionaries/ensure_attribute_value — utwórz lub znajdź wartość
- NEW: API POST products/upload_image — przyjmuje base64, zapisuje plik i DB
- NEW: IntegrationsController::shoppro_product_export() — akcja admina
- NEW: przycisk "Eksportuj do shopPRO" w liście produktów
- NEW: pole API key w ustawieniach integracji shopPRO

Tests: 765 tests, 2153 assertions — all green

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 11:43:17 +01:00
0fb09f2bae ver. 0.317: klucz API — przycisk generowania + fix zapisu
- fix: api_key brakowało w whiteliście saveSettings() — wartość tracona przy zapisie
- feat: przycisk "Generuj" losowy 32-znakowy klucz, usunięto "(ordersPRO)" z nazwy
- fix: api.php routing przeniesiony przed global settings + Throwable error handling
- fix: ApiRouter catch Throwable zamiast Exception

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 23:30:41 +01:00
25165881f7 ver. 0.315: fix PDOException w listowaniu atrybutów admin
AttributeRepository::listForAdmin() przekazywał :default_lang_id
do zapytania COUNT które nie używało tego parametru — PDO zgłaszał
SQLSTATE[HY093]: Invalid parameter number.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 17:51:37 +01:00
aa2761aaf5 ver. 0.314: fix wyszukiwarki admin + title zamówienia
- Fix: globalna wyszukiwarka - Content-Type, Cache-Control, POST,
  FETCH_ASSOC, try/catch wrapper
- New: document.title w szczegółach zamówienia = numer zamówienia

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 12:32:54 +01:00
ba67f3a59c ver. 0.313: fix sync płatności Apilo + logowanie decyzji sync
Fix: (int) cast na apilo_order_id (format "PPxxxxxx") dawał 0, przez co
syncApiloPayment() i syncApiloStatus() pomijały wywołanie API Apilo.
Zmiana na empty() w obu metodach.

New: logowanie ApiloLogger w syncApiloPaymentIfNeeded() i
syncApiloStatusIfNeeded() — każda ścieżka decyzyjna zapisuje wpis
do pp_log z kontekstem.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 11:44:11 +01:00
7d223959c8 ver. 0.311: fix race condition Apilo + persistence filtrów + poprawki cen
- Fix: race condition callback płatności przed wysłaniem do Apilo
- Fix: processApiloSyncQueue czeka na apilo_order_id zamiast usuwać task
- Fix: drugie wywołanie processApiloSyncQueue po wysyłce zamówień w cronie
- Fix: ceny w szczegółach zamówienia (effective price zamiast 0 zł)
- New: persistence filtrów tabel admin (localStorage)
- Testy: 760 tests, 2141 assertions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 10:50:34 +01:00
96be27c938 ver. 0.310: logi integracji w panelu admin
Nowa zakladka "Logi" w sekcji Integracje - podglad tabeli pp_log
z paginacja, sortowaniem, filtrami i rozwijalnym kontekstem JSON.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:54:09 +01:00
a655b2a302 ver. 0.309: ApiloLogger + cache-busting CSS/JS + poprawki UI
- ApiloLogger: logowanie operacji Apilo do pp_log z kontekstem JSON
- Cache-busting: ?ver=filemtime() dla CSS i JS w admin main-layout
- Fix: inicjalizacja $mdb przed SettingsRepository w admin/index.php
- Fix: rzutowanie (string) w ShopProductController::escapeHtml()
- UI: text-overflow ellipsis dla kategorii produktow + title tooltip
- JS: navigator.clipboard API w copyToClipboard() z fallbackiem
- CSS: uproszczenie .site-content, usuniecie .with-menu
- Migracja: pp_log + kolumny action, order_id, context

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:31:28 +01:00
23fe47e4f6 ver. 0.308: kolory statusow zamowien + poprawki bezpieczenstwa
- Kolorowe badge statusow na liscie zamowien (pp_shop_statuses.color)
- Walidacja hex koloru z DB (regex), sanityzacja HTML transport
- Polaczenie 2 zapytan SQL w jedno orderStatusData()
- Path-based form submit w table-list.php (admin URL routing)
- 11 nowych testow (750 total, 2114 assertions)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 20:57:56 +01:00
f1e58d5e14 ver. 0.307: check-update button + auto-generated changelog
- Add "Sprawdź aktualizacje" refresh button in admin sidebar (AJAX check without page reload)
- Add UpdateController::checkUpdate() action clearing session cache and querying update server
- Replace hand-edited changelog.php with auto-generating script (reads manifests + legacy JSON)
- Migrate all legacy changelog entries (0.300-0.001) to changelog-legacy.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 18:01:12 +01:00
04ba93eb9f ver. 0.306: hide transport methods with no available payment methods
When all payment methods for a transport are filtered out by
min_order_amount/max_order_amount limits, the transport is now hidden
from the basket. Prevents showing delivery options with empty payment
method lists (e.g. "Kurier - płatność przy odbiorze" when COD exceeds
max amount).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 17:09:38 +01:00
0d8a70f6e2 fix: UTF-8 BOM in update SQL files causing MariaDB syntax error
PowerShell 5.1 Out-File -Encoding UTF8 adds BOM (EF BB BF) which
breaks SQL execution on production. Also fix manifest JSON serializing
full PS objects instead of plain strings.

- build-update.ps1: use UTF8Encoding($false) for all file writes
- build-update.ps1: force .ToString() on Get-Content results
- UpdateRepository.php: strip BOM and normalize line endings in executeSql
- Rebuild ver_0.304 package files (clean SQL + manifest)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:49:23 +01:00
fdb1423285 ver. 0.305: Fix permutation attribute sorting + free delivery progress bar
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 16:33:30 +01:00
d6875246bd ver. 0.304: Configurable payment method order amount limits
Replace hardcoded PayPo condition (id=6, 40-1000 PLN) with generic
min/max order amount columns on pp_shop_payment_methods. Admin form
fields added, frontend basket checkout filters dynamically. Cache
invalidation on save. 4 new tests (734 total, 2080 assertions).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:26:51 +01:00
e1f9b3e517 ver. 0.303: Fix attribute display collision + product preview button
Fix: product attributes with the same sort order value were overwriting
each other in getProductAttributes(), causing only one attribute to
display on the frontend. Now uses usort() with sequential keys.

New: Preview button in product edit form opens product page in new tab.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 15:04:51 +01:00
6fdbe61916 ver. 0.302: REST API product variants, attributes dictionary, attribute filtering
- Add variant CRUD endpoints (variants, create_variant, update_variant, delete_variant)
- Add dictionaries/attributes endpoint with multilingual names and values
- Add attribute_* filter params for product list filtering by attribute values
- Enrich product detail attributes with translated names (attribute_names, value_names)
- Include variants array in product detail response for parent products
- Add price_brutto validation on product create
- Batch-load attribute/value translations (4 queries instead of N+1)
- Add 43 new unit tests (730 total, 2066 assertions)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-22 14:42:52 +01:00
0c3b87d831 ver. 0.300: Manifest-based update system with checksum verification and file backup
Replaces the manual ZIP packaging workflow with an automated build script.
UpdateRepository now supports both manifest JSON format (new) and legacy
_sql.txt/_files.txt format (fallback), enabling a smooth transition for
existing client instances.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 23:30:58 +01:00