WordPress.org

Make WordPress Core

Ticket #15459: 15459.6.diff

File 15459.6.diff, 9.4 KB (added by johnbillion, 6 years ago)
  • src/wp-admin/includes/class-wp-posts-list-table.php

     
    8686                }
    8787        }
    8888
     89        /**
     90         * Sets whether the table layout should be hierarchical or not.
     91         *
     92         * @since 4.2.0
     93         *
     94         * @param bool $display Whether the table layout should be hierarchical.
     95         */
     96        public function set_hierarchical_display( $display ) {
     97                $this->hierarchical_display = $display;
     98        }
     99
    89100        public function ajax_user_can() {
    90101                return current_user_can( get_post_type_object( $this->screen->post_type )->cap->edit_posts );
    91102        }
     
    95106
    96107                $avail_post_stati = wp_edit_posts_query();
    97108
    98                 $this->hierarchical_display = ( is_post_type_hierarchical( $this->screen->post_type ) && 'menu_order title' == $wp_query->query['orderby'] );
     109                $this->set_hierarchical_display( is_post_type_hierarchical( $this->screen->post_type ) && 'menu_order title' == $wp_query->query['orderby'] );
    99110
    100111                $total_items = $this->hierarchical_display ? $wp_query->post_count : $wp_query->found_posts;
    101112
     
    478489                $count = 0;
    479490                $start = ( $pagenum - 1 ) * $per_page;
    480491                $end = $start + $per_page;
     492                $to_display = array();
    481493
    482494                foreach ( $pages as $page ) {
    483495                        if ( $count >= $end )
    484496                                break;
    485497
    486498                        if ( $count >= $start ) {
    487                                 echo "\t";
    488                                 $this->single_row( $page, $level );
     499                                $to_display[$page->ID] = $level;
    489500                        }
    490501
    491502                        $count++;
    492503
    493504                        if ( isset( $children_pages ) )
    494                                 $this->_page_rows( $children_pages, $count, $page->ID, $level + 1, $pagenum, $per_page );
     505                                $this->_page_rows( $children_pages, $count, $page->ID, $level + 1, $pagenum, $per_page, $to_display );
    495506                }
    496507
    497508                // If it is the last pagenum and there are orphaned pages, display them with paging as well.
     
    502513                                                break;
    503514
    504515                                        if ( $count >= $start ) {
    505                                                 echo "\t";
    506                                                 $this->single_row( $op, 0 );
     516                                                $to_display[$op->ID] = 0;
    507517                                        }
    508518
    509519                                        $count++;
    510520                                }
    511521                        }
    512522                }
     523
     524                $ids = array_keys( $to_display );
     525                _prime_post_caches( $ids );
     526
     527                if ( ! isset( $GLOBALS['post'] ) ) {
     528                        // touch_time() requires a global post set
     529                        $GLOBALS['post'] = array_shift( $ids );
     530                }
     531
     532                foreach ( $to_display as $page_id => $level ) {
     533                        echo "\t";
     534                        $this->single_row( $page_id, $level );
     535                }
    513536        }
    514537
    515538        /**
     
    524547         * @param int $level
    525548         * @param int $pagenum
    526549         * @param int $per_page
     550         * @param array $to_display list of pages to be displayed
    527551         */
    528         private function _page_rows( &$children_pages, &$count, $parent, $level, $pagenum, $per_page ) {
     552        private function _page_rows( &$children_pages, &$count, $parent, $level, $pagenum, $per_page, &$to_display ) {
    529553
    530554                if ( ! isset( $children_pages[$parent] ) )
    531555                        return;
     
    543567                                $my_parents = array();
    544568                                $my_parent = $page->post_parent;
    545569                                while ( $my_parent ) {
    546                                         $my_parent = get_post( $my_parent );
     570                                        // Get the ID from the list or the attribute if my_parent is an object
     571                                        $parent_id = $my_parent;
     572                                        if ( is_object( $my_parent ) ) {
     573                                                $parent_id = $my_parent->ID;
     574                                        }
     575
     576                                        $my_parent = get_post( $parent_id );
    547577                                        $my_parents[] = $my_parent;
    548578                                        if ( !$my_parent->post_parent )
    549579                                                break;
     
    551581                                }
    552582                                $num_parents = count( $my_parents );
    553583                                while ( $my_parent = array_pop( $my_parents ) ) {
    554                                         echo "\t";
    555                                         $this->single_row( $my_parent, $level - $num_parents );
     584                                        $to_display[$my_parent->ID] = $level - $num_parents;
    556585                                        $num_parents--;
    557586                                }
    558587                        }
    559588
    560589                        if ( $count >= $start ) {
    561                                 echo "\t";
    562                                 $this->single_row( $page, $level );
     590                                $to_display[$page->ID] = $level;
    563591                        }
    564592
    565593                        $count++;
    566594
    567                         $this->_page_rows( $children_pages, $count, $page->ID, $level + 1, $pagenum, $per_page );
     595                        $this->_page_rows( $children_pages, $count, $page->ID, $level + 1, $pagenum, $per_page, $to_display );
    568596                }
    569597
    570598                unset( $children_pages[$parent] ); //required in order to keep track of orphans
     
    579607                global $mode;
    580608
    581609                $global_post = get_post();
     610
     611                if ( is_integer( $post ) ) {
     612                        $post = get_post( $post );
     613                }
     614
    582615                $GLOBALS['post'] = $post;
    583616                setup_postdata( $post );
    584617
  • src/wp-admin/includes/post.php

     
    10391039                $query['order'] = 'asc';
    10401040                $query['posts_per_page'] = -1;
    10411041                $query['posts_per_archive_page'] = -1;
     1042                $query['fields'] = 'id=>parent';
    10421043        }
    10431044
    10441045        if ( ! empty( $q['show_sticky'] ) )
  • tests/phpunit/tests/admin/includesListTable.php

     
     1<?php
     2
     3/**
     4 * @group admin
     5 */
     6class Tests_Admin_includesListTable extends WP_UnitTestCase {
     7        function setUp() {
     8                set_current_screen( 'edit-page' );
     9                $GLOBALS['hook_suffix'] = '';
     10                $this->table = _get_list_table( 'WP_Posts_List_Table' );
     11
     12                parent::setUp();
     13
     14                // note that our top/children/grandchildren arrays are 1-indexed
     15
     16                // create top level pages
     17                $num_posts = 5;
     18                foreach ( range( 1, $num_posts ) as $i ) {
     19                        $this->top[$i] = $this->factory->post->create_and_get( array(
     20                                'post_type'  => 'page',
     21                                'post_title' => sprintf( 'Top Level Page %d', $i ),
     22                        ) );
     23                }
     24
     25                // create child pages
     26                $num_children = 3;
     27                foreach ( $this->top as $top => $top_page ) {
     28                        foreach ( range( 1, $num_children ) as $i ) {
     29                                $this->children[$top][$i] = $this->factory->post->create_and_get( array(
     30                                        'post_type'   => 'page',
     31                                        'post_parent' => $top_page->ID,
     32                                        'post_title'  => sprintf( 'Child %d', $i ),
     33                                ) );
     34                        }
     35                }
     36
     37                // create grand-child pages for the third and fourth top-level pages
     38                $num_grandchildren = 3;
     39                foreach ( range( 3, 4 ) as $top ) {
     40                        foreach ( $this->children[$top] as $child => $child_page ) {
     41                                foreach ( range( 1, $num_grandchildren ) as $i ) {
     42                                        $this->grandchildren[$top][$child][$i] = $this->factory->post->create_and_get( array(
     43                                                'post_type'   => 'page',
     44                                                'post_parent' => $child_page->ID,
     45                                                'post_title'  => sprintf( 'Grandchild %d', $i ),
     46                                        ) );
     47                                }
     48                        }
     49                }
     50        }
     51
     52        /**
     53         * @ticket 15459
     54         */
     55        function test_list_hierarchical_pages_first_page() {
     56                $this->_test_list_hierarchical_page( array(
     57                        'paged'          => 1,
     58                        'posts_per_page' => 2,
     59                ), array(
     60                        $this->top[1]->ID,
     61                        $this->children[1][1]->ID,
     62                ) );
     63        }
     64
     65        /**
     66         * @ticket 15459
     67         */
     68        function test_list_hierarchical_pages_second_page() {
     69                $this->_test_list_hierarchical_page( array(
     70                        'paged'          => 2,
     71                        'posts_per_page' => 2,
     72                ), array(
     73                        $this->top[1]->ID,
     74                        $this->children[1][2]->ID,
     75                        $this->children[1][3]->ID,
     76                ) );
     77        }
     78
     79        /**
     80         * @ticket 15459
     81         */
     82        function test_search_hierarchical_pages_first_page() {
     83                $this->_test_list_hierarchical_page( array(
     84                        'paged'          => 1,
     85                        'posts_per_page' => 2,
     86                        's'              => 'Child',
     87                ), array(
     88                        $this->children[1][1]->ID,
     89                        $this->children[1][2]->ID,
     90                ) );
     91        }
     92
     93        /**
     94         * @ticket 15459
     95         */
     96        function test_search_hierarchical_pages_second_page() {
     97                $this->_test_list_hierarchical_page( array(
     98                        'paged'          => 2,
     99                        'posts_per_page' => 2,
     100                        's'              => 'Top',
     101                ), array(
     102                        $this->top[3]->ID,
     103                        $this->top[4]->ID,
     104                ) );
     105        }
     106
     107        /**
     108         * @ticket 15459
     109         */
     110        function test_grandchildren_hierarchical_pages_first_page() {
     111                // page 6 is the first page with grandchildren
     112                $this->_test_list_hierarchical_page( array(
     113                        'paged'          => 6,
     114                        'posts_per_page' => 2,
     115                ), array(
     116                        $this->top[3]->ID,
     117                        $this->children[3][1]->ID,
     118                        $this->grandchildren[3][1][1]->ID,
     119                        $this->grandchildren[3][1][2]->ID,
     120                ) );
     121        }
     122
     123        /**
     124         * @ticket 15459
     125         */
     126        function test_grandchildren_hierarchical_pages_second_page() {
     127                // page 7 is the second page with grandchildren
     128                $this->_test_list_hierarchical_page( array(
     129                        'paged'          => 7,
     130                        'posts_per_page' => 2,
     131                ), array(
     132                        $this->top[3]->ID,
     133                        $this->children[3][1]->ID,
     134                        $this->grandchildren[3][1][3]->ID,
     135                        $this->children[3][2]->ID,
     136                ) );
     137        }
     138
     139        /**
     140         * Helper function to test the output of a page which uses `WP_Posts_List_Table`.
     141         *
     142         * @param array $args         Query args for the list of pages.
     143         * @param array $expected_ids Expected IDs of pages returned.
     144         */
     145        protected function _test_list_hierarchical_page( array $args, array $expected_ids ) {
     146                $matches = array();
     147
     148                $_REQUEST['paged']   = $args['paged'];
     149                $GLOBALS['per_page'] = $args['posts_per_page'];
     150
     151                $args = array_merge( array(
     152                        'post_type' => 'page',
     153                ), $args );
     154
     155                // Mimic the behaviour of `wp_edit_posts_query()`:
     156                if ( ! isset( $args['orderby'] ) ) {
     157                        $args['orderby']                = 'menu_order title';
     158                        $args['order']                  = 'asc';
     159                        $args['posts_per_page']         = -1;
     160                        $args['posts_per_archive_page'] = -1;
     161                }
     162
     163                $pages = new WP_Query( $args );
     164
     165                ob_start();
     166                $this->table->set_hierarchical_display( true );
     167                $this->table->display_rows( $pages->posts );
     168                $output = ob_get_clean();
     169
     170                preg_match_all( '|<tr[^>]*>|', $output, $matches );
     171
     172                $this->assertCount( count( $expected_ids ), array_keys( $matches[0] ) );
     173
     174                foreach ( $expected_ids as $id ) {
     175                        $this->assertContains( sprintf( 'id="post-%d"', $id ), $output );
     176                }
     177        }
     178
     179}