WordPress Version: 6.1
/**
* Adds count of children to parent count.
*
* Recalculates term counts by including items from child terms. Assumes all
* relevant children are already in the $terms argument.
*
* @access private
* @since 2.3.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param object[]|WP_Term[] $terms List of term objects (passed by reference).
* @param string $taxonomy Term context.
*/
function _pad_term_counts(&$terms, $taxonomy)
{
global $wpdb;
// This function only works for hierarchical taxonomies like post categories.
if (!is_taxonomy_hierarchical($taxonomy)) {
return;
}
$term_hier = _get_term_hierarchy($taxonomy);
if (empty($term_hier)) {
return;
}
$term_items = array();
$terms_by_id = array();
$term_ids = array();
foreach ((array) $terms as $key => $term) {
$terms_by_id[$term->term_id] =& $terms[$key];
$term_ids[$term->term_taxonomy_id] = $term->term_id;
}
// Get the object and term IDs and stick them in a lookup table.
$tax_obj = get_taxonomy($taxonomy);
$object_types = esc_sql($tax_obj->object_type);
$results = $wpdb->get_results("SELECT object_id, term_taxonomy_id FROM {$wpdb->term_relationships} INNER JOIN {$wpdb->posts} ON object_id = ID WHERE term_taxonomy_id IN (" . implode(',', array_keys($term_ids)) . ") AND post_type IN ('" . implode("', '", $object_types) . "') AND post_status = 'publish'");
foreach ($results as $row) {
$id = $term_ids[$row->term_taxonomy_id];
$term_items[$id][$row->object_id] = isset($term_items[$id][$row->object_id]) ? ++$term_items[$id][$row->object_id] : 1;
}
// Touch every ancestor's lookup row for each post in each term.
foreach ($term_ids as $term_id) {
$child = $term_id;
$ancestors = array();
while (!empty($terms_by_id[$child]) && $parent = $terms_by_id[$child]->parent) {
$ancestors[] = $child;
if (!empty($term_items[$term_id])) {
foreach ($term_items[$term_id] as $item_id => $touches) {
$term_items[$parent][$item_id] = isset($term_items[$parent][$item_id]) ? ++$term_items[$parent][$item_id] : 1;
}
}
$child = $parent;
if (in_array($parent, $ancestors, true)) {
break;
}
}
}
// Transfer the touched cells.
foreach ((array) $term_items as $id => $items) {
if (isset($terms_by_id[$id])) {
$terms_by_id[$id]->count = count($items);
}
}
}