Классическая головная боль при импорте YML-фидов (Яндекс.Маркет, СберМегаМаркет, маркетплейсы): в карточке каждого товара есть только числовой идентификатор вроде <categoryId>14882</categoryId>. Сами же названия категорий и их родительские связи лежат отдельно в начале файла в блоке <categories>.
Если передать {categoryId[1]} напрямую в WP All Import, плагин создаст рубрику с именем «14882» вместо полноценного пути «Бытовая техника > Климатическая техника > Обогреватели».
Ниже — готовое и быстрое решение, которое сопоставляет ID с реальными названиями категорий и собирает их в полную иерархию.
Почему стандартные способы тормозят или ломают Preview?
- В товаре нет названий. Без сопоставления с блоком <categories> плагин видит только цифры.
- Пустой предпросмотр (Preview). В окне Preview плагин изолирует выполнение, стандартные пути к текущему файлу часто недоступны, из-за чего кастомные функции возвращают пустоту.
- Падения по памяти. Если в прайсе десятки тысяч позиций (30 000–50 000+), повторный парсинг XML-дерева на каждом товаре гарантированно приводит к Fatal error: Allowed memory size exhausted или Execution timeout.
Как мы это решаем:
При первом же вызове функция находит блок <categories> в исходном XML, за доли секунды собирает карту соответствия ID => Полный путь с названиями и сохраняет её во временный файл wpallimport_cat_map.json. Для всех последующих товаров (и в окне Preview) функция просто мгновенно берет готовое название по его ID.
Шаг 1. Добавляем функцию сопоставления в плагин Code Snippets
Добавьте этот PHP-код через плагин Code Snippets (или в functions.php дочерней темы):
function get_yml_category_path($category_id) {
static $map = null;
if ($map === null) {
$upload_dir = wp_upload_dir();
$cache_file = $upload_dir['basedir'] . '/wpallimport_cat_map.json';
// 1. Проверяем кэш
if (file_exists($cache_file) && (time() - filemtime($cache_file) < 86400)) {
$map = json_decode(file_get_contents($cache_file), true);
}
// 2. Если кэша нет — парсим категории из рабочего XML
if (empty($map)) {
$map = [];
$raw_cats = [];
// Ищем исходный XML-файл в uploads/wpallimport
$import_dir = $upload_dir['basedir'] . '/wpallimport/uploads';
$files = glob($import_dir . '/*/*.xml');
// Если не нашли в подпапках, ищем последний измененный XML в uploads
if (empty($files)) {
$files = glob($upload_dir['basedir'] . '/wpallimport/*.xml');
}
if (!empty($files)) {
// Берем самый свежий файл
usort($files, function($a, $b) {
return filemtime($b) - filemtime($a);
});
$source_file = $files[0];
// Читаем блок
$handle = @fopen($source_file, 'r');
$categories_chunk = '';
if ($handle) {
while (($line = fgets($handle)) !== false) {
$categories_chunk .= $line;
if (strpos($line, '') !== false) {
break;
}
}
fclose($handle);
}
if (preg_match('/(.*?)<\/categories>/s', $categories_chunk, $matches)) {
$xml = simplexml_load_string('' . $matches[1] . '');
if ($xml) {
foreach ($xml->category as $cat) {
$id = (string)$cat['id'];
$raw_cats[$id] = [
'name' => trim((string)$cat),
'parentId' => isset($cat['parentId']) ? (string)$cat['parentId'] : null,
];
}
}
}
}
// Выстраиваем полные цепочки для каждого ID
foreach ($raw_cats as $id => $data) {
$chain = [];
$curr = $id;
$limit = 0;
while ($curr && isset($raw_cats[$curr]) && $limit < 10) { $c_name = $raw_cats[$curr]['name']; if ($c_name !== 'Все товары') { array_unshift($chain, $c_name); } $curr = $raw_cats[$curr]['parentId']; $limit++; } $map[$id] = implode(' > ', $chain);
}
// Сохраняем в кэш
if (!empty($map)) {
@file_put_contents($cache_file, json_encode($map, JSON_UNESCAPED_UNICODE));
}
}
}
$target_id = trim((string)$category_id);
return isset($map[$target_id]) ? $map[$target_id] : '';
} Шаг 2. Настройка сопоставления в шаблоне WP All Import
Перейдите к редактированию вашего импорта на Шаг 3 (Step 3):
- Откройте блок Taxonomies, Categories, Tags.
- Отметьте таксономию Product categories (Категории товаров).
- Выберите переключатель: «An element in my file contains the entire hierarchy» (Элемент в моем файле содержит всю иерархию).
- В поле для пути категории передайте поле с ID через нашу функцию: [get_yml_category_path({categoryId[1]})]
- В поле Separated by (Разделитель) укажите символ с пробелами по бокам: >
- Нажмите Preview прямо под полем иерархии.
Что изменится?
- Было: Товар импортировался в категорию с бессмысленным числовым именем 14882.
- Стало: Функция принимает ID 14882, находит его в сопоставленной карте и отдает путь Бытовая техника > Климатическая техника > Обогреватели > Конвекторы.
- Предпросмотр работает: В окне Preview цепочка сразу видна корректно.
- Нагрузка 0%: Даже на базах в 40 000+ товаров сервер не тратит ресурсы на повторный разбор XML.
