diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php
index f9a529f069..6ed5151a98 100644
--- a/src/wp-includes/general-template.php
+++ b/src/wp-includes/general-template.php
@@ -2659,12 +2659,21 @@ function paginate_links( $args = '' ) {
// Merge additional query vars found in the original URL into 'add_args' array.
if ( isset( $url_parts[1] ) ) {
// Find the format argument.
- $format_query = parse_url( str_replace( '%_%', $args['format'], $args['base'] ), PHP_URL_QUERY );
- wp_parse_str( $format_query, $format_arg );
+ $format = explode( '?', str_replace( '%_%', $args['format'], $args['base'] ) );
+ $format_query = isset( $format[1] ) ? $format[1] : '';
+ wp_parse_str( $format_query, $format_args );
+
+ // Find the query args of the requested URL.
+ wp_parse_str( $url_parts[1], $url_query_args );
// Remove the format argument from the array of query arguments, to avoid overwriting custom format.
- wp_parse_str( remove_query_arg( array_keys( $format_arg ), $url_parts[1] ), $query_args );
- $args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $query_args ) );
+ foreach ( $format_args as $format_arg => $format_arg_value ) {
+ if ( isset( $url_query_args[ $format_arg ] ) ) {
+ unset( $url_query_args[ $format_arg ] );
+ }
+ }
+
+ $args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $url_query_args ) );
}
// Who knows what else people pass in $args
diff --git a/tests/phpunit/tests/general/paginateLinks.php b/tests/phpunit/tests/general/paginateLinks.php
index b6c1a32879..ba0b77b87e 100644
--- a/tests/phpunit/tests/general/paginateLinks.php
+++ b/tests/phpunit/tests/general/paginateLinks.php
@@ -311,4 +311,24 @@ EXPECTED;
$this->assertContains( "3", $links );
}
+
+ /**
+ * @ticket 31939
+ */
+ public function test_custom_base_query_arg_should_be_stripped_from_current_url_before_generating_pag_links() {
+ // Fake the current URL: example.com?foo
+ $request_uri = $_SERVER['REQUEST_URI'];
+ $_SERVER['REQUEST_URI'] = add_query_arg( 'foo', '', $request_uri );
+
+ $links = paginate_links( array(
+ 'base' => add_query_arg( 'foo', '%_%', home_url() ),
+ 'format' => '%#%',
+ 'total' => 5,
+ 'current' => 1,
+ 'type' => 'array',
+ ) );
+
+ $page_2_url = home_url() . '?foo=2';
+ $this->assertContains( "2", $links );
+ }
}