Make WordPress Core

Changeset 58379


Ignore:
Timestamp:
06/11/2024 02:12:52 AM (5 months ago)
Author:
peterwilsoncc
Message:

Administration: Prevent an orderby array throwing a notice.

Prevent WP_List_Table::search_box() from throwing an array to string conversion notice when post list tables are loaded with an array of orderby parameters in the URL, eg: /wp-admin/edit.php?post_type=page&orderby[menu_order]=ASC&orderby[title]=ASC.

Follow up to [29027].

Props leonidasmilossis, rajinsharwar, swissspidy, NomNom99, pls78, SergeyBiryukov.
Fixes #59494.
See #17065.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-list-table.php

    r58374 r58379  
    389389
    390390        if ( ! empty( $_REQUEST['orderby'] ) ) {
    391             echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
     391            if ( is_array( $_REQUEST['orderby'] ) ) {
     392                foreach ( $_REQUEST['orderby'] as $key => $value ) {
     393                    /*
     394                     * Orderby can be either an associative array or non-associative array.
     395                     * In the latter case, this makes sure the key is a string before calling esc_attr().
     396                     */
     397                    $key = (string) $key;
     398                    echo '<input type="hidden" name="orderby[' . esc_attr( $key ) . ']" value="' . esc_attr( $value ) . '" />';
     399                }
     400            } else {
     401                echo '<input type="hidden" name="orderby" value="' . esc_attr( $_REQUEST['orderby'] ) . '" />';
     402            }
    392403        }
    393404        if ( ! empty( $_REQUEST['order'] ) ) {
  • trunk/tests/phpunit/tests/admin/wpListTable.php

    r56542 r58379  
    522522        );
    523523    }
     524
     525    /**
     526     * Tests that "search_box()" works correctly with an orderby array with multiple values.
     527     *
     528     * @ticket 59494
     529     */
     530    public function test_search_box_working_with_array_of_orderby_multiple_values() {
     531        $_REQUEST['s']       = 'search term';
     532        $_REQUEST['orderby'] = array(
     533            'menu_order' => 'ASC',
     534            'title'      => 'ASC',
     535        );
     536
     537        $actual = get_echo( array( $this->list_table, 'search_box' ), array( 'Search Posts', 'post' ) );
     538
     539        $expected_html1 = '<input type="hidden" name="orderby[menu_order]" value="ASC" />';
     540        $expected_html2 = '<input type="hidden" name="orderby[title]" value="ASC" />';
     541
     542        $this->assertStringContainsString( $expected_html1, $actual );
     543        $this->assertStringContainsString( $expected_html2, $actual );
     544    }
     545
     546    /**
     547     * Tests that "search_box()" works correctly with an orderby array with a single value.
     548     *
     549     * @ticket 59494
     550     */
     551    public function test_search_box_working_with_array_of_orderby_single_value() {
     552        // Test with one 'orderby' element.
     553        $_REQUEST['s']       = 'search term';
     554        $_REQUEST['orderby'] = array(
     555            'title' => 'ASC',
     556        );
     557
     558        $actual = get_echo( array( $this->list_table, 'search_box' ), array( 'Search Posts', 'post' ) );
     559
     560        $expected_html = '<input type="hidden" name="orderby[title]" value="ASC" />';
     561
     562        $this->assertStringContainsString( $expected_html, $actual );
     563    }
     564
     565    /**
     566     * Tests that "search_box()" works correctly with orderby set to a string.
     567     *
     568     * @ticket 59494
     569     */
     570    public function test_search_box_works_with_orderby_string() {
     571        // Test with one 'orderby' element.
     572        $_REQUEST['s']       = 'search term';
     573        $_REQUEST['orderby'] = 'title';
     574
     575        $actual = get_echo( array( $this->list_table, 'search_box' ), array( 'Search Posts', 'post' ) );
     576
     577        $expected_html = '<input type="hidden" name="orderby" value="title" />';
     578
     579        $this->assertStringContainsString( $expected_html, $actual );
     580    }
    524581}
Note: See TracChangeset for help on using the changeset viewer.