Jump to content

How to hide empty categories in top menu?


Recommended Posts

Nevermind, already got it working.

 

Just in case anyone else wonders (really easy!), blocktopmenu.php should look like this:

foreach ($children as $child)
{
    $id_category = (int)$child['id_category'];
    $ProductsCount = 0;
    $ProductsCount = (int)Db::getInstance()->getValue('SELECT COUNT(cp.id_category) FROM '._DB_PREFIX_.'category_product cp, '._DB_PREFIX_.'product pr WHERE cp.id_category = '.$id_category .' AND cp.id_product = pr.id_product AND pr.active = 1' );
    if($ProductsCount>0)
    {
        $this->getCategory($id_category, (int)$id_lang, (int)$child['id_shop']);
    }
}

Cheers.

 

Edit: It's a fix for the 1.5.6.2 version; sorry for the misunderstood.

Edited by rsaiz (see edit history)
Link to comment
Share on other sites

Where exactly in blocktopmenu.php I should put this?

Lines 716 - 724 in my blocktopmenu.php

 

public function hookActionObjectManufacturerDeleteAfter($params)
{
$this->clearMenuCache();
}


public function hookActionObjectManufacturerAddAfter($params)
{
$this->clearMenuCache();
}
Edited by Elfiszcze (see edit history)
Link to comment
Share on other sites

All right, try this. In classes/Category.php locate:

$result = Db::getInstance()->executeS('
				SELECT c.*, cl.*
				FROM `'._DB_PREFIX_.'category` c
				'.($use_shop_restriction ? Shop::addSqlAssociation('category', 'c') : '').'
				LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').'
				'.(isset($groups) && Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON c.`id_category` = cg.`id_category`' : '').'
				'.(isset($root_category) ? 'RIGHT JOIN `'._DB_PREFIX_.'category` c2 ON c2.`id_category` = '.(int)$root_category.' AND c.`nleft` >= c2.`nleft` AND c.`nright` <= c2.`nright`' : '').'
				WHERE 1 '.$sql_filter.' '.($id_lang ? 'AND `id_lang` = '.(int)$id_lang : '').'
				'.($active ? ' AND c.`active` = 1' : '').'
				'.(isset($groups) && Group::isFeatureActive() ? ' AND cg.`id_group` IN ('.implode(',', $groups).')' : '').'
				'.(!$id_lang || (isset($groups) && Group::isFeatureActive()) ? ' GROUP BY c.`id_category`' : '').'
				'.($sql_sort != '' ? $sql_sort : ' ORDER BY c.`level_depth` ASC').'
				'.($sql_sort == '' && $use_shop_restriction ? ', category_shop.`position` ASC' : '').'
				'.($sql_limit != '' ? $sql_limit : '')
			);

And paste this instead:

$result = Db::getInstance()->executeS('SELECT c.*, cl.*
				FROM `'._DB_PREFIX_.'category` c
				'.($use_shop_restriction ? Shop::addSqlAssociation('category', 'c') : '').'
				LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').'
                                LEFT JOIN `'._DB_PREFIX_.'category_product` cp on cp.`id_category` = c.`id_category`
                                LEFT JOIN `'._DB_PREFIX_.'product_shop` ps on ps.`id_product` = cp.`id_product`
				'.(isset($groups) && Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON c.`id_category` = cg.`id_category`' : '').'
				'.(isset($root_category) ? 'RIGHT JOIN `'._DB_PREFIX_.'category` c2 ON c2.`id_category` = '.(int)$root_category.' AND c.`nleft` >= c2.`nleft` AND c.`nright` <= c2.`nright`' : '').'
				WHERE 1 '.$sql_filter.' '.($id_lang ? 'AND `id_lang` = '.(int)$id_lang : '').'
AND ps.active = 1 and ps.available_for_order = 1
				'.($active ? ' AND c.`active` = 1' : '').'
				'.(isset($groups) && Group::isFeatureActive() ? ' AND cg.`id_group` IN ('.implode(',', $groups).')' : '').'
				'.(!$id_lang || (isset($groups) && Group::isFeatureActive()) ? ' GROUP BY c.`id_category`' : '').'
				'.($sql_sort != '' ? $sql_sort : ' ORDER BY c.`level_depth` ASC').'
				'.($sql_sort == '' && $use_shop_restriction ? ', category_shop.`position` ASC' : '').'
				'.($sql_limit != '' ? $sql_limit : ''));

Its almost an alpha fix, it will only hide totally empty categories. I mean, if there is only one product and it's out of stock or inactive, it will show the category.

 

Hope this works for you or help you somehow; I need to work on my own project and version!

 

Cheers and good luck!

 

PS: Anyway, let me know if it was helpful!

PPS: the right way to do this, is by overriding Category.php and getNestedCategories!

Edited by rsaiz (see edit history)
  • Like 1
Link to comment
Share on other sites

Great news, you're welcome.

 

I think it can be improved by modifying the very same method in its last lines (a foreach function, as far as I remember) so it wont show a category if it has no products at all or inactive or out of stock; so if you ever had the time you can do it by yourself :)

Link to comment
Share on other sites

  • 1 month later...

All right, try this. In classes/Category.php locate:

