WordPress.org

Make WordPress Core

Ticket #11847: fix-counts.php

File fix-counts.php, 2.0 KB (added by fwiffo, 6 years ago)

workaround filter on get_terms

Line 
1<?php
2
3        function fix_term_count($terms, $taxonomies, $args) { # {{{
4                # Currently, when get_terms is used with a custom taxonomy, it returns
5                # a count value that includes unpublished content. So wp_tag_cloud will
6                # produce unexpected results. The tooltip will show the count including
7                # unpublished content, but the page it links to will only show published
8                # items. If a term is only attached to unpublished content, then it'll
9                # be a 404, which is even worse. So this filter does its own query to
10                # get an accurate count and filters things accordingly.
11
12                # This may be unnecessary in a future WordPress version.
13
14                if (!$args['fix_counts'])
15                        return $terms;
16
17                global $wpdb;
18
19                $term_ids = array();
20                foreach ($terms as $term)
21                        $term_ids[] = $term->term_id;
22
23                $posts_where = "AND $wpdb->posts.post_type != 'revision' AND (($wpdb->posts.post_status = 'publish') OR ($wpdb->posts.post_status = 'inherit' AND (p2.post_status = 'publish')))";
24                $posts_where = apply_filters('posts_where', $posts_where);
25
26                $query = "
27                        SELECT COUNT(1) as count, t.term_id
28                                FROM $wpdb->terms AS t
29                                INNER JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id
30                                INNER JOIN $wpdb->term_relationships AS tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
31                                INNER JOIN $wpdb->posts ON $wpdb->posts.ID = tr.object_id
32                                LEFT JOIN $wpdb->posts AS p2 on $wpdb->posts.post_parent = p2.ID
33                                WHERE t.term_id IN (".join(', ', $term_ids).")
34                                        $posts_where
35                                GROUP BY t.name, t.term_id, tt.parent
36                                ";
37
38                $counts = $wpdb->get_results($query);
39                $_terms = array();
40                $_counts = array();
41                foreach ($counts as $c)
42                        $_counts[$c->term_id] = $c->count;
43
44                foreach ($terms as $t) {
45                        if (!$_counts[$t->term_id]) {
46                                if ($args['hide_empty'])
47                                        continue;
48                                $t->count = 0;
49                        } else {
50                                $t->count = $_counts[$t->term_id];
51                        }
52                        $_terms[] = $t;
53                }
54
55                # TODO: Worry about hierarchy and padding parent counts or just be
56                # satisifed knowing that I didn't set up any of my taxonomies as
57                # hierarchical?
58
59                return $_terms;
60        } # }}}
61
62# vim:noet:ts=4