Диагностика проблемы с установкой родительской категории товара в WooCommerce
При массовом изменении товаров или ручном редактировании часто возникает ситуация, когда дочерняя категория товара установлена, но родительская категория не присваивается автоматически. Это приводит к некорректному отображению товара в фильтрах и навигации по категориям.
Как понять, что проблема именно в этом:
- Товар отображается только в дочерней категории, но не в родительской.
- Фильтры по родительским категориям не показывают товар.
- После импорта или редактирования товара родительская категория остаётся пустой.
Как автоматически установить родительскую категорию при изменении товара в WooCommerce
Реализуем функцию, которая при сохранении товара проверит, есть ли у товара дочерние категории, и если есть, автоматически добавит соответствующие родительские категории.
Пошаговое решение
- Подключаем хук
save_post_product— срабатывает при сохранении товара. - Получаем все категории товара.
- Для каждой категории проверяем наличие родительской категории.
- Добавляем родительские категории к товару, если они ещё не установлены.
- Обновляем категории товара.
add_action('save_post_product', 'auto_set_parent_categories', 20, 3);
function auto_set_parent_categories($post_id, $post, $update) {
// Проверяем, что это не автосохранение
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// Проверяем права пользователя
if (!current_user_can('edit_product', $post_id)) {
return;
}
// Получаем текущие категории товара
$terms = wp_get_post_terms($post_id, 'product_cat', array('fields' => 'ids'));
if (empty($terms) || is_wp_error($terms)) {
return;
}
$all_cats = $terms;
foreach ($terms as $term_id) {
$term = get_term($term_id, 'product_cat');
if ($term && $term->parent && !in_array($term->parent, $all_cats)) {
$all_cats[] = $term->parent;
}
}
// Если родительские категории добавились, обновляем таксономию
if (count($all_cats) > count($terms)) {
wp_set_post_terms($post_id, $all_cats, 'product_cat');
}
}Проверка результата после внедрения
Для проверки выполните следующие действия:
- Откройте товар в админке WooCommerce.
- Выберите дочернюю категорию для товара.
- Сохраните изменения.
- Проверьте, что при просмотре категории товара в админке или на сайте родительская категория тоже присвоена.
- Используйте функцию
wp_get_post_terms($product_id, 'product_cat')и убедитесь, что в списке есть родительские категории.
Частые ошибки и как их исправить
- Функция не срабатывает: возможно, хук подключён неверно или при сохранении вызывается автосохранение. Проверьте условие
DOING_AUTOSAVEи права пользователя. - Добавляются лишние категории: Если у категории несколько уровней родителей, функция добавит только непосредственного родителя. Для добавления всех предков нужно рекурсивно подняться по иерархии.
- Производительность падает при массовом обновлении: При большом количестве товаров обновление категорий может замедлить сохранение. В таком случае лучше запускать оптимизацию через WP-CLI или отдельный скрипт.
Практические советы по оптимизации и безопасности
- Чтобы избежать повторных вызовов при массовом импорте, используйте флаг, например,
remove_actionперед обновлением категорий, и затем снова добавляйте хук. - Для сложных иерархий категорий используйте функцию получения всех родителей через
get_ancestors():
$ancestors = get_ancestors($term_id, 'product_cat');
$all_cats = array_unique(array_merge($all_cats, $ancestors));- Проверяйте наличие ошибок через
is_wp_error()после операций с терминами. - Добавляйте логирование для отладки, например, с помощью
error_log().
Сравнение решений для установки родительских категорий
| Метод | Плюсы | Минусы | Применимость |
|---|---|---|---|
| Хук save_post_product с wp_set_post_terms | Автоматизация, работает при редактировании товара | Может замедлять сохранение при большом объеме | Малые и средние магазины |
| Отдельный скрипт на WP-CLI для массового обновления | Быстрая обработка больших объемов | Не автоматизировано, требует запуска вручную | Крупные магазины, импорт |
| Использование плагинов для управления категориями | Простота установки, GUI | Может быть избыточно, нагрузка на сайт | Новички, небольшие проекты |