Разработка модуля импорта данных 1С-Битрикс
Импорт в 1С-Битрикс — это не просто «загрузить CSV». Это трансформация данных из чужого формата в структуры Битрикса с учётом инфоблоков, торгового каталога, CRM, пользователей. Встроенный импорт есть только для каталога через CommerceML и YML, для всего остального пишут отдельный модуль.
Что предоставляет стандарт и где он заканчивается
Стандартный модуль catalog поддерживает импорт через CSaleImport и класс CDataExchangeXML для CommerceML 2.x. Работает приемлемо для простого каталога. Проблемы начинаются с:
- произвольные форматы (Excel, JSON, XML с нестандартной схемой)
- импорт в несколько инфоблоков одновременно
- обновление существующих записей с логикой слияния полей
- импорт пользователей, заказов, CRM-сущностей
- большие файлы (10 000+ строк) без таймаутов
Архитектура модуля
Модуль vendor.importer строится вокруг трёх абстракций: Reader (читает источник), Transformer (преобразует данные), Writer (записывает в Битрикс).
SourceFile → Reader → RawRow[] → Transformer → MappedRow[] → Writer → Bitrix entities
ReaderInterface:
interface ReaderInterface
{
public function open(string $filePath): void;
public function readNext(): ?array; // null = конец файла
public function getHeaders(): array;
public function close(): void;
}
Реализации: CsvReader, XlsxReader (через PhpSpreadsheet), XmlReader (через XMLReader для потокового чтения больших файлов), JsonReader.
Маппинг полей
Конфигурация маппинга хранится в b_vendor_importer_mapping:
{
"source": "csv",
"target": "catalog_product",
"iblock_id": 5,
"fields": {
"article": "PROPERTY_ARTICLE",
"name": "NAME",
"price": "CATALOG_PRICE_1",
"stock": "CATALOG_STORE_PRODUCT_AMOUNT"
},
"key_field": "article",
"update_strategy": "merge"
}
key_field определяет поле для идентификации существующей записи (артикул, внешний ID, email). update_strategy:
-
merge— обновляет только поля из маппинга, остальные не трогает -
replace— полная замена записи -
skip— пропуск существующих, только новые
Потоковая обработка больших файлов
Импорт 50 000 строк нельзя обработать за один HTTP-запрос. Используем сессионный подход с агентом:
// Шаг 1: загрузка файла, создание задания
$job = ImportJobTable::add([
'FILE_PATH' => $uploadedPath,
'MAPPING_ID' => $mappingId,
'STATUS' => 'pending',
'TOTAL' => 0,
'PROCESSED' => 0,
]);
// Шаг 2: агент читает порциями
public static function processChunk(int $jobId, int $offset, int $limit = 100): string
{
$job = ImportJobTable::getById($jobId)->fetch();
$reader = ReaderFactory::create($job['FILE_PATH']);
$reader->open($job['FILE_PATH']);
// пропускаем offset строк, читаем limit строк
// ...обрабатываем, обновляем PROCESSED
}
Агент вызывается каждую минуту, обрабатывает следующую порцию, обновляет счётчик. Прогресс виден в административном интерфейсе в реальном времени.
Writer: запись в инфоблок
class IblockElementWriter implements WriterInterface
{
public function write(MappedRow $row): WriteResult
{
$existing = $this->findByKey($row->getKeyValue());
if ($existing) {
$result = \CIBlockElement::Update($existing['ID'], $row->toIblockArray());
} else {
$element = new \CIBlockElement();
$result = $element->Add($row->toIblockArray());
}
return new WriteResult($result !== false, $existing ? 'updated' : 'created');
}
}
Аналогичные Writer-классы: CrmLeadWriter (через \Bitrix\Crm\LeadTable), SaleOrderWriter (через \Bitrix\Sale\Order::create()), UserWriter (через \CUser::Add/Update).
Валидация данных
Перед записью каждая строка проходит валидацию. Правила описываются декларативно:
$rules = [
'EMAIL' => ['required', 'email'],
'PRICE' => ['required', 'numeric', 'min:0'],
'NAME' => ['required', 'max:255'],
'STATUS' => ['in:active,inactive,pending'],
];
Строки с ошибками не записываются, фиксируются в b_vendor_importer_error с указанием номера строки, поля и причины. После импорта доступен отчёт об ошибках с возможностью скачать CSV «проблемных строк».
Уведомления и логирование
По завершении импорта модуль отправляет email-уведомление инициатору через \Bitrix\Main\Mail\Event::send(). В уведомлении: общее количество строк, создано/обновлено/ошибок, ссылка на журнал.
Журнал хранится в b_vendor_importer_log: job_id, line_number, action (created/updated/skipped/error), entity_id, message, created_at.
Сроки разработки
| Этап | Срок |
|---|---|
| Архитектура, интерфейсы, инсталлятор | 1 день |
| Readers: CSV, XLSX, XML, JSON | 2 дня |
| Маппинг, трансформер, конфигуратор | 2 дня |
| Writers под конкретные сущности Битрикс | 3 дня |
| Потоковая обработка, агенты | 2 дня |
| Валидация, логирование, отчёт ошибок | 1 день |
| Административный интерфейс, тестирование | 2 дня |
Итого: 13 рабочих дней. Нестандартные форматы источника или сложная логика трансформации (дедупликация, обогащение данных из внешних API) оцениваются дополнительно.







