Skip to content

fix(product): сохранение Data и extra fields в процессорах Create/Update#298

Open
Ibochkarev wants to merge 2 commits into
betafrom
fix/297-product-data-payload
Open

fix(product): сохранение Data и extra fields в процессорах Create/Update#298
Ibochkarev wants to merge 2 commits into
betafrom
fix/297-product-data-payload

Conversation

@Ibochkarev
Copy link
Copy Markdown
Member

@Ibochkarev Ibochkarev commented May 24, 2026

Описание

Исправляет #297: поля msProductData (включая Object Extension / extra fields, например ext_id) не сохранялись при вызове runProcessor с блоком Data или плоскими ключами (price, …).

Причина (две части):

  1. Resource\Create|Update вызывают $object->fromArray($properties) без ignoreInvalid — колонки msProductData не попадают на объект.
  2. На Create composite Data требует id ресурса; запись в beforeSave() не гарантирует persist price и extra fields.

Решение:

  • Trait ProductDataPayloadTrait: захват Data в beforeSet(), whitelist через getDataFieldsNames(), loadMap() для extra fields.
  • UpdateapplyProductDataPayload() в beforeSave().
  • CreatepersistProductDataPayload() в afterSave() после insert ресурса.
  • Alias-классы msProductCreateProcessor / msProductUpdateProcessor для резолвера Resource\Create|Update::getInstance() (импорт CSV, интеграции).

Поддерживаются плоские ключи в корне payload и явный блок Data (при конфликте побеждает Data).

Тип изменений

  • Исправление бага (non-breaking change)
  • Новая функциональность (non-breaking change)
  • Breaking change (изменение, ломающее обратную совместимость)
  • Рефакторинг (без изменения функциональности)
  • Документация
  • Другое (опишите):

Связанные Issues

Closes #297

Как это было протестировано?

  • Ручное тестирование
  • Автоматические тесты (PHPStan, ESLint)
  • Тестирование на разных версиях PHP/MODX

Конфигурация тестирования:

  • MiniShop3: dev / beta
  • MODX: 3.x
  • PHP: php -l для изменённых PHP-файлов (OK)

Сценарии для ревьюера:

  1. MiniShop3\Processors\Product\Create + Data => ['price' => 5200, 'ext_id' => '…'] — значения в ms3_products.
  2. MODX\Revolution\Processors\Resource\Create + class_key = msProduct — тот же результат (alias-процессор).
  3. Update с блоком Data — поля обновляются.
  4. Плоские price / ext_id в корне payload.
  5. Регрессия: создание/редактирование товара в менеджере (price, options-*).

Пример runProcessor:

$response = $modx->runProcessor('MiniShop3\\Processors\\Product\\Create', [
    'pagetitle' => 'Товар',
    'parent' => 42,
    'class_key' => \MiniShop3\Model\msProduct::class,
    'Data' => [
        'price' => 1990.00,
        'ext_id' => 'SKU-123',
    ],
]);

Скриншоты (если применимо)

До После
price / extra fields не сохранялись через runProcessor на Create сохраняются через Data и плоские ключи после afterSave()

Чеклист

  • Код соответствует стилю проекта
  • Добавлены/обновлены комментарии в сложных местах
  • Изменения не ломают существующую функциональность
  • Лексиконы добавлены на двух языках (ru/en) — не требуется (нет UI-строк)
  • PHPStan проходит без новых ошибок
  • ESLint проходит без ошибок (для JS/Vue изменений) — не затронуто
  • Обновлён CHANGELOG.md (для значимых изменений) — по политике репо, при релизе

Дополнительные заметки

Code review (clean-code / pre-merge)

Сильные стороны:

  • Trait с одной ответственностью, методы короткие, имена раскрывают intent (capture / apply / persist).
  • Whitelist полей через getDataFieldsNames() + array_intersect_key — безопаснее произвольного merge.
  • fromArray(..., true, true) с ignoreInvalid — корректный контракт для extra fields.
  • Разделение Create (afterSave + explicit save) / Update (beforeSave) задокументировано в docblock trait.
  • Alias-процессоры в Model\ — минимальный diff, без дублирования логики.

Замечания (не блокеры, follow-up):

  • persistProductDataPayload() возвращает false и при «нет полей для записи», и при ошибке $productData->save() — в Create::afterSave() результат не проверяется; при сбое save клиент может получить success. Имеет смысл различать noop / failure или проверять return при непустом payload.
  • Невалидная JSON-строка в Data из connector молча игнорируется — для отладки можно log или validation error (низкий приоритет).
  • Автотестов на trait нет — regression только ручной (типично для MODX processors).

Затронутые файлы:

  • Processors/Product/ProductDataPayloadTrait.php (новый)
  • Processors/Product/Create.php, Update.php
  • Model/msProductCreateProcessor.php, msProductUpdateProcessor.php (новые)

MODX Resource processors call fromArray() without ignoreInvalid, so extra
fields and flat msProductData keys were dropped. Add Data payload support
and apply allowed fields in beforeSave() after loadMap().

Closes #297
@Ibochkarev Ibochkarev requested a review from biz87 May 24, 2026 11:11
Move product data payload application to afterSave on Create so price and
extra fields save once the resource id exists; add MODX resolver aliases for
Resource Create/Update and JSON-decoded Data payloads.
@Ibochkarev Ibochkarev changed the title fix(product): поддержка Data и extra fields в процессорах Create/Update fix(product): сохранение Data и extra fields в процессорах Create/Update May 24, 2026
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.

[Feature] кастомные поля msProductData в процессор create product

1 participant