HUSKY - Products Filter Professional for WooCommerce

Jak naprawić filtrowanie hierarchii kategorii w sklepie woocommerce (normalizuj bazę danych)

Jeśli napotykasz problemy, w których filtrowanie według kategorii nadrzędnych nie zwraca żadnych wyników, mimo że produkty są przypisane do kategorii podrzędnych, ten przewodnik pomoże Ci je rozwiązać.

Problem

Objaw: Podczas filtrowania według kategorii nadrzędnej, żadne produkty nie są pokazywane, mimo że produkty istnieją w jej kategoriach podrzędnych.

Przykład:

  • Struktura kategorii: Federal Actions > SEC > Enforcement
  • Produkt jest przypisany do: Enforcement (tylko kategoria dziecka)
  • Filtrowanie według Federal Actions lub SEC zwraca: Brak wyników
  • Filtrowanie według Enforcement zwraca: Produkt pokazany

Dlaczego tak się dzieje

WordPress/WooCommerce wymaga produkty, które mają być jawnie oznaczone wszystkie kategorie nadrzędne w hierarchii, a nie tylko w kategorii potomnej.

Kiedy przypisujesz produkt do podrzędnej kategorii za pomocą interfejsu administratora WordPress, WooCommerce nie oznacza automatycznie produktu ze wszystkimi kategoriami nadrzędnymi w tabeli relacji terminów. Jest to wymóg struktury danych, a nie ograniczenie HUSKY.

Poprawne przypisanie kategorii powinno zawierać:

  • Kategoria potomna: Enforcement
  • Kategoria nadrzędna: SEC
  • Kategoria nadrzędna: Federal Actions

Jak sprawdzić, czy masz ten problem

  1. Przejdź do strony edycji produktu: wp-admin/post.php?post=YOUR_PRODUCT_ID&action=edit
  2. Spójrz na pole Metadane kategorii po prawej stronie
  3. Sprawdź, czy wszystkie kategorie nadrzędne w hierarchii są zaznaczone
  4. Jeśli zaznaczona jest tylko kategoria podrzędna → Masz ten problem

Rozwiązanie: Automatyczna normalizacja hierarchii kategorii

To rozwiązanie składa się z dwóch części:

  1. Poprawka przyszłościowa: Automatycznie zaznacz kategorie nadrzędne podczas zapisywania produktów
  2. Natychmiastowa poprawka: Znormalizuj wszystkie istniejące produkty

Część 1: Automatyczne oznaczanie kategorii nadrzędnych (przyszłe produkty)

Dodaj ten kod do swojego motywu potomnego 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);
        }
    }
}

Co to robi:

  • Wywoływane za każdym razem, gdy produkt jest zapisywany
  • Pobiera wszystkie przypisane kategorie
  • Znajduje wszystkie kategorie nadrzędne dla każdej przypisanej kategorii
  • Oznacza produkt z pełną hierarchią
  • Czyści wszystkie odpowiednie pamięci podręczne

Wynik: Od teraz każdy zapisany produkt będzie automatycznie zawierał wszystkie kategorie nadrzędne.

Część 2: Normalizacja istniejących produktów (jednorazowa poprawka)

Ten skrypt naprawi wszystkie istniejące produkty w Twojej bazie danych. Dodaj to tymczasowy kod do swojego 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
    ];
}

Jak używać:

  1. Dodaj kod do swojego functions.php
  2. Przejdź do: https://yoursite.com/?normalize_cats=1 (musisz być zalogowany jako administrator)
  3. Poczekaj na zakończenie skryptu
  4. Zobaczysz wyniki pokazujące, ile produktów zostało zaktualizowanych
  5. Usuń ten kod po jednorazowym uruchomieniu

Oczekiwany wynik:

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

Oznacza to, że 156 produktów z 919 brakowało kategorii nadrzędnych i zostało naprawionych.

Testowanie poprawki

