Skip to content

Commit 417f21d

Browse files
committed
First pass.
1 parent 653e935 commit 417f21d

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

src/wp-includes/general-template.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4651,6 +4651,12 @@ function paginate_links( $args = '' ) {
46514651
$format = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
46524652
$format .= $wp_rewrite->using_permalinks() ? user_trailingslashit( $wp_rewrite->pagination_base . '/%#%', 'paged' ) : '?paged=%#%';
46534653

4654+
// Modify base and format default values if rewrite rules do not include a trailing slash.
4655+
if ( $wp_rewrite->using_permalinks() && ! $wp_rewrite->use_trailing_slashes ) {
4656+
$pagenum_link = str_replace( '/%_%', '%_%', $pagenum_link );
4657+
$format = '/' . ltrim( $format, '/' );
4658+
}
4659+
46544660
$defaults = array(
46554661
'base' => $pagenum_link, // http://example.com/all_posts.php%_% : %_% is replaced by format (below).
46564662
'format' => $format, // ?page=%#% : %#% is replaced by the page number.

tests/phpunit/tests/general/paginateLinks.php

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,25 @@ class Tests_General_PaginateLinks extends WP_UnitTestCase {
99

1010
private $i18n_count = 0;
1111

12+
public static $post_ids = array();
13+
14+
public static $category_id = 0;
15+
16+
public static function wpSetUpBeforeClass( $factory ) {
17+
self::$category_id = $factory->term->create(
18+
array(
19+
'taxonomy' => 'category',
20+
'name' => 'Categorized',
21+
array( 'slug' => 'categorized' ),
22+
)
23+
);
24+
25+
self::$post_ids = $factory->post->create_many( 10 );
26+
foreach ( self::$post_ids as $post_id ) {
27+
wp_set_post_categories( $post_id, array( self::$category_id ) );
28+
}
29+
}
30+
1231
public function set_up() {
1332
parent::set_up();
1433

@@ -383,4 +402,112 @@ public function test_custom_base_query_arg_should_be_stripped_from_current_url_b
383402
$page_2_url = home_url() . '?foo=2';
384403
$this->assertContains( "<a class=\"page-numbers\" href=\"$page_2_url\">2</a>", $links );
385404
}
405+
406+
/**
407+
* Ensures pagination links include trailing slashes when the permalink structure includes them.
408+
*
409+
* @ticket 61393
410+
*/
411+
public function test_permalinks_with_trailing_slash_produce_links_with_trailing_slashes() {
412+
update_option( 'posts_per_page', 2 );
413+
$this->set_permalink_structure( '/%postname%/' );
414+
415+
$this->go_to( '/category/categorized/page/2/' );
416+
417+
// For some reason current isn't picked up.
418+
$links = paginate_links( array( 'current' => 2 ) );
419+
420+
$this->assertMatchesRegularExpression( '/\/categorized\/page\/[0-9]\/"/', $links, 'Pagination links with trailing slashes should be included.' );
421+
$this->assertDoesNotMatchRegularExpression( '/\/categorized\/page\/[0-9]"/', $links, 'Pagination links without trailing slashes should not be included.' );
422+
423+
$this->assertStringContainsString( '/category/categorized/"', $links, 'The links should link to page one with a trailing slash.' );
424+
$this->assertStringNotContainsString( '/category/categorized"', $links, 'No links to page on should lack a trailing slash.' );
425+
}
426+
427+
/**
428+
* Ensures pagination links do not include trailing slashes when the permalink structure doesn't includes them.
429+
*
430+
* @ticket 61393
431+
*/
432+
public function test_permalinks_without_trailing_slash_produce_links_without_trailing_slashes() {
433+
update_option( 'posts_per_page', 2 );
434+
$this->set_permalink_structure( '/%postname%' );
435+
436+
$this->go_to( '/category/categorized/page/2' );
437+
438+
// For some reason current isn't picked up.
439+
$links = paginate_links( array( 'current' => 2 ) );
440+
441+
$this->assertDoesNotMatchRegularExpression( '/\/categorized\/page\/[0-9]\/"/', $links, 'Pagination links with trailing slashes should not be included.' );
442+
$this->assertMatchesRegularExpression( '/\/categorized\/page\/[0-9]"/', $links, 'Pagination links without trailing slashes should be included.' );
443+
444+
$this->assertStringNotContainsString( '/category/categorized/"', $links, 'The links should link to page one should not contain a trailing slash.' );
445+
$this->assertStringContainsString( '/category/categorized"', $links, 'The links to page one should not include a trailing slash.' );
446+
}
447+
448+
/**
449+
* Ensures the pagination links do not modify query strings (permalinks with trailing slash).
450+
*
451+
* @ticket 61393
452+
* @ticket 63123
453+
*
454+
* @dataProvider data_query_strings
455+
*
456+
* @param string $query_string Query string.
457+
* @param string $unexpected Unexpected query string.
458+
*/
459+
public function test_permalinks_with_trailing_slash_do_not_modify_query_strings( $query_string, $unexpected ) {
460+
update_option( 'posts_per_page', 2 );
461+
$this->set_permalink_structure( '/%postname%/' );
462+
463+
$this->go_to( "/page/2/?{$query_string}" );
464+
465+
// For some reason current isn't picked up.
466+
$links = paginate_links( array( 'current' => 2 ) );
467+
468+
$this->assertStringContainsString( "/page/3/?{$query_string}\"", $links, 'The query string should appear in the links.' );
469+
$this->assertStringNotContainsString( "/page/3/?{$unexpected}\"", $links, 'The query string should not be modified.' );
470+
}
471+
472+
/**
473+
* Ensures the pagination links do not modify query strings (permalinks without trailing slash).
474+
*
475+
* @ticket 61393
476+
* @ticket 63123
477+
*
478+
* @dataProvider data_query_strings
479+
*
480+
* @param string $query_string Query string.
481+
* @param string $unexpected Unexpected query string.
482+
*/
483+
public function test_permalinks_without_trailing_slash_do_not_modify_query_strings( $query_string, $unexpected ) {
484+
update_option( 'posts_per_page', 2 );
485+
$this->set_permalink_structure( '/%postname%' );
486+
487+
$this->go_to( "/page/2?{$query_string}" );
488+
489+
// For some reason current isn't picked up.
490+
$links = paginate_links( array( 'current' => 2 ) );
491+
492+
$this->assertStringContainsString( "/page/3?{$query_string}\"", $links, 'The query string should appear in the links.' );
493+
$this->assertStringNotContainsString( "/page/3?{$unexpected}\"", $links, 'The query string should not be modified.' );
494+
}
495+
496+
/**
497+
* Data provider for
498+
* - test_permalinks_without_trailing_slash_do_not_modify_query_strings
499+
* - test_permalinks_with_trailing_slash_do_not_modify_query_strings
500+
*
501+
* @return array[] Data provider.
502+
*/
503+
public function data_query_strings() {
504+
return array(
505+
array( 'foo=bar', 'foo=bar/' ),
506+
array( 'foo=bar', 'foo=bar%2F' ),
507+
array( 'foo=bar%2F', 'foo=bar' ),
508+
509+
array( 's=post', 's=post/' ),
510+
array( 's=post', 's=post%2F' ),
511+
);
512+
}
386513
}

0 commit comments

Comments
 (0)