函数文档

_pad_term_counts()

💡 云策文档标注

概述

_pad_term_counts() 是一个 WordPress 内部函数,用于重新计算分层分类法(如文章分类)中术语的计数,通过将子术语的项目数量累加到父术语中。它假设所有相关子术语已通过引用传递在 $terms 参数中。

关键要点

  • 函数作用:重新计算术语计数,将子术语的项目(如文章)数量添加到父术语的计数中。
  • 适用条件:仅适用于分层分类法(如 is_taxonomy_hierarchical() 返回 true),否则函数直接返回。
  • 参数:$terms(必需,术语对象数组,按引用传递)和 $taxonomy(必需,分类法名称字符串)。
  • 内部流程:通过数据库查询获取对象与术语关系,使用递归方式遍历祖先术语以更新计数。
  • 相关函数:依赖 _get_term_hierarchy()、is_taxonomy_hierarchical()、get_taxonomy() 和 wpdb::get_results() 等辅助函数。

代码示例

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 );
        }
    }
}

注意事项

  • 此函数是内部函数,通常由 WP_Term_Query::get_terms() 调用,不建议在插件或主题中直接使用。
  • 函数假设 $terms 参数包含所有相关子术语,且通过引用传递,会直接修改传入的术语对象数组。
  • 仅处理已发布的文章(post_status = 'publish'),其他状态的文章不计入。
  • 从 WordPress 2.3.0 版本引入,是核心功能的一部分。

📄 原文内容

Adds count of children to parent count.

Description

Recalculates term counts by including items from child terms. Assumes all relevant children are already in the $terms argument.

Parameters

$termsobject[]|WP_Term[]required
List of term objects (passed by reference).
$taxonomystringrequired
Term context.

Source

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 );
		}
	}
}

Changelog

Version Description
2.3.0 Introduced.