HUSKY - Products Filter Professional for WooCommerce

Як виправити фільтрацію ієрархії категорій у магазині woocommerce (нормалізувати базу даних)

Якщо ви стикаєтеся з проблемами, коли фільтрація за батьківськими категоріями не дає результатів, хоча товари призначені для дочірніх категорій, цей посібник допоможе вам це виправити.

Проблема

Симптом: При фільтрації за батьківською категорією товари не відображаються, хоча вони існують у її дочірніх категоріях.

Приклад:

  • Структура категорії: Federal Actions > SEC > Enforcement
  • Товар призначений для: Enforcement (тільки дочірня категорія)
  • Фільтрація за Federal Actions або SEC повертає: Немає результатів
  • Фільтрація за Enforcement повертає: Показаний продукт

Чому це відбувається

WordPress/WooCommerce вимагає продукти, які повинні бути явно позначені усі батьківські категорії в ієрархії, а не тільки дочірню категорію.

Коли ви призначаєте товар до дочірньої категорії через інтерфейс адміністратора WordPress, WooCommerce не позначає товар автоматично всіма батьківськими категоріями в таблиці зв'язків термінів. Це вимога структури даних, а не обмеження HUSKY.

Правильне призначення категорії має включати:

  • Дочірня категорія: Enforcement
  • Батьківська категорія: SEC
  • Батьківська категорія: Federal Actions

Як перевірити, чи є у вас ця проблема

  1. Перейдіть на сторінку редагування товару: wp-admin/post.php?post=YOUR_PRODUCT_ID&action=edit
  2. Подивіться на метабокс Категорії праворуч
  3. Перевірити, чи усі батьківські категорії в ієрархії перевіряються
  4. Якщо вибрано лише дочірню категорію → Ви маєте цю проблему

Рішення: Автоматична нормалізація ієрархії категорій

Це рішення складається з двох частин:

  1. Майбутньозахищене виправлення: Автоматично позначати батьківські категорії при збереженні товарів
  2. Негайна виправлення: Нормалізувати всі існуючі товари

Частина 1: Автоматичне позначення батьківських категорій (майбутні продукти)

Додайте цей код до свого дочірнього теми functions.php:

/**
 * Automatically mark all parent categories when product is saved
 * This ensures hierarchy filtering works correctly
 */
add_action('save_post_product', 'auto_mark_parent_categories', 10, 1);

function auto_mark_parent_categories($product_id) {
    // Clear cache
    clean_object_term_cache($product_id, 'product_cat');

    // Get currently assigned categories
    $terms = wp_get_post_terms($product_id, 'product_cat', ['fields' => 'ids']);

    if (!is_wp_error($terms) AND !empty($terms)) {
        $all_terms = [];

        // For each assigned category, get all its parents
        foreach ($terms as $term_id) {
            $all_terms[] = $term_id;

            // Get all ancestor categories
            $ancestors = get_ancestors($term_id, 'product_cat', 'taxonomy');
            if (!empty($ancestors)) {
                $all_terms = array_merge($all_terms, $ancestors);
            }
        }

        // Assign product to all categories including parents
        wp_set_object_terms($product_id, array_unique($all_terms), 'product_cat');

        // Clear caches
        clean_post_cache($product_id);
        clean_object_term_cache($product_id, 'product_cat');

        if (function_exists('wc_delete_product_transients')) {
            wc_delete_product_transients($product_id);
        }
    }
}

Що це робить:

  • Спрацьовує щоразу, коли продукт зберігається
  • Отримує всі призначені категорії
  • Знаходить усі батьківські категорії для кожної призначеної категорії
  • Позначає продукт із повною ієрархією
  • Очищає всі відповідні кеші

Результат: Відтепер будь-який збережений продукт автоматично включатиме всі батьківські категорії.

Частина 2: Нормалізувати наявні продукти (одноразове виправлення)

Цей скрипт виправить усі існуючі товари у вашій базі даних. Додайте цей тимчасовий код у ваш functions.php:

/**
 * One-time script to normalize all existing products
 * Access: yourdomain.com/?normalize_cats=1 (must be logged in as admin)
 */
add_action('init', function () {
    if (isset($_GET['normalize_cats']) AND current_user_can('manage_options')) {
        $result = normalize_all_products_categories();
        echo '<h2>Category Normalization Results</h2>';
        echo '<pre>';
        print_r($result);
        echo '</pre>';
        die();
    }
});

