Перенести каталог ~58 000 товаров в интернет-магазин сантехники на CS-Cart из одной CSV-выгрузки: описания, фото, характеристики в карточку и в фильтры, вложенные категории. Штатный импортёр CS-Cart берёт простые поля, но на сложной логике (характеристики → фильтры по уровням категорий, идемпотентный повторный импорт, тысячи изображений) требует ручной доводки на каждой итерации.
Написал PHP-скрипт с бутстрапом init.php — он поднимает окружение CS-Cart и пишет через функции ядра, без прямого доступа к таблицам и рассинхрона связанных сущностей.
Категории: резолв пути из трёх уровней, авто-создание недостающих узлов с parent_id, переиспользование существующих. Товары: upsert по артикулу (product_code) через fn_update_product — повторная выгрузка обновляет, а не плодит дубли. Характеристики: парс плоского поля «Название: Значение», создание и привязка значений к товару.
Отдельное решение по фильтрам: фильтруемые характеристики привязаны к категории 2-го уровня, первый уровень без фильтров, третий — только для определения подкатегории. CS-Cart прячет пустые фильтры, поэтому в каждой подкатегории покупатель видит только релевантные. Изображения — парс списка путей и привязка к товару; ~180 товаров без фото вынесены в отчёт, а не уронили импорт. Скрипт ведёт лог и сводный отчёт (создано/обновлено/пропущено), валидирует пустые поля.
~58 000 товаров в каталоге с описаниями, фото, характеристиками и фильтрами; вложенная структура категорий; характеристики работают и в карточке, и как фильтры по подкатегориям. Прогон идемпотентен — импорт можно гонять итеративно по мере обновления источника, без дублей.
Честно про ограничение: скрипт заточен под схему этой выгрузки (набор колонок, формат характеристик) — под другой источник маппинг перенастраивается. Это инструмент проекта, а не универсальный импортёр.