WordPress.org

Make WordPress Core

Changeset 31203


Ignore:
Timestamp:
01/16/2015 03:48:24 PM (5 years ago)
Author:
boonebgorges
Message:

In paginate_links(), don't override custom format arguments when setting up default 'add_args'.

Since 4.1 [29780], the default value of the 'add_args' argument in
paginate_links() has been determined by parsing the current URL. This change
had the side effect of overriding custom values of 'format' that changed the
pagination query var, with the result that plugins using paginate_links()
with a custom format generated the incorrect links unless explicitly
declaring 'add_args=false' to prevent the default values from overriding. We
fix this behavior by parsing URL query vars into the 'add_args' array only
after the explicit function params have been parsed, and by skipping the
current page's pagination query var when doing this parsing (to avoid the
override).

Props obenland.
Fixes #30831 for trunk.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/general-template.php

    r31188 r31203  
    25832583    global $wp_query, $wp_rewrite;
    25842584
    2585     $total        = ( isset( $wp_query->max_num_pages ) ) ? $wp_query->max_num_pages : 1;
    2586     $current      = ( get_query_var( 'paged' ) ) ? intval( get_query_var( 'paged' ) ) : 1;
     2585    // Setting up default values based on the current URL.
    25872586    $pagenum_link = html_entity_decode( get_pagenum_link() );
    2588     $query_args   = array();
    25892587    $url_parts    = explode( '?', $pagenum_link );
    25902588
    2591     if ( isset( $url_parts[1] ) ) {
    2592         wp_parse_str( $url_parts[1], $query_args );
    2593         $query_args = urlencode_deep( $query_args );
    2594     }
    2595 
    2596     $pagenum_link = remove_query_arg( array_keys( $query_args ), $pagenum_link );
    2597     $pagenum_link = trailingslashit( $pagenum_link ) . '%_%';
    2598 
     2589    // Get max pages and current page out of the current query, if available.
     2590    $total   = isset( $wp_query->max_num_pages ) ? $wp_query->max_num_pages : 1;
     2591    $current = get_query_var( 'paged' ) ? intval( get_query_var( 'paged' ) ) : 1;
     2592
     2593    // Append the format placeholder to the base URL.
     2594    $pagenum_link = trailingslashit( $url_parts[0] ) . '%_%';
     2595
     2596    // URL base depends on permalink settings.
    25992597    $format  = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
    26002598    $format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%';
     
    26122610        'mid_size' => 2,
    26132611        'type' => 'plain',
    2614         'add_args' => $query_args, // array of query args to add
     2612        'add_args' => array(), // array of query args to add
    26152613        'add_fragment' => '',
    26162614        'before_page_number' => '',
     
    26192617
    26202618    $args = wp_parse_args( $args, $defaults );
     2619
     2620    // Merge additional query vars found in the original URL into 'add_args' array.
     2621    if ( isset( $url_parts[1] ) ) {
     2622        // Find the format argument.
     2623        $format_query = parse_url( str_replace( '%_%', $args['format'], $args['base'] ), PHP_URL_QUERY );
     2624        wp_parse_str( $format_query, $format_arg );
     2625
     2626        // Remove the format argument from the array of query arguments, to avoid overwriting custom format.
     2627        wp_parse_str( remove_query_arg( array_keys( $format_arg ), $url_parts[1] ), $query_args );
     2628        $args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $query_args ) );
     2629    }
    26212630
    26222631    // Who knows what else people pass in $args
  • trunk/tests/phpunit/tests/general/paginateLinks.php

    r30133 r31203  
    230230        }
    231231    }
     232
     233    /**
     234     * @ticket 30831
     235     */
     236    function test_paginate_links_with_custom_query_args() {
     237        add_filter( 'get_pagenum_link', array( $this, 'add_query_arg' ) );
     238        $links = paginate_links( array(
     239            'current'  => 2,
     240            'total'    => 5,
     241            'end_size' => 1,
     242            'mid_size' => 1,
     243            'type'     => 'array',
     244            'add_args' => array(
     245                'baz' => 'qux',
     246            ),
     247        ) );
     248        remove_filter( 'get_pagenum_link', array( $this, 'add_query_arg' ) );
     249
     250        $document = new DOMDocument();
     251        $document->preserveWhiteSpace = false;
     252
     253        $data = array(
     254            0 => home_url( '/?baz=qux&foo=bar&s=search+term' ),
     255            1 => home_url( '/?baz=qux&foo=bar&s=search+term' ),
     256            3 => home_url( '/?paged=3&baz=qux&foo=bar&s=search+term' ),
     257            5 => home_url( '/?paged=5&baz=qux&foo=bar&s=search+term' ),
     258            6 => home_url( '/?paged=3&baz=qux&foo=bar&s=search+term' ),
     259        );
     260
     261        foreach ( $data as $index => $expected_href ) {
     262            $document->loadHTML( $links[ $index ] );
     263            $tag = $document->getElementsByTagName( 'a' )->item( 0 );
     264            $this->assertNotNull( $tag );
     265
     266            $href = $tag->attributes->getNamedItem( 'href' )->value;
     267            $this->assertEquals( $expected_href, $href );
     268        }
     269    }
     270
     271    /**
     272     * @ticket 30831
     273     */
     274    public function test_paginate_links_should_allow_non_default_format_without_add_args() {
     275        // Fake the query params.
     276        $request_uri = $_SERVER['REQUEST_URI'];
     277        $_SERVER['REQUEST_URI'] = add_query_arg( 'foo', 3, home_url() );
     278
     279        $links = paginate_links( array(
     280            'base'    => add_query_arg( 'foo', '%#%' ),
     281            'format'  => '',
     282            'total'   => 5,
     283            'current' => 3,
     284            'type'    => 'array',
     285        ) );
     286
     287        $this->assertContains( '?foo=1', $links[1] );
     288        $this->assertContains( '?foo=2', $links[2] );
     289        $this->assertContains( '?foo=4', $links[4] );
     290        $this->assertContains( '?foo=5', $links[5] );
     291
     292        $_SERVER['REQUEST_URI'] = $request_uri;
     293    }
    232294}
Note: See TracChangeset for help on using the changeset viewer.