From 83d27d86a8df2ea47375e14790ca17ae11804617 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Tue, 25 Nov 2025 19:30:50 +0100 Subject: [PATCH 01/13] Get archives: add filter to customize query LIMIT clause This new filter will allow site admins to customize the LIMIT clause for all wp_get_archives requests on their site. Trac ticket: https://core.trac.wordpress.org/ticket/64304 --- src/wp-includes/general-template.php | 10 +++- .../phpunit/tests/functions/wpGetArchives.php | 49 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 640bc54c8e754..1dfdbc72958a9 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -2070,7 +2070,15 @@ function wp_get_archives( $args = '' ) { $last_changed = wp_cache_get_last_changed( 'posts' ); - $limit = $parsed_args['limit']; + /** + * Filters the SQL LIMIT clause for retrieving archives. + * + * @since 7.0.0 + * + * @param string $limit The limit of the query for the `wp_get_archives` function. + * @param array $parsed_args An array of default arguments. + */ + $limit = apply_filters( 'getarchives_limit', $parsed_args['limit'], $parsed_args ); if ( 'monthly' === $parsed_args['type'] ) { $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit"; diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index b12fe262e83a1..8f4e781bc913d 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -204,4 +204,53 @@ public function test_wp_get_archives_post_type() { ); $this->assertSame( $expected, trim( $archives ) ); } + + /** + * @ticket 7.0.0 + */ + public function test_wp_get_archives_limit_filter() { + $ids = array_slice( array_reverse( self::$post_ids ), 0, 3 ); + + $title1 = get_post( $ids[0] )->post_title; + $title2 = get_post( $ids[1] )->post_title; + $title3 = get_post( $ids[2] )->post_title; + + // Test without filter - should return all 3 posts when limit is 3. + $archives_without_filter = wp_get_archives( + array( + 'echo' => false, + 'type' => 'postbypost', + 'limit' => 3, + ) + ); + $this->assertStringContainsString( $title1, $archives_without_filter ); + $this->assertStringContainsString( $title2, $archives_without_filter ); + $this->assertStringContainsString( $title3, $archives_without_filter ); + + // Add filter to modify limit to 2. + add_filter( + 'getarchives_limit', + function( $limit, $parsed_args ) { + // Modify limit from 3 to 2. + return ' LIMIT 2'; + }, + 10, + 2 + ); + + // Test with filter - should return only 2 posts. + $archives_with_filter = wp_get_archives( + array( + 'echo' => false, + 'type' => 'postbypost', + 'limit' => 3, + ) + ); + $this->assertStringContainsString( $title1, $archives_with_filter ); + $this->assertStringContainsString( $title2, $archives_with_filter ); + $this->assertStringNotContainsString( $title3, $archives_with_filter ); + + // Remove filter. + remove_all_filters( 'getarchives_limit' ); + } } From 0259158a9c9fee1d519e0e83eaf84b578bba09ea Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Tue, 25 Nov 2025 19:38:05 +0100 Subject: [PATCH 02/13] Update ticket number --- tests/phpunit/tests/functions/wpGetArchives.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index 8f4e781bc913d..de5a83c52f80c 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -206,7 +206,7 @@ public function test_wp_get_archives_post_type() { } /** - * @ticket 7.0.0 + * @ticket 64304 */ public function test_wp_get_archives_limit_filter() { $ids = array_slice( array_reverse( self::$post_ids ), 0, 3 ); From 4cac4dc3608ee773e778fc461fa319c675743604 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Tue, 25 Nov 2025 19:39:15 +0100 Subject: [PATCH 03/13] Add missing space --- tests/phpunit/tests/functions/wpGetArchives.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index de5a83c52f80c..908e12ec2d67e 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -230,7 +230,7 @@ public function test_wp_get_archives_limit_filter() { // Add filter to modify limit to 2. add_filter( 'getarchives_limit', - function( $limit, $parsed_args ) { + function ( $limit, $parsed_args ) { // Modify limit from 3 to 2. return ' LIMIT 2'; }, From aad4330ceb1e250207a6dcc969c018093e87add2 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Wed, 26 Nov 2025 12:19:00 +0100 Subject: [PATCH 04/13] Better alignment Co-authored-by: Weston Ruter --- src/wp-includes/general-template.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 1dfdbc72958a9..dd2469e2b7746 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -2075,7 +2075,7 @@ function wp_get_archives( $args = '' ) { * * @since 7.0.0 * - * @param string $limit The limit of the query for the `wp_get_archives` function. + * @param string $limit The limit of the query for the `wp_get_archives` function. * @param array $parsed_args An array of default arguments. */ $limit = apply_filters( 'getarchives_limit', $parsed_args['limit'], $parsed_args ); From b4c617d3e68a60be6fa2c90a649f317080db7468 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Wed, 26 Nov 2025 12:22:44 +0100 Subject: [PATCH 05/13] Switch to filtering the limit earlier See https://github.com/WordPress/wordpress-develop/pull/10552#discussion_r2561111059 --- src/wp-includes/general-template.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index dd2469e2b7746..3c472d4858995 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -2031,9 +2031,19 @@ function wp_get_archives( $args = '' ) { $parsed_args['type'] = 'monthly'; } - if ( ! empty( $parsed_args['limit'] ) ) { - $parsed_args['limit'] = absint( $parsed_args['limit'] ); - $parsed_args['limit'] = ' LIMIT ' . $parsed_args['limit']; + /** + * Filters the limit for the number of posts to include in the archive. + * + * @since 7.0.0 + * + * @param int $limit The limit for the number of posts to include in the archive. Default 0. + * @param array $parsed_args An array of default arguments. + */ + $limit_number = (int) apply_filters( 'getarchives_limit', absint( $parsed_args['limit'] ), $parsed_args ); + if ( $limit_number > 0 ) { + $limit = " LIMIT $limit_number"; + } else { + $limit = ''; } $order = strtoupper( $parsed_args['order'] ); @@ -2070,16 +2080,6 @@ function wp_get_archives( $args = '' ) { $last_changed = wp_cache_get_last_changed( 'posts' ); - /** - * Filters the SQL LIMIT clause for retrieving archives. - * - * @since 7.0.0 - * - * @param string $limit The limit of the query for the `wp_get_archives` function. - * @param array $parsed_args An array of default arguments. - */ - $limit = apply_filters( 'getarchives_limit', $parsed_args['limit'], $parsed_args ); - if ( 'monthly' === $parsed_args['type'] ) { $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit"; $key = md5( $query ); From 1ac21ca6df017c540d9c36662b48f68d610024ce Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Wed, 26 Nov 2025 19:53:05 +0100 Subject: [PATCH 06/13] Update test to match updated filter Co-authored-by: Weston Ruter --- tests/phpunit/tests/functions/wpGetArchives.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index 908e12ec2d67e..3cc171c131ae6 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -232,7 +232,7 @@ public function test_wp_get_archives_limit_filter() { 'getarchives_limit', function ( $limit, $parsed_args ) { // Modify limit from 3 to 2. - return ' LIMIT 2'; + return 2; }, 10, 2 From 7ce9d9fc678cd3ca42084f0f34802fb821a0c93c Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Wed, 26 Nov 2025 19:53:20 +0100 Subject: [PATCH 07/13] Remove unnecessary removal Co-authored-by: Weston Ruter --- tests/phpunit/tests/functions/wpGetArchives.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index 3cc171c131ae6..b93c904a262c7 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -249,8 +249,5 @@ function ( $limit, $parsed_args ) { $this->assertStringContainsString( $title1, $archives_with_filter ); $this->assertStringContainsString( $title2, $archives_with_filter ); $this->assertStringNotContainsString( $title3, $archives_with_filter ); - - // Remove filter. - remove_all_filters( 'getarchives_limit' ); } } From 750ca847db6da988b11611277e9713b692cf2c25 Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Wed, 26 Nov 2025 20:16:39 +0100 Subject: [PATCH 08/13] Switch to a different filter name and implementation see discussion in https://github.com/WordPress/wordpress-develop/pull/10552#issuecomment-3582546446 --- src/wp-includes/general-template.php | 29 ++++++----- .../phpunit/tests/functions/wpGetArchives.php | 49 ++++++++----------- 2 files changed, 36 insertions(+), 42 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 3c472d4858995..289d54860f83b 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -2018,6 +2018,17 @@ function wp_get_archives( $args = '' ) { 'w' => get_query_var( 'w' ), ); + /** + * Filters the archive links list arguments. + * + * @since 7.0.0 + * + * @see wp_get_archives() + * + * @param array $args An array of arguments. + */ + $args = apply_filters( 'wp_get_archives_args', $args ); + $parsed_args = wp_parse_args( $args, $defaults ); $post_type_object = get_post_type_object( $parsed_args['post_type'] ); @@ -2031,19 +2042,9 @@ function wp_get_archives( $args = '' ) { $parsed_args['type'] = 'monthly'; } - /** - * Filters the limit for the number of posts to include in the archive. - * - * @since 7.0.0 - * - * @param int $limit The limit for the number of posts to include in the archive. Default 0. - * @param array $parsed_args An array of default arguments. - */ - $limit_number = (int) apply_filters( 'getarchives_limit', absint( $parsed_args['limit'] ), $parsed_args ); - if ( $limit_number > 0 ) { - $limit = " LIMIT $limit_number"; - } else { - $limit = ''; + if ( ! empty( $parsed_args['limit'] ) ) { + $parsed_args['limit'] = absint( $parsed_args['limit'] ); + $parsed_args['limit'] = ' LIMIT ' . $parsed_args['limit']; } $order = strtoupper( $parsed_args['order'] ); @@ -2080,6 +2081,8 @@ function wp_get_archives( $args = '' ) { $last_changed = wp_cache_get_last_changed( 'posts' ); + $limit = $parsed_args['limit']; + if ( 'monthly' === $parsed_args['type'] ) { $query = "SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb->posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit"; $key = md5( $query ); diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index b93c904a262c7..1a774f66a2da1 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -208,46 +208,37 @@ public function test_wp_get_archives_post_type() { /** * @ticket 64304 */ - public function test_wp_get_archives_limit_filter() { + public function test_wp_get_archives_args_filter() { + // Test that the filter can modify the limit argument. + $filter_callback = function( $args ) { + $args['limit'] = 3; + return $args; + }; + add_filter( 'wp_get_archives_args', $filter_callback ); + $ids = array_slice( array_reverse( self::$post_ids ), 0, 3 ); + $link1 = get_permalink( $ids[0] ); + $link2 = get_permalink( $ids[1] ); + $link3 = get_permalink( $ids[2] ); + $title1 = get_post( $ids[0] )->post_title; $title2 = get_post( $ids[1] )->post_title; $title3 = get_post( $ids[2] )->post_title; - // Test without filter - should return all 3 posts when limit is 3. - $archives_without_filter = wp_get_archives( + $expected = <<$title1 +
  • $title2
  • +
  • $title3
  • +EOF; + $archives = wp_get_archives( array( 'echo' => false, 'type' => 'postbypost', - 'limit' => 3, + 'limit' => 5, // This should be overridden by the filter to 3. ) ); - $this->assertStringContainsString( $title1, $archives_without_filter ); - $this->assertStringContainsString( $title2, $archives_without_filter ); - $this->assertStringContainsString( $title3, $archives_without_filter ); - - // Add filter to modify limit to 2. - add_filter( - 'getarchives_limit', - function ( $limit, $parsed_args ) { - // Modify limit from 3 to 2. - return 2; - }, - 10, - 2 - ); - // Test with filter - should return only 2 posts. - $archives_with_filter = wp_get_archives( - array( - 'echo' => false, - 'type' => 'postbypost', - 'limit' => 3, - ) - ); - $this->assertStringContainsString( $title1, $archives_with_filter ); - $this->assertStringContainsString( $title2, $archives_with_filter ); - $this->assertStringNotContainsString( $title3, $archives_with_filter ); + $this->assertSameIgnoreEOL( $expected, trim( $archives ) ); } } From f4ec0f710fba920f239bcf6cb54a3c02e768fd5f Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Wed, 26 Nov 2025 20:18:29 +0100 Subject: [PATCH 09/13] Fix phpcs linting error --- tests/phpunit/tests/functions/wpGetArchives.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index 1a774f66a2da1..cd6946b3c2052 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -210,7 +210,7 @@ public function test_wp_get_archives_post_type() { */ public function test_wp_get_archives_args_filter() { // Test that the filter can modify the limit argument. - $filter_callback = function( $args ) { + $filter_callback = function ( $args ) { $args['limit'] = 3; return $args; }; From 2160d0cd3aa6b09021715e676ad19da90c0fc25f Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Thu, 27 Nov 2025 09:09:38 +0100 Subject: [PATCH 10/13] Better alignment Co-authored-by: Weston Ruter --- src/wp-includes/general-template.php | 4 ++-- tests/phpunit/tests/functions/wpGetArchives.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wp-includes/general-template.php b/src/wp-includes/general-template.php index 289d54860f83b..68baee9d31373 100644 --- a/src/wp-includes/general-template.php +++ b/src/wp-includes/general-template.php @@ -2019,13 +2019,13 @@ function wp_get_archives( $args = '' ) { ); /** - * Filters the archive links list arguments. + * Filters the arguments for displaying archive links. * * @since 7.0.0 * * @see wp_get_archives() * - * @param array $args An array of arguments. + * @param array $args Arguments. */ $args = apply_filters( 'wp_get_archives_args', $args ); diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index cd6946b3c2052..a7de966cf6785 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -227,9 +227,9 @@ public function test_wp_get_archives_args_filter() { $title3 = get_post( $ids[2] )->post_title; $expected = <<$title1 -
  • $title2
  • -
  • $title3
  • +
  • $title1
  • +
  • $title2
  • +
  • $title3
  • EOF; $archives = wp_get_archives( array( From 6cfa1b9cff9b6222424bebf1ba044dcf0f650e9b Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Thu, 27 Nov 2025 09:10:50 +0100 Subject: [PATCH 11/13] More concise expected string building Co-authored-by: Weston Ruter --- .../phpunit/tests/functions/wpGetArchives.php | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index a7de966cf6785..722a13a3979cd 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -218,19 +218,15 @@ public function test_wp_get_archives_args_filter() { $ids = array_slice( array_reverse( self::$post_ids ), 0, 3 ); - $link1 = get_permalink( $ids[0] ); - $link2 = get_permalink( $ids[1] ); - $link3 = get_permalink( $ids[2] ); - - $title1 = get_post( $ids[0] )->post_title; - $title2 = get_post( $ids[1] )->post_title; - $title3 = get_post( $ids[2] )->post_title; - - $expected = <<$title1 -
  • $title2
  • -
  • $title3
  • -EOF; + $expected = join( + "\n", + array_map( + static function ( $id ) { + return sprintf( '
  • %s
  • ', get_permalink( $id ), get_the_title( $id ) ); + }, + $ids + ) + ); $archives = wp_get_archives( array( 'echo' => false, From 9ee87b60b80f00235d2f7583cfc9644b0fba9dda Mon Sep 17 00:00:00 2001 From: Jeremy Herve Date: Thu, 27 Nov 2025 09:11:16 +0100 Subject: [PATCH 12/13] Use assertEqualHTML Co-authored-by: Weston Ruter --- tests/phpunit/tests/functions/wpGetArchives.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index 722a13a3979cd..615beb49fdba1 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -235,6 +235,6 @@ static function ( $id ) { ) ); - $this->assertSameIgnoreEOL( $expected, trim( $archives ) ); + $this->assertEqualHTML( $expected, $archives ); } } From ecdeb3d5b37d81412faa53bd06cd332d375193b6 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Fri, 28 Nov 2025 22:07:31 -0800 Subject: [PATCH 13/13] Use static closure and remove unnecessary variable --- tests/phpunit/tests/functions/wpGetArchives.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/phpunit/tests/functions/wpGetArchives.php b/tests/phpunit/tests/functions/wpGetArchives.php index 615beb49fdba1..3f98d5c5644f6 100644 --- a/tests/phpunit/tests/functions/wpGetArchives.php +++ b/tests/phpunit/tests/functions/wpGetArchives.php @@ -210,11 +210,13 @@ public function test_wp_get_archives_post_type() { */ public function test_wp_get_archives_args_filter() { // Test that the filter can modify the limit argument. - $filter_callback = function ( $args ) { - $args['limit'] = 3; - return $args; - }; - add_filter( 'wp_get_archives_args', $filter_callback ); + add_filter( + 'wp_get_archives_args', + static function ( $args ) { + $args['limit'] = 3; + return $args; + } + ); $ids = array_slice( array_reverse( self::$post_ids ), 0, 3 );