Skip to content

Commit 5c93224

Browse files
committed
First pass.
1 parent 50bb23e commit 5c93224

2 files changed

Lines changed: 133 additions & 0 deletions

File tree

src/wp-includes/general-template.php

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

4646+
// Modify base and format default values if rewrite rules do not include a trailing slash.
4647+
if ( $wp_rewrite->using_permalinks() && ! $wp_rewrite->use_trailing_slashes ) {
4648+
$pagenum_link = str_replace( '/%_%', '%_%', $pagenum_link );
4649+
$format = '/' . ltrim( $format, '/' );
4650+
}
4651+
46464652
$defaults = array(
46474653
'base' => $pagenum_link, // http://example.com/all_posts.php%_% : %_% is replaced by format (below).
46484654
'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

@@ -362,4 +381,112 @@ public function test_custom_base_query_arg_should_be_stripped_from_current_url_b
362381
$page_2_url = home_url() . '?foo=2';
363382
$this->assertContains( "<a class=\"page-numbers\" href=\"$page_2_url\">2</a>", $links );
364383
}
384+
385+
/**
386+
* Ensures pagination links include trailing slashes when the permalink structure includes them.
387+
*
388+
* @ticket 61393
389+
*/
390+
public function test_permalinks_with_trailing_slash_produce_links_with_trailing_slashes() {
391+
update_option( 'posts_per_page', 2 );
392+
$this->set_permalink_structure( '/%postname%/' );
393+
394+
$this->go_to( '/category/categorized/page/2/' );
395+
396+
// For some reason current isn't picked up.
397+
$links = paginate_links( array( 'current' => 2 ) );
398+
399+
$this->assertMatchesRegularExpression( '/\/categorized\/page\/[0-9]\/"/', $links, 'Pagination links with trailing slashes should be included.' );
400+
$this->assertDoesNotMatchRegularExpression( '/\/categorized\/page\/[0-9]"/', $links, 'Pagination links without trailing slashes should not be included.' );
401+
402+
$this->assertStringContainsString( '/category/categorized/"', $links, 'The links should link to page one with a trailing slash.' );
403+
$this->assertStringNotContainsString( '/category/categorized"', $links, 'No links to page on should lack a trailing slash.' );
404+
}
405+
406+
/**
407+
* Ensures pagination links do not include trailing slashes when the permalink structure doesn't includes them.
408+
*
409+
* @ticket 61393
410+
*/
411+
public function test_permalinks_without_trailing_slash_produce_links_without_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->assertDoesNotMatchRegularExpression( '/\/categorized\/page\/[0-9]\/"/', $links, 'Pagination links with trailing slashes should not be included.' );
421+
$this->assertMatchesRegularExpression( '/\/categorized\/page\/[0-9]"/', $links, 'Pagination links without trailing slashes should be included.' );
422+
423+
$this->assertStringNotContainsString( '/category/categorized/"', $links, 'The links should link to page one should not contain a trailing slash.' );
424+
$this->assertStringContainsString( '/category/categorized"', $links, 'The links to page one should not include a trailing slash.' );
425+
}
426+
427+
/**
428+
* Ensures the pagination links do not modify query strings (permalinks with trailing slash).
429+
*
430+
* @ticket 61393
431+
* @ticket 63123
432+
*
433+
* @dataProvider data_query_strings
434+
*
435+
* @param string $query_string Query string.
436+
* @param string $unexpected Unexpected query string.
437+
*/
438+
public function test_permalinks_with_trailing_slash_do_not_modify_query_strings( $query_string, $unexpected ) {
439+
update_option( 'posts_per_page', 2 );
440+
$this->set_permalink_structure( '/%postname%/' );
441+
442+
$this->go_to( "/page/2/?{$query_string}" );
443+
444+
// For some reason current isn't picked up.
445+
$links = paginate_links( array( 'current' => 2 ) );
446+
447+
$this->assertStringContainsString( "/page/3/?{$query_string}\"", $links, 'The query string should appear in the links.' );
448+
$this->assertStringNotContainsString( "/page/3/?{$unexpected}\"", $links, 'The query string should not be modified.' );
449+
}
450+
451+
/**
452+
* Ensures the pagination links do not modify query strings (permalinks without trailing slash).
453+
*
454+
* @ticket 61393
455+
* @ticket 63123
456+
*
457+
* @dataProvider data_query_strings
458+
*
459+
* @param string $query_string Query string.
460+
* @param string $unexpected Unexpected query string.
461+
*/
462+
public function test_permalinks_without_trailing_slash_do_not_modify_query_strings( $query_string, $unexpected ) {
463+
update_option( 'posts_per_page', 2 );
464+
$this->set_permalink_structure( '/%postname%' );
465+
466+
$this->go_to( "/page/2?{$query_string}" );
467+
468+
// For some reason current isn't picked up.
469+
$links = paginate_links( array( 'current' => 2 ) );
470+
471+
$this->assertStringContainsString( "/page/3?{$query_string}\"", $links, 'The query string should appear in the links.' );
472+
$this->assertStringNotContainsString( "/page/3?{$unexpected}\"", $links, 'The query string should not be modified.' );
473+
}
474+
475+
/**
476+
* Data provider for
477+
* - test_permalinks_without_trailing_slash_do_not_modify_query_strings
478+
* - test_permalinks_with_trailing_slash_do_not_modify_query_strings
479+
*
480+
* @return array[] Data provider.
481+
*/
482+
public function data_query_strings() {
483+
return array(
484+
array( 'foo=bar', 'foo=bar/' ),
485+
array( 'foo=bar', 'foo=bar%2F' ),
486+
array( 'foo=bar%2F', 'foo=bar' ),
487+
488+
array( 's=post', 's=post/' ),
489+
array( 's=post', 's=post%2F' ),
490+
);
491+
}
365492
}

0 commit comments

Comments
 (0)