get_page_hierarchy()WP 2.0.0

Order the pages with children under parents in a flat list.

It uses auxiliary structure to hold parent-children relationships and runs in O(N) complexity

1 time — 0.000018 sec (very fast) | 50000 times — 0.18 sec (very fast) | PHP 7.0.8, WP 4.6

No Hooks.

Return

String[]. Array of post names keyed by ID and arranged by hierarchy. Children immediately follow their parents.

Usage

get_page_hierarchy( $pages, $page_id );
$pages(WP_Post[]) (required) (passed by reference — &)
Posts array (passed by reference).
$page_id(int)
Parent page ID.

Examples

0

#1 Tree sorting demonstration

To make it clearer, I removed most of the fields that each post has. There are 3 fields involved in this sorting: ID, post_parent, and post_name.

So what does the function do? As you can see from the example, we had an array of posts where one post is a child of another. But the order of these posts in the array is chaotic.

This function sorts all the elements in the array so that each next element is a child of the previous one. After that, the function creates a new array and puts the posts ID in the key of this array, and the posts slug (post_name) is placed in the value. As a result, we can easily create a tree of posts using the resulting array...

$pages = array(
  (object) array(
	 'ID'            => 111,
	 'post_name'     => 'hooks',
	 'post_parent'   => 0,
  ),
  (object) array(
	 'ID'            => 222,
	 'post_name'     => 'comment-manager',
	 'post_parent'   => 444,
  ),
  (object) array(
	 'ID'            => 333,
	 'post_name'     => 'statistics',
	 'post_parent'   => 444,
  ),
  (object) array(
	 'ID'            => 444,
	 'post_name'     => 'resursyi-o-wordpress',
	 'post_parent'   => 111,
  ),
);

$pages = get_page_hierarchy( $pages );

/* $pages will be equal to:
Array
(
	[111] => hooks
	[444] => resursyi-o-wordpress
	[222] => comment-manager
	[333] => statistics
)
*/

Changelog

Since 2.0.0 Introduced.

get_page_hierarchy() code WP 6.4.3

function get_page_hierarchy( &$pages, $page_id = 0 ) {
	if ( empty( $pages ) ) {
		return array();
	}

	$children = array();
	foreach ( (array) $pages as $p ) {
		$parent_id                = (int) $p->post_parent;
		$children[ $parent_id ][] = $p;
	}

	$result = array();
	_page_traverse_name( $page_id, $children, $result );

	return $result;
}