WordPress.org

Make WordPress Core

Ticket #10852: new_get_page_children.3.diff

File new_get_page_children.3.diff, 4.6 KB (added by santagada, 5 years ago)

new version with tests

  • src/wp-includes/post.php

    diff --git src/wp-includes/post.php src/wp-includes/post.php
    index 88c5802..20bbf6c 100644
    function get_page_by_title( $page_title, $output = OBJECT, $post_type = 'page' ) 
    43114311 * children for the same to retrieve all children of a page. Does not make any
    43124312 * SQL queries to get the children.
    43134313 *
     4314 * It uses auxiliary structure to hold parent-children relationships and
     4315 * runs in O(N) complexity
     4316 *
    43144317 * @since 1.5.1
    43154318 *
    43164319 * @param int   $page_id    Page ID.
    function get_page_by_title( $page_title, $output = OBJECT, $post_type = 'page' ) 
    43184321 * @return array List of page children.
    43194322 */
    43204323function get_page_children( $page_id, $pages ) {
    4321         $page_list = array();
    4322         foreach ( (array) $pages as $page ) {
    4323                 if ( $page->post_parent == $page_id ) {
    4324                         $page_list[] = $page;
    4325                         if ( $children = get_page_children( $page->ID, $pages ) ) {
    4326                                 $page_list = array_merge( $page_list, $children );
     4324        // build a hash of ID -> children
     4325        $children = array();
     4326        foreach ( (array) $pages as $p ) {
     4327                $children[ intval( $p->post_parent ) ][] = $p;
     4328        }
     4329
     4330        $post_list = array();
     4331        if( array_key_exists( $page_id, $children ) ) {
     4332                $to_look = array_reverse( $children[ $page_id ] );
     4333                // while we still have posts to_look add them to the list
     4334                while ( $to_look ) {
     4335                        $p = array_pop( $to_look );
     4336                        $post_list[] = $p;
     4337                        if ( array_key_exists( $p->ID, $children ) ) {
     4338                                foreach ( array_reverse( $children[ $p->ID ] ) as $child ) {
     4339                                        $to_look[] = $child;
     4340                                }
    43274341                        }
    43284342                }
    43294343        }
    43304344
    4331         return $page_list;
     4345        return $post_list;
    43324346}
    43334347
    43344348/**
  • new file tests/phpunit/tests/post/getPageChildren.php

    diff --git tests/phpunit/tests/post/getPageChildren.php tests/phpunit/tests/post/getPageChildren.php
    new file mode 100644
    index 0000000..949c854
    - +  
     1<?php
     2
     3/**
     4 * @group post
     5 */
     6
     7class Tests_Post_getPageChildren extends WP_UnitTestCase {
     8        function setUp() {
     9                parent::setUp();
     10        }
     11
     12        function test_get_hierarchical_ordering() {
     13        $page_1 = $this->factory->post->create( array( 'post_type' => 'page' ) );
     14        $page_2 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_1 ) );
     15        $page_3 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_1 ) );
     16        $page_4 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_2 ) );
     17
     18        /*
     19         * Here's the tree we are testing:
     20         *
     21         * page 1
     22         * - page 2
     23         * -- page 4
     24         * - page 3
     25         *
     26         * If hierarchical => true works, the order will be 1,2,4,3.
     27         * If it doesn't, they will be in the creation order, 1,2,3,4.
     28         */
     29
     30        $pages = get_pages();
     31
     32        $ordered_pages = get_page_children( 0, $pages );
     33        $this->assertEqualSets( array($page_1, $page_2, $page_4, $page_3 ), wp_list_pluck( $ordered_pages, 'ID' ) );
     34        $ordered_pages = get_page_children( $page_1, $pages );
     35        $this->assertEqualSets( array($page_2, $page_4, $page_3 ), wp_list_pluck( $ordered_pages, 'ID' ) );
     36        $ordered_pages = get_page_children( $page_2, $pages );
     37        $this->assertEqualSets( array( $page_4 ), wp_list_pluck( $ordered_pages, 'ID' ) );
     38        $ordered_pages = get_page_children( $page_4, $pages );
     39        $this->assertEqualSets( array(), wp_list_pluck( $ordered_pages, 'ID' ) );
     40        }
     41
     42    function test_get_missing_parent() {
     43        $page_1 = $this->factory->post->create( array( 'post_type' => 'page' ) );
     44        $page_2 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_1 ) );
     45        $page_3 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_1 ) );
     46        $page_4 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_2 ) );
     47
     48        $pages = get_pages();
     49
     50        $ordered_pages = get_page_children( -1, $pages );
     51        $this->assertEqualSets( array(), $ordered_pages );
     52
     53    }
     54
     55    function test_get_outside_parent() {
     56        $page_1 = $this->factory->post->create( array( 'post_type' => 'page' ) );
     57        $page_2 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_1 ) );
     58        $page_3 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_1 ) );
     59        $page_4 = $this->factory->post->create( array( 'post_type' => 'page', 'post_parent' => $page_2 ) );
     60
     61        $pages = get_posts( array( $page_2, $page_4 ) );
     62
     63        $ordered_pages = get_page_children($page_3, $pages );
     64        $this->assertEqualSets( array(), $ordered_pages );
     65    }
     66}