Po zaimplementowaniu obu części:

  1. Przejdź do swojej strony sklepu z filtrami HUSKY
  2. Spróbuj filtrować według kategoria nadrzędna
  3. Produkty z podkategorii powinny teraz się pojawiać
  4. Spróbuj przejść przez hierarchię – wszystkie poziomy powinny działać

Dlaczego nie uczynić tego domyślnym w HUSKY?

To zasadne pytanie. Oto dlaczego:

  1. Zmiana struktury danych: Modyfikuje to podstawowe relacje danych WooCommerce
  2. Nie uniwersalne: Niektóre witryny celowo przypisują tylko kategorie podrzędne dla określonej logiki biznesowej
  3. Wydajność: W bardzo dużych katalogach dodaje to narzut do każdego zapisywania produktu
  4. Konflikty: Może kolidować z innymi wtyczkami zarządzającymi relacjami kategorii

Przyszłe udoskonalenie: Możemy dodać to jako opcjonalne ustawienie w HUSKY, które użytkownicy mogą włączyć, jeśli jest to potrzebne, ale nie będzie to domyślne zachowanie.

Alternatywa: Ręczne przypisywanie kategorii

Jeśli wolisz ręczną kontrolę, możesz:

  1. Edytuj każdy produkt
  2. W meta-polu Kategorii zaznacz wszystkie odpowiednie kategorie nadrzędne ręcznie
  3. Zapisz produkt

Daje to precyzyjną kontrolę, ale jest czasochłonne dla dużych katalogów.

Rozwiązywanie problemów

Skrypt pokazuje 0 znormalizowanych produktów

  • Twoje produkty mogą już mieć przypisane poprawne kategorie nadrzędne
  • Sprawdź ręcznie kilka produktów, aby zweryfikować

Filtrowanie nadal nie działa po normalizacji

  • Wyczyść wszystkie pamięci podręczne (WordPress, serwer, przeglądarka)
  • Upewnij się, że HUSKY używa poprawnej taksonomii (product_cat)
  • Sprawdź konflikty z innymi wtyczkami filtrującymi
  • Weryfikuj, czy produkty są opublikowane (nie szkice)

Produkty znikają z filtra kategorii podrzędnych

To nie powinno się zdarzyć, ale jeśli się zdarzy:

  • Skrypt zachowuje wszystkie istniejące przypisania kategorii
  • Sprawdź, czy inny plugin nie przeszkadza
  • Przywróć z kopii zapasowej i skontaktuj się ze wsparciem

Niestandardowe taksonomie

To rozwiązanie działa również dla niestandardowe taksonomie utworzone za pomocą CPT UI lub podobnych wtyczek. Po prostu zmień 'product_cat' do swojego niestandardowego ciągu taksonomii:

// 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');

Ważne uwagi

  • Wymagany motyw potomny: Zawsze używaj motywu potomnego, aby zapobiec utracie kodu podczas aktualizacji motywu
  • Najpierw wykonaj kopię zapasową: Wykonaj kopię zapasową bazy danych przed uruchomieniem skryptu normalizacji
  • Testuj na Staging: Najpierw przetestuj na stronie staging, jeśli to możliwe
  • Skrypt jednorazowy: Usuń skrypt normalizacji po jego uruchomieniu
  • Zachowaj kod z części 1: The save_post_product hook powinien pozostać na stałe

Podsumowanie

Dodaj do functions.php na stałe:

  • Automatyczne zaznaczanie kategorii nadrzędnych (część 1)

Uruchom raz i usuń:

  • Skrypt normalizujący (Część 2)

Oczekiwane wyniki:

  • Filtrowanie kategorii nadrzędnych działa poprawnie
  • Filtrowanie kategorii potomnych nadal działa
  • Funkcje hierarchicznego rozwijania działają poprawnie
  • Przyszłe produkty automatycznie uwzględniają kategorie nadrzędne