Support » Fixing WordPress » 5/12 Nightly Bug with Empty Categories

  • In template-functions-category.php list_cats(), you’ve got:

    if (intval($hide_empty) == 1 && !isset($category_posts)) {
    $cat_counts = $wpdb->get_results(" SELECT cat_ID,
    COUNT($tablepost2cat.post_id) AS cat_count
    FROM $tablecategories
    LEFT JOIN $tablepost2cat ON (cat_ID = category_id)
    LEFT JOIN $tableposts ON (ID = post_id)
    WHERE 1 = 1 $exclusions
    GROUP BY category_id");
    foreach ($cat_counts as $cat_count) {
    $category_posts["$cat_count->cat_ID"] = $cat_count->cat_count;
    }
    }

    This code will only run if “hide categories with no posts” has
    been enabled, and that is the default setting. As such, outta
    the box, the above code is being run.
    Outta the box, however, the lowest ID’d empty category will
    always display in wp_list_cats. skippy_ and I had a big discussion
    about this on IRC around this timestamp, we confirmed it, and brux eventually waltzed in and fixed it for us.
    To duplicate the bug:
    a) Fresh install of the 5/12 nightly.
    b) “General” has two posts in it.
    c) Add a new category “Bob”. No posts.
    d) “Bob” should appear in the category list for the
    web visitor templates, even though it shouldn’t.
    e) Add a new category “Fred”. No posts.
    f) “Bob” still displays, but “Fred” doesn’t.
    The SQL above, when run at the shell, returns something like:

    +--------+-----------+
    | cat_ID | cat_count |
    +--------+-----------+
    | 1 | 2 |
    | 5 | 0 |
    +--------+-----------+
    2 rows in set (0.00 sec)

    In this case, cat_ID#1 is General with 2 posts, and cat_ID#5 is
    an empty category. ID’s 6 and 7 actually exist, and they have no
    posts, but they do not show up in the list.
    The incorrect showing of the category is actually caused later
    on by a conditional in the “should we show this category?” code:

    foreach ($categories as $category) {
    if ((intval($hide_empty) == 0 ||
    isset($category_posts["$category->cat_ID"]))
    && (!$children || $category->category_parent == $child_of)) {

    The above is two lines in the code, I’ve just spliced ’em up here
    for readability. Here, you’re checking merely for the existence
    of a category_post ID, not if cat_count was actually a non-zero
    number. Since the post ID existed (see the above SQL), the category was displayed.
    The fix is simple, was suggested by brux, and confirmed by myself
    and skippy (dunno what brux was using, but skippy and I were using MySQL 4.0.12 and .17 respectively). Instead of using LEFT JOINS, use INNER JOINS instead:
    <brux> change both left join to inner join
    <brux> and see if it does what you want
    <brux> left join includes everything even if there isn’t a match
    <brux> and you don’t want that
    So, thus, your code becomes:

    if (intval($hide_empty) == 1 && !isset($category_posts)) {
    $cat_counts = $wpdb->get_results(" SELECT cat_ID,
    COUNT($tablepost2cat.post_id) AS cat_count
    FROM $tablecategories
    INNER JOIN $tablepost2cat ON (cat_ID = category_id)
    INNER JOIN $tableposts ON (ID = post_id)
    WHERE 1 = 1 $exclusions
    GROUP BY category_id");
    foreach ($cat_counts as $cat_count) {
    $category_posts["$cat_count->cat_ID"] = $cat_count->cat_count;
    }
    }

    I’ve sent this to you through email as well.
    Thanks!

Viewing 2 replies - 1 through 2 (of 2 total)
Viewing 2 replies - 1 through 2 (of 2 total)
  • The topic ‘5/12 Nightly Bug with Empty Categories’ is closed to new replies.