Skip to content

Commit 7915dde

Browse files
authored
Merge pull request #292 from modx-pro/release/1.11.0-beta1
release: 1.11.0-beta1
2 parents 3a07663 + 8014435 commit 7915dde

4 files changed

Lines changed: 56 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,25 @@
3535

3636
#### 🐛 Исправлено
3737

38+
**Дублирование товаров при `includeThumbs` (#281):**
39+
- В сниппетах `msProducts`, `msCart`, `msGetOrder` LEFT JOIN превью выбирал все картинки галереи товара — `GROUP BY` по URL размножал первую строку столько раз, сколько фото в галерее.
40+
- Новый общий хелпер `MiniShop3\Utils\ProductThumbnailJoin::buildLeftJoinOn()` формирует SQL ON: одно превью на товар (превью главного фото — `parent_id = 0`, минимальный `position`), аналогично `ProductImageService::updateProductImage()`. Алиасы и size-папка санитизируются.
41+
- Попутно исправлена опечатка `parent``parent_id` в `msGetOrder` (нет такого поля в `ms3_product_files`, JOIN тихо игнорировался).
42+
43+
**Дерево категорий в UI привязки опций — поддержка вложенного каталога и мульти-магазина (#237):**
44+
- `OptionsController::getTree` отдаёт на каждом уровне `msCategory` (выбираемые, с чекбоксом) и `modResource`/`modDocument`/`modWebLink` с `isfolder=1` (навигационные, без чекбокса). `msProduct` и обычные страницы без `isfolder` исключаются.
45+
- В ответе для каждого узла появился флаг `selectable: bool` — Vue `OptionCategoryTree` рендерит чекбокс только для `selectable=true`, навигационные узлы можно раскрывать, но не выбирать.
46+
- Системная настройка `ms3_option_category_tree_parent` (была введена в первой попытке) **удалена** — дерево работает на семантике ресурсов, без необходимости в фиксированном root-id.
47+
48+
**Очистка числовых полей доставки/оплаты не сохранялась:**
49+
- В формах настроек способов доставки и оплаты при попытке очистить поле (например, `free_delivery_amount`) старое значение оставалось в БД. Ввод явного `0` сохранялся правильно.
50+
- Причина — `isset($data[$field])` в `DeliveriesController` / `PaymentsController` возвращал `false` для значения `null` (PrimeVue `InputNumber` при очистке шлёт `null`), и поле пропускалось при сохранении. Заменено на `array_key_exists($field, $data)`.
51+
- Аналогичный паттерн в других контроллерах Manager API зафиксирован в issue #289.
52+
53+
**Импорт товаров — поддержка поля «Остаток на складе» (#283):**
54+
- В конфигурации импорта (`config/import-fields.php`) добавлены поля `stock` и `remains` (алиас MS2). При обработке CSV `ImportCSV` маппит `remains``stock` для совместимости с легаси-настройками `ms3_utility_import_fields`.
55+
- В Vue-форме маппинга автоподстановка типичных заголовков CSV (`stock`, `remains`, `quantity`, `qty`) → товарное поле `stock`.
56+
3857
**Двойной префикс в Phinx defensive-checks из PR #271 (#276):**
3958
- `TablePrefixAdapter::hasTable($name)` / `$this->table($name)` / `hasColumn` сами добавляют `table_prefix`. Ручной конкат `$prefix . 'ms3_grid_fields'` в defensive-проверках после #271 приводил к двойному префиксу (`modx_modx_*`) — Phinx никогда не находил таблицу и seed-миграции всегда уходили в no-op.
4059
- **Воздействие**: на свежих установках MS3 ≥ 1.10.1 таблица `ms3_grid_fields` создавалась, но не наполнялась — гриды (заказы, клиенты, доставки, оплаты, вендоры, позиции заказа, товары категории) загружались без default-конфигурации. На существующих установках, где seed успел выполниться до #271, последствий нет.

_build/config.inc.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
'name' => 'MiniShop3',
1313
'name_lower' => 'minishop3',
1414
'name_short' => 'ms3',
15-
'version' => '1.10.1',
15+
'version' => '1.11.0',
1616
'release' => 'beta1',
1717
// Install package to site right after build
1818
'install' => false,

core/components/minishop3/docs/changelog.txt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,41 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.11.0-beta1]
9+
10+
### Added
11+
- New `msOptionGroup` model replaces `modCategory` for grouping product options (#10). Migration converts existing `msOption.modcategory_id` → `option_group_id` automatically (each distinct `modcategory_id` becomes a row in `ms3_option_groups` using `modCategory.category` as name). Admin: separate "Option Groups" tab next to "Options" with CRUD, drag-and-drop ordering, options-per-group counter.
12+
- Public `window.ms3.refresh()` storefront JS API and `ms3:refresh` DOM event (#274) for integration with third-party AJAX components that replace catalog DOM (mFilter / mSearch2 / custom AJAX / infinite scroll). The component dispatches `ms3:refresh` after its DOM swap — MS3 re-binds `ProductCardUI` / `QuantityUI` state. MS3 does NOT listen for vendor-specific events; dependency direction is component-→-MS3.
13+
- Manager API endpoint `POST /api/mgr/orders/{id}/recalculate-cost` and "Recalculate cost" button in the order admin (#212). Three modes: `auto` (DefaultDelivery/DefaultPayment by fields, no external provider calls), `manual` (operator-provided `manual_delivery_cost`), `force_provider` (explicit provider call in try/catch). Honours discounts via `PriceAdjustment` and total clamp via `OrderService::clampComputedTotal()`.
14+
- Negative additional cost for delivery and payment methods (#211): the `price` field now accepts fixed discounts (`-10`) and percent discounts (`-10%`). Common normalizer `MiniShop3\Utils\PriceAdjustment` shared between manager API and legacy processors.
15+
- Negative total guard `OrderService::clampComputedTotal(?msOrder, float, float, float = 0.0)` (#265): when sum of cart + delivery + payment costs goes below zero (e.g. misconfigured discounts), total is clamped to 0 and a `LOG_LEVEL_WARN` line with the breakdown is written. Wired into all calculation paths.
16+
- Vue admin: live "Discount" / "Markup" badges on the `price` field of delivery/payment edit forms (#265).
17+
- Validation rules editor for deliveries now lists model fields and Object Extension fields for `msOrder` / `msOrderAddress` (#215) in addition to the static set.
18+
- Order fields tabs: "Configure fields" empty-state hint and conditional action bar visibility on Info / Address tabs (#182).
19+
- Import: product `stock` field is now available in the field mapping (#283), with auto-mapping of typical CSV headers (`stock`, `remains`, `quantity`, `qty`).
20+
- Web API for customer profile: `POST /api/v1/customer/add` (quick profile field update incl. extra fields, #241/#261), `POST /api/v1/customer/changeAddress`, `GET /api/v1/customer/email/verify` (with HTML redirect support), `POST /api/v1/customer/email/resend-verification` (#226).
21+
- System settings: `ms3_email_verification_url`, `ms3_email_verification_success_url` for customizing the email-verification flow.
22+
23+
### Changed (breaking)
24+
- **Storefront snippets — numeric placeholders contract** (#242, breaking). Plain placeholders (`cost`, `cart_cost`, `delivery_cost`, `price`, `weight`, …) are now plain `float` for arithmetic and Fenom `|number`. Display strings with locale / currency / unit live in `*_formatted`. Removed `formatPrices` no-op in `msProducts` and `msOrderTotal`. Migration: change `{$order.cost}` (which used to render `5 300 ₽`) to `{$order.cost_formatted}`, or keep `{$order.cost}` only for arithmetic / `|number`. Affects `msOrder`, `msGetOrder`, `msCart`, `msProducts`, `msOrderTotal`, default `ms3_order.tpl`.
25+
- **Schema — `msOption.modcategory_id` → `msOption.option_group_id`** (#10, breaking for direct DB readers). Data migration is automatic. Custom code reading `modcategory_id` directly must switch to `option_group_id`; the join alias `category_name` in `OptionLoaderService` / `CategoryOptionService` is renamed to `group_name`. Snippet `msProductOptions` filters/sorts by `group_name`.
26+
- **Manager API — `GET /api/mgr/options/modcategories` removed**, replaced by `/api/mgr/option-groups` (CRUD + reorder + bulk delete + per-group options count).
27+
- `msCart` snippet no longer suppresses output on `?msorder=...` by default (#249) — the cart loads and renders the chunk as usual, so mini-cart blocks in the global layout keep working on the "thank you" page. New `hideOnThanks=1` parameter brings back the previous "blank on thanks page" behavior for a specific call.
28+
- `Processors\Product\Update`: option deletion now applies on save (#199 follow-up). Form options are captured in `beforeSet` into `$ms3ProductFormOptions` and passed to `ProductDataService::saveOptions(..., removeOther: true)` after the parent `afterSave` — avoids MODX 3 quirk where the processor's `options` property is often empty post-save.
29+
- `ProductDataService::saveCategories()`: missing `categories` key in the form payload no longer wipes extra category links (#238). Behavior is now symmetric with `saveLinks()` — explicit empty array still clears, but absence of the key (tab not rendered yet) is a no-op. Integrations relying on "no `categories` in POST → clear all" must pass `categories: []` explicitly.
30+
- Web API `POST /api/v1/customer/add` allows all columns present in the `msCustomer` xPDO map (including Object Extension after `loadMap()`), with an explicit denylist of sensitive/system fields (#261). Rakit-validation preserved for `first_name` / `last_name` / `email` / `phone`; other allowed columns are normalized by `phptype`.
31+
32+
### Fixed
33+
- Product duplicate via MODX context menu: option values now copy over to the new product (#257). After `modResource::duplicate()`, `OptionService` re-syncs `ms3_product_options` rows from the source.
34+
- `Processors\Product\Create`: empty option fields no longer wipe options on save. Aligned with `Update` — sync only when the request contained `options-*` keys.
35+
- Plugin events that mutate data via `returnedValues` (#219, #221): `msOnBeforeSendNotification`, `msOnBeforeImport`, `msOnImportRow`, `msOnProductsLoad`, `msOnProductPrepare` apply mutations from the MODX `returnedValues` channel; `Cart::changeOption`, `Customer::validate`, `Customer::getOrCreate`, `OrderStatusService::change`, `OrderUserResolver::getUserId` consume merged `$response['data']` after `invokeEvent`.
36+
- Option category tree for nested catalogs and multi-store setups (#237): tree returns `msCategory` (selectable) plus `modResource`/`modDocument`/`modWebLink` with `isfolder=1` (navigation-only) — no system setting required.
37+
- Product list duplicates on `includeThumbs` (#281): one thumbnail per product via shared `ProductThumbnailJoin` helper in `msProducts`, `msCart`, `msGetOrder`. Fixed `parent` → `parent_id` typo in `msGetOrder`.
38+
- Delivery / payment numeric fields can finally be cleared from the admin form — the controller no longer silently drops `null` values (`isset` → `array_key_exists`).
39+
- Email verification flow: link in the email points to Web API by default (`api.php?route=…/email/verify&token=…&html=1`), with optional custom URL via `ms3_email_verification_url` (#226).
40+
- Phinx defensive checks added in 1.10.x-era seed migrations no longer skip every install due to double `table_prefix` (#276): API methods (`hasTable`, `$this->table()`, `hasColumn`) now receive unprefixed names; raw SQL keeps `{$prefix}name`. Initial schema's foreign-key step also fixed (FK constraints were never being created on fresh installs).
41+
- Many smaller fixes — see project CHANGELOG.md for details.
42+
843
## [1.10.1-beta1]
944

1045
### Fixed

core/components/minishop3/src/MiniShop3.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
class MiniShop3
2222
{
23-
public $version = '1.10.1-beta1';
23+
public $version = '1.11.0-beta1';
2424

2525
/** @var modX $modx */
2626
public $modx;

0 commit comments

Comments
 (0)