WP_Comment_Query::fill_descendants() WordPress Method

The WP_Comment_Query::fill_descendants() method is used to fill the descendants for a given comment. This is done by querying the database for all the comments that have the given comment's id as their parent id. The comments are then added to the descendants property of the given comment.

WP_Comment_Query::fill_descendants( WP_Comment[] $comments ) #

Fetch descendants for located comments.


Description

Instead of calling get_children() separately on each child comment, we do a single set of queries to fetch the descendant trees for all matched top-level comments.


Top ↑

Parameters

$comments

(WP_Comment[])(Required)Array of top-level comments whose descendants should be filled in.


Top ↑

Return

(array)


Top ↑

Source

File: wp-includes/class-wp-comment-query.php

	protected function fill_descendants( $comments ) {
		global $wpdb;

		$levels = array(
			0 => wp_list_pluck( $comments, 'comment_ID' ),
		);

		$key          = md5( serialize( wp_array_slice_assoc( $this->query_vars, array_keys( $this->query_var_defaults ) ) ) );
		$last_changed = wp_cache_get_last_changed( 'comment' );

		// Fetch an entire level of the descendant tree at a time.
		$level        = 0;
		$exclude_keys = array( 'parent', 'parent__in', 'parent__not_in' );
		do {
			// Parent-child relationships may be cached. Only query for those that are not.
			$child_ids           = array();
			$uncached_parent_ids = array();
			$_parent_ids         = $levels[ $level ];
			foreach ( $_parent_ids as $parent_id ) {
				$cache_key        = "get_comment_child_ids:$parent_id:$key:$last_changed";
				$parent_child_ids = wp_cache_get( $cache_key, 'comment' );
				if ( false !== $parent_child_ids ) {
					$child_ids = array_merge( $child_ids, $parent_child_ids );
				} else {
					$uncached_parent_ids[] = $parent_id;
				}
			}

			if ( $uncached_parent_ids ) {
				// Fetch this level of comments.
				$parent_query_args = $this->query_vars;
				foreach ( $exclude_keys as $exclude_key ) {
					$parent_query_args[ $exclude_key ] = '';
				}
				$parent_query_args['parent__in']    = $uncached_parent_ids;
				$parent_query_args['no_found_rows'] = true;
				$parent_query_args['hierarchical']  = false;
				$parent_query_args['offset']        = 0;
				$parent_query_args['number']        = 0;

				$level_comments = get_comments( $parent_query_args );

				// Cache parent-child relationships.
				$parent_map = array_fill_keys( $uncached_parent_ids, array() );
				foreach ( $level_comments as $level_comment ) {
					$parent_map[ $level_comment->comment_parent ][] = $level_comment->comment_ID;
					$child_ids[]                                    = $level_comment->comment_ID;
				}

				$data = array();
				foreach ( $parent_map as $parent_id => $children ) {
					$cache_key          = "get_comment_child_ids:$parent_id:$key:$last_changed";
					$data[ $cache_key ] = $children;
				}
				wp_cache_set_multiple( $data, 'comment' );
			}

			$level++;
			$levels[ $level ] = $child_ids;
		} while ( $child_ids );

		// Prime comment caches for non-top-level comments.
		$descendant_ids = array();
		for ( $i = 1, $c = count( $levels ); $i < $c; $i++ ) {
			$descendant_ids = array_merge( $descendant_ids, $levels[ $i ] );
		}

		_prime_comment_caches( $descendant_ids, $this->query_vars['update_comment_meta_cache'] );

		// Assemble a flat array of all comments + descendants.
		$all_comments = $comments;
		foreach ( $descendant_ids as $descendant_id ) {
			$all_comments[] = get_comment( $descendant_id );
		}

		// If a threaded representation was requested, build the tree.
		if ( 'threaded' === $this->query_vars['hierarchical'] ) {
			$threaded_comments = array();
			$ref               = array();
			foreach ( $all_comments as $k => $c ) {
				$_c = get_comment( $c->comment_ID );

				// If the comment isn't in the reference array, it goes in the top level of the thread.
				if ( ! isset( $ref[ $c->comment_parent ] ) ) {
					$threaded_comments[ $_c->comment_ID ] = $_c;
					$ref[ $_c->comment_ID ]               = $threaded_comments[ $_c->comment_ID ];

					// Otherwise, set it as a child of its parent.
				} else {

					$ref[ $_c->comment_parent ]->add_child( $_c );
					$ref[ $_c->comment_ID ] = $ref[ $_c->comment_parent ]->get_child( $_c->comment_ID );
				}
			}

			// Set the 'populated_children' flag, to ensure additional database queries aren't run.
			foreach ( $ref as $_ref ) {
				$_ref->populated_children( true );
			}

			$comments = $threaded_comments;
		} else {
			$comments = $all_comments;
		}

		return $comments;
	}


Top ↑

Changelog

Changelog
VersionDescription
4.4.0Introduced.

The content displayed on this page has been created in part by processing WordPress source code files which are made available under the GPLv2 (or a later version) license by theĀ Free Software Foundation. In addition to this, the content includes user-written examples and information. All material is subject to review and curation by the WPPaste.com community.