Ответы:
Самый простой способ сделать это - переписать только Mage_Catalog_Block_Navigation
блок:
=> В методе _renderCategoryMenuItemHtml()
вы хотите заменить цикл
foreach ($children as $child) {
if ($child->getIsActive()) {
$activeChildren[] = $child;
}
}
=> с этим:
foreach ($children as $child) {
if ($child->getIsActive() && $this->_hasProducts($child->entity_id)) {
$activeChildren[] = $child;
}
}
=> и аналогично в методе renderCategoriesMenuHtml()
заменить код
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive()) {
$activeCategories[] = $child;
}
}
=> с этим:
foreach ($this->getStoreCategories() as $child) {
if ($child->getIsActive() && $this->_hasProducts($child->entity_id)) {
$activeCategories[] = $child;
}
}
=> Наконец, добавьте метод, который мы только что использовали в нашем коде:
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;
}
Имейте в виду, что метод проверяет каждую категорию в отдельности, используя модель каталога / категории. Итак, если у вас много категорий, вы можете переписать код, чтобы не столкнуться с проблемами производительности. В небольшом магазине, где мы работаем, это работает нормально.
Нет встроенной функции для скрытия пустых категорий (но вы можете вручную выбрать «Активен» = «Нет» для каждой категории в области администрирования-> каталог-> управлять категориями)
Вот ссылка на отличный пост из блога Джоша Пратцки , где он написал пошаговое руководство о том, как сделать расширение для этой цели.
Чтобы скрыть пустую категорию в верхнем меню, выполните следующие действия:
Перейдите в
app/code/core/Mage/Catalog/Block
папку и скопируйтеNavigation.php
.Переопределите
Navigation.php
в вашем локальном пакете. ОткройтеNavigation.php
ваш пакет и вставьте следующий код в этот файл:
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;
}
}
Для меня сработало создание дерева категорий шаблона и реализация функции условия, которая отображает дерево категорий:
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;
}
Вы можете выполнить следующий sql, чтобы отключить все категории без продуктов.
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
Более подробную информацию вы можете найти здесь http://quicktips.ru/all/hide-all-categories-without-products-and-show-categories-with-pr/
то, что я сделал, чтобы скрыть пустые категории, это переписать Mage_Catalog_Model_Resource_Category_Tree
load()
функцию. Я должен присоединиться к коллекции продуктов с коллекцией категорий, как показано ниже.
$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()));
добавить этот код раньше $arrNodes = $this->_conn->fetchAll($select);
этой строкой.
И оберните этот код этим условием, этот класс также вызывается из внешней и внутренней модели.
if(!Mage::getSingleton('admin/session')->isLoggedIn())
Я добавил дополнительное поле product_count, которое содержит фактическое количество активных продуктов.
Я использую сторонний модуль для отображения категории в верхнем меню, и я поставил условие на основе количества продуктов при отображении меню.