Row-to-item mapping modules¶
The historical includes/mapping/row-to-item-core.php path is now a compatibility facade. Runtime loading goes through includes/mapping/row-to-item/90-compose.php.
Current runtime structure¶
Load order is intentionally explicit:
10-foundation.php15-input-context.php20-media.php25-links.php30-category.php35-offer-state.php40-classification.php45-identity.php50-core.php
90-compose.php owns this load order.
Module responsibilities¶
10-foundation.phpowns reusable row-access and source-feed normalization primitives.15-input-context.phpowns source normalization, provider detection, merchant/seller/marketplace resolution, raw EAN/title acquisition, accessory/title/price guards, shipping, prepared-feed network authority, and merchant-id fallback policy.20-media.phpowns media/gallery acquisition: main image resolution, indexed AWIN/Darty fallbacks, alternate images, gallery JSON/count, and the historical Acer delivery-time payload.25-links.phpowns offer URL/product-id acquisition: feed link candidates, URL precedence, missing-URL guard, merchant product-id fallback, AWIN product-id guard, and deterministic non-AWIN product-id fallback.30-category.phpowns category/raw-field acquisition, Effinity category capture, multi-feed category-path enrichment, and the historical out-of-scope guard.35-offer-state.phpowns the offer-state payload: custom fields, legacy spec hints, condition normalization, old-price/savings normalization, normalized EAN, probable spec type, row metadata, and Effinity raw attributes. It retains the historical Acer RRP/indexed-price fallback.40-classification.phpowns the vertical-selection/classifier pipeline, category vertical routing, soft-review fallback, quality checks, and the historical narrow Acer vertical-skip bypass.45-identity.phpowns identity construction, Effinity no-EAN fallback identity, and the historical PC-Portable.net no-EAN exception.50-core.phpis now the orchestration layer. It delegates input context, media, links/product ids, category, offer state, classification, identity, then final-row construction while preserving historical drop/guard ordering.90-compose.phpowns module loading and keeps the compatibility boundary stable.
Entrypoints and compatibility¶
20-row-to-item.php remains the mapping entry loader and delegates to the composer. Direct callers of the historical row-to-item-core.php path remain supported through the compatibility facade.
The public runtime function remains ccx_feeds_row_to_item().
Delegation order¶
The effective high-level orchestration is:
input context -> media -> links/product ids -> category -> offer state -> classification -> identity -> final row builder
The extracted responsibilities are no longer duplicated inline in 50-core.php; the boundary contracts explicitly protect against those historical blocks drifting back into the core.
Merchant and provider exceptions¶
Merchant/provider exceptions remain explicit and narrow:
- input context retains Electro Depot, Certideal, PC-Portable.net and Darty guard behavior;
- media retains the Acer indexed delivery-time payload;
- category retains Effinity hierarchy behavior;
- offer state retains the Acer RRP/indexed-price fallback and Effinity raw-attribute capture;
- classification retains the Acer main-product bypass;
- identity retains Effinity fallback identity plus the PC-Portable.net EAN exception.
Runtime contracts¶
tests/Runtime/RowToItemCoreBoundaryContractTest.php locks the compatibility facade, composer order, extracted module surfaces, provider/merchant exceptions, and delegation order.
tests/Runtime/RowToItemInputBoundaryContractTest.php locks the input-context and link/product-id boundaries.
tests/Runtime/PreparedFeedNetworkAuthorityContractTest.php locks prepared-feed catalogue network authority in the extracted input-context module.
The full PHPUnit suite and the repository audit remain the final regression gates after structural changes.