Como Corrigir a Filtragem de Hierarquia de Categoria na loja woocommerce (normalizar banco de dados)
Se você estiver enfrentando problemas em que a filtragem por categorias pai não retorna resultados, mesmo que os produtos sejam atribuídos a categorias filhas, este guia ajudará você a corrigi-lo.
O Problema
Sintoma: Ao filtrar por uma categoria pai, nenhum produto é exibido, mesmo que existam produtos em suas subcategorias.
Exemplo:
- Estrutura de categoria:
Federal Actions > SEC > Enforcement - Produto é atribuído a:
Enforcement(apenas categoria filha) - Filtragem por
Federal ActionsouSECretorna: Nenhum resultado - Filtragem por
Enforcementretorna: Produto mostrado
Por que isso acontece
WordPress/WooCommerce requer produtos a serem explicitamente marcados com todas as categorias pai na hierarquia, não apenas na categoria filha.
Quando você atribui um produto a uma categoria filha 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. Este é um requisito de estrutura de dados, não uma limitação do HUSKY.
A atribuição correta da categoria deve incluir:
- Categoria filha:
Enforcement - Categoria pai:
SEC - Categoria avó:
Federal Actions
Como verificar se você tem este problema
- Vá para a página de edição de um produto:
wp-admin/post.php?post=YOUR_PRODUCT_ID&action=edit - Olhe na caixa de meta das Categorias no lado direito
- Verificar se todas as categorias pai na hierarquia estão marcados
- Se apenas a categoria filha estiver marcada → Você tem este problema
Solução: Normalização Automática da Hierarquia de Categorias
Esta solução consiste em duas partes:
- Correção à prova de futuro: Marca automaticamente categorias pai ao salvar produtos
- Correção imediata: Normalizar todos os produtos existentes
Parte 1: Marcar Automaticamente Categorias Principais (Produtos Futuros)
Adicione este código ao seu tema filho 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);
}
}
}
O que isso faz:
- Aciona 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 temporário código para o 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:
- Adicione o código ao seu
functions.php - Ir para:
https://yoursite.com/?normalize_cats=1(deve estar logado como admin) - Aguarde a conclusão do script
- Você verá resultados mostrando quantos produtos foram atualizados
- 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 faltando categorias pai e foram corrigidos.
Testando a Correção
Após implementar ambas as partes:
- Vá para a sua página de loja com filtros HUSKY
- Tente filtrar por um categoria pai
- Produtos de categorias filhas agora devem aparecer
- Tente explorar a hierarquia – todos os níveis devem funcionar
Por que não tornar isso o padrão no HUSKY?
Esta é uma pergunta legítima. Eis o porquê:
- Mudança na Estrutura de Dados: Isso modifica as relações de dados principais do WooCommerce
- Não Universal: Alguns sites atribuem intencionalmente apenas categorias filhas para lógica de negócios específica
- Desempenho: Em catálogos muito grandes, isso adiciona sobrecarga a cada salvamento de produto
- Conflitos: Pode interferir com outros plugins que gerenciam relacionamentos de categoria
Melhoria Futura: Podemos adicionar isso como uma configuração opcional no HUSKY que os usuários podem habilitar se necessário, mas não será o comportamento padrão.
Alternativa: Atribuição Manual de Categoria
Se você preferir controle manual, você pode:
- Editar cada produto
- Na metabox de Categorias, marque todas as categorias pai relevantes manualmente
- Salvar o produto
Isso lhe dá controle granular, mas consome tempo para catálogos grandes.
Solução de Problemas
O script mostra 0 produtos normalizados
- Seus produtos podem já ter as categorias principais corretas atribuídas
- Verifique alguns produtos manualmente para verificar
A filtragem ainda não funciona após a normalização
- Limpar todos os caches (WordPress, servidor, navegador)
- Certifique-se de que HUSKY está usando a taxonomia correta (
product_cat) - Verificar conflitos com outros plugins de filtro
- Verifique se os produtos estão publicados (não rascunho)
Produtos desaparecem do filtro de categoria filha
Isso não deveria acontecer, mas se acontecer:
- O script preserva todas as atribuições de categoria existentes
- Verifique se outro plugin está interferindo
- Restaurar do backup e entrar em contato com o suporte
Taxonomias Personalizadas
Esta solução também funciona para taxonomias personalizadas criados com CPT UI ou plugins semelhantes. Simplesmente mude 'product_cat' para o seu slug de taxonomia personalizado:
// 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
- Child Theme Necessário: Sempre use um tema filho para evitar perda de código durante atualizações de tema
- Faça Backup Primeiro: Faça backup do seu banco de dados antes de executar o script de normalização
- Testar em Staging: Teste em um site de staging primeiro, se possível
- Script Único: Remover o script de normalização após executá-lo
- Keep Part 1 Code: O
save_post_producthook deve permanecer permanentemente
Resumo
Adicionar ao functions.php permanentemente:
- Hook de marcação automática de categorias pai (Parte 1)
Executar uma vez e remover:
- Script de Normalização (Parte 2)
Resultados esperados:
- A filtragem por categoria pai funciona corretamente
- A filtragem de categorias filhas continua funcionando
- Funções de drill-down de hierarquia funcionam corretamente
- Produtos futuros incluem automaticamente categorias pai