Respostas:
A maneira mais fácil de fazer isso é reescrever o Mage_Catalog_Block_Navigation
bloco:
=> No método que _renderCategoryMenuItemHtml()
você deseja substituir o loop
foreach ($children as $child) {
if ($child->getIsActive()) {
$activeChildren[] = $child;
}
}
=> com isso:
foreach ($children as $child) {
if ($child->getIsActive() && $this->_hasProducts($child->entity_id)) {
$activeChildren[] = $child;
}
}
=> e da mesma forma no método renderCategoriesMenuHtml()
substitua o código
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive()) {
$activeCategories[] = $child;
}
}
=> com isso:
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive() && $this->_hasProducts($child->entity_id)) {
$activeCategories[] = $child;
}
}
=> Por fim, adicione o método que estávamos usando em nosso código:
protected function _hasProducts($category_id) {
$products = Mage::getModel('catalog/category')->load($category_id)
->getProductCollection()
->addAttributeToSelect('entity_id')
->addAttributeToFilter('status', 1)
->addAttributeToFilter('visibility', 4);
return ( $products->count() > 0 ) ? true : false;
}
Lembre-se de que o método verifica cada categoria individualmente usando o modelo de catálogo / categoria. Portanto, se você tiver muitas categorias, poderá reescrever o código para não ter problemas de desempenho. Em uma loja menor que estamos executando, isso funciona bem.
Não há recurso interno para ocultar categorias vazias (mas você pode selecionar manualmente Está ativo = Não para cada categoria na área de administração-> catálogo-> gerenciar categorias)
Aqui está um link em um ótimo post do blog de Josh Prattski , onde ele escreveu passo a passo sobre como fazer uma extensão para esse fim.
Para ocultar uma categoria vazia no menu Superior, faça o seguinte:
Vá para
app/code/core/Mage/Catalog/Block
Pasta e copieNavigation.php
.Substitua
Navigation.php
no seu pacote local. Abra oNavigation.php
seu pacote e cole o seguinte código neste arquivo:
if ($category->getIsActive()) {
$cat = Mage::getModel('catalog/category')->load($category->getId());
$products = Mage::getResourceModel('catalog/product_collection')->addCategoryFilter($cat);
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($products);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($products);
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($products);
if (count($products) == 0) {
return;
}
}
O que funcionou para mim é criar uma árvore de categorias de modelo e implementar uma função de condição que renderiza a árvore de categorias:
foreach ($children as $child)
{
if ($child->getIsActive() && $this->_hasProducts($child->entity_id))
{
$activeChildren[] = $child;
}
}
function _hasProducts:
protected function _hasProducts($category_id) {
$products = Mage::getModel('catalog/category')->load($category_id)
->getProductCollection()
->addAttributeToSelect('entity_id')
->addAttributeToFilter('status', 1)
->addAttributeToFilter('visibility', 4);
return ( $products->count() > 0 ) ? true : false;
}
Você pode executar o seguinte sql para desativar todas as categorias sem produtos.
UPDATE `catalog_category_entity_int` AS `status`
INNER JOIN `eav_attribute` AS `attr` ON `attr`.`attribute_code` = 'is_active'
AND `attr`.`entity_type_id` = 3
AND `status`.`attribute_id` = `attr`.`attribute_id`
SET `status`.`value` = IF((SELECT COUNT(`index`.`product_id`)
FROM `catalog_category_product_index` AS `index`
WHERE `index`.`category_id` = `status`.`entity_id` GROUP BY `index`.`category_id`) > 0, 1, 0)
WHERE `status`.`store_id` = 0
Mais detalhes você pode encontrar aqui http://quicktips.ru/all/hide-all-categories-without-products-and-show-categories-with-pr/
o que fiz para ocultar categorias vazias é reescrever a Mage_Catalog_Model_Resource_Category_Tree
load()
função. Tenho que ingressar na coleção de produtos com a coleção de categorias, como abaixo.
$collection = Mage::getResourceModel('catalog/product_collection');
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($collection);
Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
$collection->getSelect()->join(
array('product_category' => Mage::getSingleton('core/resource')->getTableName('catalog/category_product_index')),
'product_category.product_id = e.entity_id',
array('')
);
$collection->getSelect()->where('product_category.category_id = '.$this->_table.'.entity_id');
$select->columns(array('product_count' => $collection->getSelectCountSql()));
adicione este código antes $arrNodes = $this->_conn->fetchAll($select);
desta linha.
E envolva esse código com essa condição, essa classe chamada de modelo front-end e back-end também
if(!Mage::getSingleton('admin/session')->isLoggedIn())
Adicionei o campo extra product_count, que contém a contagem real de produtos ativos.
Estou usando um módulo de terceiros para exibir a categoria no menu superior e coloquei as condições com base na contagem de produtos quando o menu é renderizado.