HUSKY - Product Filter for WooCommerce

Filtro por Categoria do WooCommerce Retorna Sem Resultados: Correção de Hierarquia de Categoria

Se o filtro por categoria do WooCommerce não retornar resultados para categorias pai, mesmo que os produtos estejam atribuídos a categorias filho, este guia ajudará você a corrigir isso.

O Problema

Sintoma: Quando você filtra por uma categoria pai, nenhum produto é exibido, mesmo que existam produtos em suas categorias filho.

Exemplo:

  • Estrutura de categorias: Federal Actions > SEC > Enforcement
  • Produto atribuído a: Enforcement (apenas categoria filho)
  • Filtrar por Federal Actions ou SEC retorna: Sem resultados
  • Filtrar por Enforcement retorna: Produto exibido

Por que Isso Acontece

WordPress/WooCommerce exige que os produtos sejam explicitamente marcados com todas as categorias pai na hierarquia, não apenas a categoria filho.

Quando você atribui um produto a uma categoria filho através da interface de administração do WordPress, o WooCommerce não marca automaticamente o produto com todas as categorias pai na tabela de relacionamentos de termos. Isso é um requisito de estrutura de dados, não uma limitação do HUSKY.

A atribuição correta de categorias deve incluir:

  • Categoria filho: Enforcement
  • Categoria pai: SEC
  • Categoria avô: Federal Actions

Como Verificar se Você Tem Esse Problema

  1. Acesse a página de edição do produto: wp-admin/post.php?post=YOUR_PRODUCT_ID&action=edit
  2. Observe a caixa de metadados Categorias no lado direito
  3. Verifique se todas as categorias pai na hierarquia estão marcadas
  4. Se apenas a categoria filho estiver marcada → Você tem esse problema

Solução: Normalização Automática da Hierarquia de Categorias

Esta solução consiste em duas partes:

  1. Correção à prova de futuro: Marcar automaticamente as categorias pai ao salvar produtos
  2. Correção imediata: Normalizar todos os produtos existentes

Parte 1: Marcar Automaticamente Categorias Pai (Produtos Futuros)

Adicione este código ao functions.php do seu tema filho:

/**
 * 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);
        }
    }
}

O que isso faz:

  • É acionado toda vez que um produto é salvo
  • Obtém todas as categorias atribuídas
  • Encontra todas as categorias pai para cada categoria atribuída
  • Marca o produto com a hierarquia completa
  • Limpa todos os caches relevantes

Resultado: A partir de agora, qualquer produto salvo incluirá automaticamente todas as categorias pai.

Parte 2: Normalizar Produtos Existentes (Correção Única)

Este script corrigirá todos os produtos existentes em seu banco de dados. Adicione este código temporário ao seu 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
    ];
}

Como usar:

  1. Adicione o código ao seu functions.php
  2. Acesse: https://yoursite.com/?normalize_cats=1 (deve estar logado como administrador)
  3. Aguarde a conclusão do script
  4. Você verá resultados mostrando quantos produtos foram atualizados
  5. Remova este código após executá-lo uma vez

Saída esperada:

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

Isso significa que 156 produtos de 919 estavam sem categorias pai e foram corrigidos.

Testando a Correção

  1. Acesse sua página de loja com os filtros HUSKY
  2. Tente filtrar por uma categoria pai
  3. Produtos de categorias filho devem agora aparecer
  4. Tente navegar pela hierarquia – todos os níveis devem funcionar

Por que não Tornar Isso Padrão no HUSKY?

Esta é uma pergunta legítima. Eis o porquê:

  1. Alteração na Estrutura de Dados: Isso modifica os relacionamentos de dados principais do WooCommerce
  2. Não Universal: Alguns sites intencionalmente atribuem apenas categorias filho para lógica de negócios específica
  3. Desempenho: Em catálogos muito grandes, isso adiciona sobrecarga a cada salvamento de produto
  4. Conflitos: Pode interferir com outros plugins que gerenciam relacionamentos de categorias

Melhoria Futura: Podemos adicionar isso como uma configuração opcional no HUSKY que os usuários podem ativar se necessário, mas não será comportamento padrão.

Alternativa: Atribuição Manual de Categorias

  1. Edite cada produto
  2. Na caixa de metadados Categorias, marque todas as categorias pai relevantes manualmente
  3. Salve o produto

Isso dá a você controle granular, mas é demorado para catálogos grandes.

Solução de Problemas

O script mostra 0 produtos normalizados

  • Seus produtos podem já ter as categorias pai corretas atribuídas
  • Verifique alguns produtos manualmente para confirmar

Filtragem ainda não funciona após a normalização

  • Limpe todos os caches (WordPress, servidor, navegador)
  • Certifique-se de que o HUSKY está usando a taxonomia correta (product_cat)
  • Verifique conflitos com outros plugins de filtro
  • Confirme que os produtos estão publicados (não rascunho)

Produtos desaparecem do filtro de categoria filho

Isso não deveria acontecer, mas se acontecer:

  • O script preserva todas as atribuições de categorias existentes
  • Verifique se outro plugin está interferindo
  • Restaure a partir de um backup e entre em contato com o suporte

Taxonomias Personalizadas

Esta solução também funciona para taxonomias personalizadas criadas com CPT UI ou plugins similares. Basta alterar 'product_cat' para o slug da sua taxonomia personalizada:

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

Notas Importantes

  • Tema Filho Necessário: Sempre use um tema filho para evitar perda de código durante atualizações do tema
  • Backup Primeiro: Faça backup do banco de dados antes de executar o script de normalização
  • Teste em Staging: Teste em um site de staging primeiro, se possível
  • Script Único: Remova o script de normalização após executá-lo
  • Mantenha o Código da Parte 1: O hook save_post_product deve permanecer permanentemente

Resumo

Adicionar ao functions.php permanentemente:

  • Hook para marcar automaticamente categorias pai (Parte 1)

Executar uma vez e remover:

  • Script de normalização (Parte 2)

Resultados esperados:

  • Filtragem por categoria pai funciona corretamente
  • Filtragem por categoria filho continua funcionando
  • Navegação na hierarquia funciona adequadamente
  • Produtos futuros incluem automaticamente categorias pai