$result = Db::getInstance()->executeS('
				SELECT c.*, cl.*
				FROM `'._DB_PREFIX_.'category` c
				'.($use_shop_restriction ? Shop::addSqlAssociation('category', 'c') : '').'
				LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').'
				'.(isset($groups) && Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON c.`id_category` = cg.`id_category`' : '').'
				'.(isset($root_category) ? 'RIGHT JOIN `'._DB_PREFIX_.'category` c2 ON c2.`id_category` = '.(int)$root_category.' AND c.`nleft` >= c2.`nleft` AND c.`nright` <= c2.`nright`' : '').'
				WHERE 1 '.$sql_filter.' '.($id_lang ? 'AND `id_lang` = '.(int)$id_lang : '').'
				'.($active ? ' AND c.`active` = 1' : '').'
				'.(isset($groups) && Group::isFeatureActive() ? ' AND cg.`id_group` IN ('.implode(',', $groups).')' : '').'
				'.(!$id_lang || (isset($groups) && Group::isFeatureActive()) ? ' GROUP BY c.`id_category`' : '').'
				'.($sql_sort != '' ? $sql_sort : ' ORDER BY c.`level_depth` ASC').'
				'.($sql_sort == '' && $use_shop_restriction ? ', category_shop.`position` ASC' : '').'
				'.($sql_limit != '' ? $sql_limit : '')
			);

And paste this instead:

$result = Db::getInstance()->executeS('SELECT c.*, cl.*
				FROM `'._DB_PREFIX_.'category` c
				'.($use_shop_restriction ? Shop::addSqlAssociation('category', 'c') : '').'
				LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').'
                                LEFT JOIN `'._DB_PREFIX_.'category_product` cp on cp.`id_category` = c.`id_category`
                                LEFT JOIN `'._DB_PREFIX_.'product_shop` ps on ps.`id_product` = cp.`id_product`
				'.(isset($groups) && Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON c.`id_category` = cg.`id_category`' : '').'
				'.(isset($root_category) ? 'RIGHT JOIN `'._DB_PREFIX_.'category` c2 ON c2.`id_category` = '.(int)$root_category.' AND c.`nleft` >= c2.`nleft` AND c.`nright` <= c2.`nright`' : '').'
				WHERE 1 '.$sql_filter.' '.($id_lang ? 'AND `id_lang` = '.(int)$id_lang : '').'
AND ps.active = 1 and ps.available_for_order = 1
				'.($active ? ' AND c.`active` = 1' : '').'
				'.(isset($groups) && Group::isFeatureActive() ? ' AND cg.`id_group` IN ('.implode(',', $groups).')' : '').'
				'.(!$id_lang || (isset($groups) && Group::isFeatureActive()) ? ' GROUP BY c.`id_category`' : '').'
				'.($sql_sort != '' ? $sql_sort : ' ORDER BY c.`level_depth` ASC').'
				'.($sql_sort == '' && $use_shop_restriction ? ', category_shop.`position` ASC' : '').'
				'.($sql_limit != '' ? $sql_limit : ''));

Its almost an alpha fix, it will only hide totally empty categories. I mean, if there is only one product and it's out of stock or inactive, it will show the category.

 

Hope this works for you or help you somehow; I need to work on my own project and version!

 

Cheers and good luck!

 

PS: Anyway, let me know if it was helpful!

PPS: the right way to do this, is by overriding Category.php and getNestedCategories!

 

Hi rsaiz, Hi all

Good Job, this way work fine for me...thanks....but i have a critical question...

Scenario i have a PS v. 1.6.0.5 if i make this change on classes/Category.php in my back end, when i edit one or more products, for exmample, to put Featured products this change hide also Associated categories, if i want show only Associated categories in b.e.? exist a solution?

Thanks in advance,

Best regards,

 

Daniele aka DuNdI

Link to comment
Share on other sites

  • 3 months later...

Why he don't work for me. I try to paste the code in my classes/Category.php (PS1.6)

$result = Db::getInstance()->executeS('SELECT c.*, cl.*
				FROM `'._DB_PREFIX_.'category` c
				'.($use_shop_restriction ? Shop::addSqlAssociation('category', 'c') : '').'
				LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON c.`id_category` = cl.`id_category`'.Shop::addSqlRestrictionOnLang('cl').'
                                LEFT JOIN `'._DB_PREFIX_.'category_product` cp on cp.`id_category` = c.`id_category`
                                LEFT JOIN `'._DB_PREFIX_.'product_shop` ps on ps.`id_product` = cp.`id_product`
				'.(isset($groups) && Group::isFeatureActive() ? 'LEFT JOIN `'._DB_PREFIX_.'category_group` cg ON c.`id_category` = cg.`id_category`' : '').'
				'.(isset($root_category) ? 'RIGHT JOIN `'._DB_PREFIX_.'category` c2 ON c2.`id_category` = '.(int)$root_category.' AND c.`nleft` >= c2.`nleft` AND c.`nright` <= c2.`nright`' : '').'
				WHERE 1 '.$sql_filter.' '.($id_lang ? 'AND `id_lang` = '.(int)$id_lang : '').'
AND ps.active = 1 and ps.available_for_order = 1
				'.($active ? ' AND c.`active` = 1' : '').'
				'.(isset($groups) && Group::isFeatureActive() ? ' AND cg.`id_group` IN ('.implode(',', $groups).')' : '').'
				'.(!$id_lang || (isset($groups) && Group::isFeatureActive()) ? ' GROUP BY c.`id_category`' : '').'
				'.($sql_sort != '' ? $sql_sort : ' ORDER BY c.`level_depth` ASC').'
				'.($sql_sort == '' && $use_shop_restriction ? ', category_shop.`position` ASC' : '').'
				'.($sql_limit != '' ? $sql_limit : ''));

but my empty categories show. How it's possible?

Edited by santi00 (see edit history)
Link to comment
Share on other sites

×
×
  • Create New...