Skip to content

fix(manager): formatRow без несуществующего id и сохранение доп. категорий товара (#238)#258

Merged
biz87 merged 1 commit into
betafrom
fix/manager-category-options-save-categories
May 17, 2026
Merged

fix(manager): formatRow без несуществующего id и сохранение доп. категорий товара (#238)#258
biz87 merged 1 commit into
betafrom
fix/manager-category-options-save-categories

Conversation

@biz87
Copy link
Copy Markdown
Member

@biz87 biz87 commented May 17, 2026

Перенос (с ребейзом) PR #240 от @Ibochkarev — оригинальная ветка в форке автора отставала от `beta` и конфликтовала по `CHANGELOG.md` после мержа PR #245 / #253 / #254 / #256. Сам фикс автора оставлен без изменений.

Что в этом PR

3 файла, +24/−4 поверх актуального `beta`. Один коммит, авторство @Ibochkarev сохранено.

Два связанных бага

1. PHP Warning `Undefined array key "id"` в списке опций категории

`msCategoryOption` имеет составной первичный ключ `(category_id, option_id)` — отдельного поля `id` в таблице нет. В выборке списка тоже нет колонки `id`. На PHP 8+ обращение к `$row['id']` в `CategoryOptionsController::formatRow()` бросает warning.

Фикс: проверка через `array_key_exists('id', $row)`, fallback на `option_id` (в рамках одной категории уникален; Vue-грид и так использует `data-key="option_id"`).

```php
$categoryId = (int)($row['category_id'] ?? 0);
$optionId = (int)($row['option_id'] ?? 0);
$rowId = array_key_exists('id', $row) ? (int)$row['id'] : $optionId;
```

2. Сохранение товара без открытия вкладки «Категории» обнуляло доп. категории

В Vue-админке вкладка «Категории» рендерится lazy — скрытое поле `categories` появляется в форме только после её монтирования. Если пользователь сохранил товар, не открыв вкладку, в POST ключа `categories` нет.

Раньше `ProductDataService::saveCategories()` трактовал отсутствие ключа как «пустой массив» → `removeCollection` чистил все доп. категории. Серьёзный data-loss.

Фикс: при отсутствии `categories` в `_fields` — `return` без изменений. Тот же контракт, что у `saveLinks()`.

```php
if (!array_key_exists('categories', $fields)) {
return; // не очищаем без явной команды
}
```

Что разрешено при ребейзе

  • Конфликт в `CHANGELOG.md` — содержимое PR объединено в существующий блок `## Май 2026 → ### Разработка → #### 🐛 Исправлено` рядом с уже мерженными пунктами. Исходная структура автора (`### [2026-05-08] / #### Исправлено / 📁 Изменённые файлы`) переформатирована под единый стиль раздела. Добавлена явная пометка про изменение контракта (см. ниже).

Внимание — изменение контракта

⚠️ Интеграции, сознательно полагавшиеся на «нет `categories` в POST → очистить связи», должны теперь передавать пустой массив явно. Это поведение было неочевидным и опасным (data-loss при стандартном сохранении товара), новое — соответствует контракту `saveLinks()`. В CHANGELOG добавлена явная пометка.

Тип релиза

PATCH с тонким contract-change. В минор 1.11.0-beta1.

Тестирование

  • PHPStan на изменённых файлах — 0 ошибок.
  • Файлы синхронизированы на dev-сайт.
  • Ручная проверка:
    • Баг 1: Открыть категорию → вкладка «Опции» → список опций. На PHP 8+ в логах MODX не должно быть warning'ов про `Undefined array key "id"`.
    • Баг 2: Открыть товар → НЕ открывая вкладку «Категории», поменять любое поле и сохранить. Доп. категории товара (привязки через `msCategoryMember`) сохраняются. После открытия вкладки и явного изменения — синхронизация работает как раньше.

Связанные

…ние доп. категорий без POST-поля

CategoryOptionsController: для ответа API не обращаться к отсутствующему столбцу id у msCategoryOption.
ProductDataService::saveCategories: при отсутствии ключа categories в POST не очищать msCategoryMember (как saveLinks).

Closes GH-238
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Warning formatRow id в CategoryOptionsController и потеря доп. категорий товара при save

2 participants