_update_post_term_count()WP 2.3.0

Updates the number of posts attached to a term (taxonomy element). The types of posts to consider are taken from the taxonomy settings.

The function is responsible for updating the post count in the term (tags or categories) for a specific taxonomy related to posts. The function counts the number of posts associated with each term and updates this value in the database.

Such updates occur automatically when creating/updating a post linked to the taxonomy or when adding/removing a term.

Internal function — this function is designed to be used by the kernel itself. It is not recommended to use this function in your code.

Returns

null. Nothing (null).

Usage

_update_post_term_count( $terms, $taxonomy );
$terms(int[]) (required)
Array of numbers from the term_taxonomy_id field of the wp_term_relationships table.
Since WP 4.4 it should match the term ID. Read more here.
$taxonomy(WP_Taxonomy) (required)
Taxonomy object, the terms of which are specified in the previous parameter.

Examples

2

#1 Demo

Since _update_post_term_count() is an internal WordPress function and it is dangerous to use it directly in theme or plugin code, the example of using this function is based on its application within the function register_taxonomy().

In the example, a new taxonomy "genre" is created for post entries, and the function _update_post_term_count() is used to count the number of posts associated with each term in this taxonomy.

add_action( 'init', 'create_book_tax' );

function create_book_tax() {
  register_taxonomy(
	  'genre',
	  'post',
	  array(
		  'label' => __( 'Genre' ),
		  'rewrite' => array( 'slug' => 'genre' ),
		  'update_count_callback' => '_update_post_term_count',
	  )
  );
}

In this example, _update_post_term_count will be called immediately after the number of posts associated with any term from the “genre” taxonomy is changed, ensuring an accurate count of associated posts for each term.

Notes

  • Global. wpdb. $wpdb WordPress database abstraction object.

Changelog

Since 2.3.0 Introduced.

_update_post_term_count() code WP 6.9.1

function _update_post_term_count( $terms, $taxonomy ) {
	global $wpdb;

	$object_types = (array) $taxonomy->object_type;

	foreach ( $object_types as &$object_type ) {
		list( $object_type ) = explode( ':', $object_type );
	}

	$object_types = array_unique( $object_types );

	$check_attachments = array_search( 'attachment', $object_types, true );
	if ( false !== $check_attachments ) {
		unset( $object_types[ $check_attachments ] );
		$check_attachments = true;
	}

	if ( $object_types ) {
		$object_types = esc_sql( array_filter( $object_types, 'post_type_exists' ) );
	}

	$post_statuses = array( 'publish' );

	/**
	 * Filters the post statuses for updating the term count.
	 *
	 * @since 5.7.0
	 *
	 * @param string[]    $post_statuses List of post statuses to include in the count. Default is 'publish'.
	 * @param WP_Taxonomy $taxonomy      Current taxonomy object.
	 */
	$post_statuses = esc_sql( apply_filters( 'update_post_term_count_statuses', $post_statuses, $taxonomy ) );

	foreach ( (array) $terms as $tt_id ) {
		$count = 0;

		// Attachments can be 'inherit' status, we need to base count off the parent's status if so.
		if ( $check_attachments ) {
			// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration
			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts p1 WHERE p1.ID = $wpdb->term_relationships.object_id AND ( post_status IN ('" . implode( "', '", $post_statuses ) . "') OR ( post_status = 'inherit' AND post_parent > 0 AND ( SELECT post_status FROM $wpdb->posts WHERE ID = p1.post_parent ) IN ('" . implode( "', '", $post_statuses ) . "') ) ) AND post_type = 'attachment' AND term_taxonomy_id = %d", $tt_id ) );
		}

		if ( $object_types ) {
			// phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.QuotedDynamicPlaceholderGeneration
			$count += (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_relationships, $wpdb->posts WHERE $wpdb->posts.ID = $wpdb->term_relationships.object_id AND post_status IN ('" . implode( "', '", $post_statuses ) . "') AND post_type IN ('" . implode( "', '", $object_types ) . "') AND term_taxonomy_id = %d", $tt_id ) );
		}

		/**
		 * Fires when a term count is calculated, before it is updated in the database.
		 *
		 * @since 6.9.0
		 *
		 * @param int    $tt_id         Term taxonomy ID.
		 * @param string $taxonomy_name Taxonomy slug.
		 * @param int    $count         Term count.
		 */
		do_action( 'update_term_count', $tt_id, $taxonomy->name, $count );

		/** This action is documented in wp-includes/taxonomy.php */
		do_action( 'edit_term_taxonomy', $tt_id, $taxonomy->name );
		$wpdb->update( $wpdb->term_taxonomy, compact( 'count' ), array( 'term_taxonomy_id' => $tt_id ) );

		/** This action is documented in wp-includes/taxonomy.php */
		do_action( 'edited_term_taxonomy', $tt_id, $taxonomy->name );
	}
}