- b2evolution CMS Support Forums
- b2evolution Support
- Plugins & Extensions
- [Hack] Hide empty categories
1 rmazoyer Mar 30, 2007 11:26
Hello,
I've modified [url=http://www.petitbourgeois.com/]my install[/url] of 1.9.3 to hide empty categories from the cat list. Rationale goes like this: I use my blog both for private and public publishing, and some categories are used only by private posts -- they're useless for non-identified visitors.
So I want to hide categories that contain no posts. However, categories are hierarchically organized, and a parent cat might have no posts while its children do -- that parent would need to be displayed. So a simple test on cat_postcount would not work.
So what does this hack precisely do?
- makes available in $cache_categories, a cumulative count of posts visible to the current user, contained by each category AND its children (called cat_postcount_subs)
- makes available in $cache_categories, a cumulative count of posts with status "published", contained by each category AND its children (called cat_postcount_pubsubs)
- hides categories that contain no posts visible to the current user
- hides categories that contain no published posts when generating the static version of a blog's home page
This is a hack, I've had to modify a core file (_category.funcs.php) so it's a pretty brittle solution. I am not sure if the maintainers will consider it good enough to integrate in the main code. Actually, I suspect there are more elegant ways to achieve what I did in that file (the extra SQL query is probably superfluous) but I'm just too lazy to take care of that aspect just now -- and it works.
The code
In inc/MODEL/collections/_category.funcs.php
line 329, under
$this_cat['cat_postcount'] = 0;
ADD
$this_cat['cat_postcount_subs'] = 0;
$this_cat['cat_postcount_pubsubs'] = 0;
line 446, under
$cache_categories[$cat_ID]['cat_postcount'] = $myrow['cat_postcount'];
ADD
$cache_categories[$cat_ID]['cat_postcount_subs'] = $myrow['cat_postcount'];
line 450, under
$ItemQuery = & new ItemQuery( $dbtable, $dbprefix, $dbIDname );
ADD
$ItemQuery->where_chapter( $blog, '', array() );
// * Restrict to only published posts
$ItemQuery->where_visibility( array('published') );
$ItemQuery->where_datestart( '', '', '', '', $timestamp_min, $timestamp_max );
$sql = 'SELECT postcat_cat_ID AS cat_ID, COUNT(*) AS cat_postcount'
.$ItemQuery->get_from()
.$ItemQuery->get_where()
.$ItemQuery->get_group_by()."
GROUP BY cat_ID";
foreach( $DB->get_results( $sql, ARRAY_A, 'Load postcounts' ) as $myrow )
{
$cat_ID = $myrow['cat_ID'];
if( !isset($cache_categories[$cat_ID]) )
echo '<p>*** WARNING: There are '.$myrow['cat_postcount'].' posts attached to non existant category #'.$cat_ID.'. You must fix the database! ***</p>';
// echo 'Postcount for cat #', $cat_ID, ' is ', $myrow['cat_postcount'], '<br />';
$cache_categories[$cat_ID]['cat_postcount_pubsubs'] = $myrow['cat_postcount'];
}
foreach( $cache_categories as $cat_ID => $onecat )
{ // Now let's bubble them up
$thisID = $cat_ID;
// echo 'Processing cat #'.$thisID.': ';
while ($cache_categories[$thisID]['cat_parent_ID'] > 0) {
$parentID = $cache_categories[$thisID]['cat_parent_ID'];
$cache_categories[$parentID]['cat_postcount_subs'] += $cache_categories[$cat_ID]['cat_postcount'];
$cache_categories[$parentID]['cat_postcount_pubsubs'] += $cache_categories[$cat_ID]['cat_postcount_pubsubs'];
// echo 'parent #', $parentID, ' is now ', $cache_categories[$parentID]['cat_postcount_subs'], '; ';
$thisID = $parentID;
}
// echo '.<br/>';
}
Categories now expose the following properties:
- cat_postcount_subs (count of posts in current category and its children)
- cat_postcount_pubsubs (count of published posts in current category and its children)
Now let's use those values in the categories display plugin:
In plugins/_categories.plugin.php
line 86, in the options description, ADD
* - 'option_hide_empty' : true|false (Default: true)
line 138, under
if(!isset($params['option_all'])) $params['option_all'] = T_('All');
ADD
// Hide empty categories?
if(!isset($params['option_hide_empty'])) $params['option_hide_empty'] = true;
line 272, under
$cat = get_the_category_by_ID( $cat_ID );
ADD
global $generating_static;
if (($cat['cat_postcount_subs'] < 1 || ($cat['cat_postcount_pubsubs'] < 1 && !empty($generating_static))) && $this->params['option_hide_empty'])
{ // Skip empty cats
return '';
}
Feedback most welcome: maybe I've done something that was already there and I didn't notice, or maybe I've done it in an inefficient way (that's quite likely, in fact). I hope it helps, though!
Best,
Raphaƫl