function normalize_all_products_categories() {
    global $wpdb;

    // Get all product IDs
    $args = [
        'post_type' => 'product',
        'post_status' => 'any',
        'posts_per_page' => -1,
        'fields' => 'ids'
    ];

    $product_ids = get_posts($args);
    $log = [];
    $normalized_count = 0;

    foreach ($product_ids as $product_id) {
        // Get current categories
        $terms = wp_get_post_terms($product_id, 'product_cat', ['fields' => 'ids']);

        if (!is_wp_error($terms) AND !empty($terms)) {
            $all_terms = [];

            // Collect all parent categories
            foreach ($terms as $term_id) {
                $all_terms[] = $term_id;

                // Get ancestors
                $ancestors = get_ancestors($term_id, 'product_cat', 'taxonomy');

                if (!empty($ancestors)) {
                    $all_terms = array_merge($all_terms, $ancestors);
                }
            }

            $all_terms = array_unique($all_terms);

            // Only update if we're adding new parent categories
            if (count($all_terms) > count($terms)) {
                wp_set_object_terms($product_id, $all_terms, 'product_cat');
                $normalized_count++;
                $log[] = "Product #{$product_id}: added " . (count($all_terms) - count($terms)) . " parent categories";
            }
        }
    }

    // Log to WordPress error log
    error_log("=== Category Normalization Complete ===");
    error_log(implode("\n", $log));
    error_log("Total normalized: {$normalized_count} products");

    return [
        'success' => true,
        'normalized' => $normalized_count,
        'total' => count($product_ids),
        'details' => $log
    ];
}

Як використовувати:

  1. Додайте код до вашого functions.php
  2. Перейти до: https://yoursite.com/?normalize_cats=1 (потрібно увійти як адміністратор)
  3. Дочекайтеся завершення скрипта
  4. Ви побачите результати, що показують, скільки товарів було оновлено
  5. Видаліть цей код після одноразового запуску

Очікуваний вивід:

Category Normalization Results
Array
(
    [success] => 1
    [normalized] => 156
    [total] => 919
)

Це означає, що 156 товарів з 919 не мали батьківських категорій і були виправлені.

Тестування виправлення

Після реалізації обох частин:

  1. Перейдіть на сторінку свого магазину з фільтрами HUSKY
  2. Спробуйте фільтрувати за батьківська категорія
  3. Тепер товари з дочірніх категорій мають з'являтися
  4. Спробуйте проаналізувати ієрархію – усі рівні повинні працювати

Чому б не зробити це за замовчуванням у HUSKY?

Це обґрунтоване питання. Ось чому:

  1. Зміна структури даних: Це модифікує основні зв'язки даних WooCommerce
  2. Не універсальний: Деякі сайти навмисно призначають лише дочірні категорії для певної бізнес-логіки
  3. Продуктивність: У дуже великих каталогах це додає навантаження на кожне збереження товару
  4. Конфлікти: Може конфліктувати з іншими плагінами, які керують зв'язками категорій

Майбутнє вдосконалення: Можливо, ми додамо це як необов'язкове налаштування в HUSKY, що користувачі можуть увімкнути, якщо це необхідно, але це не буде поведінкою за замовчуванням.

Альтернатива: Ручне призначення категорій

Якщо ви віддаєте перевагу ручному керуванню, ви можете:

  1. Редагувати кожен продукт
  2. У метабоксі Категорії, поставте галочку усі відповідні батьківські категорії вручну
  3. Зберегти товар

Це дає вам детальний контроль, але вимагає багато часу для великих каталогів.

Виправлення проблем

Скрипт показує 0 нормалізованих продуктів

  • Ваші продукти, можливо, вже мають правильно призначені батьківські категорії
  • Перевірте кілька продуктів вручну, щоб переконатися

Фільтрація все ще не працює після нормалізації

  • Очистити весь кеш (WordPress, сервер, браузер)
  • Переконайтеся, що HUSKY використовує правильну таксономію (product_cat)
  • Перевірте конфлікти з іншими плагінами фільтрації
  • Перевірити, чи продукти опубліковані (не чорнові)

Продукти зникають із фільтра дочірньої категорії

Цього не повинно статися, але якщо це станеться:

  • Скрипт зберігає всі наявні призначення категорій
  • Перевірте, чи інший плагін не конфліктує
  • Відновіть з резервної копії та зв'яжіться з підтримкою

Власні таксономії

Це рішення також працює для власні таксономії створені за допомогою CPT UI або подібних плагінів. Просто змініть 'product_cat' до вашого кастомного слаг таксономії:

// Example for custom taxonomy 'modality'
$terms = wp_get_post_terms($product_id, 'modality', ['fields' => 'ids']);
wp_set_object_terms($product_id, array_unique($all_terms), 'modality');

Важливі примітки

  • Необхідна дочірня тема: Завжди використовуйте дочірню тему, щоб запобігти втраті коду під час оновлення теми
  • Спочатку зробіть резервну копію: Резервно збережіть вашу базу даних перед запуском скрипта нормалізації
  • Тестування на стейджингу: Спочатку протестуйте на тестовому сайті, якщо це можливо
  • Одноразовий скрипт: Видалити скрипт нормалізації після його запуску
  • Зберегти код Частини 1: The save_post_product хук повинен залишатися постійно

Підсумок

Додайте до functions.php назавжди:

  • Хук автоматичного позначення батьківських категорій (Частина 1)

Запустити один раз і видалити:

  • Скрипт нормалізації (Частина 2)

Очікувані результати:

  • Фільтрація за батьківською категорією працює коректно
  • Фільтрація дочірніх категорій продовжує працювати
  • Ієрархічні функції розгортання працюють належним чином
  • Майбутні товари автоматично включають батьківські категорії