From beb50703339e54cdeae59ea81e4911ccda8f3d5e Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Sun, 29 Mar 2026 04:28:51 +0000 Subject: [PATCH 1/3] Feeds: Guard against empty array passed to max() in get_feed_build_date(). When `wp_list_pluck()` returns an empty array from posts that lack the `post_modified_gmt` property, `max()` throws a `ValueError` on PHP 8+. This adds an emptiness check before calling `max()`, allowing `$datetime` to remain `false` and fall through to the existing `get_lastpostmodified()` fallback. Includes a unit test that simulates the condition. Fixes #59956. --- src/wp-includes/feed.php | 4 +- tests/phpunit/tests/date/getFeedBuildDate.php | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/feed.php b/src/wp-includes/feed.php index 821a3eb9be804..7b6045ce9c2a9 100644 --- a/src/wp-includes/feed.php +++ b/src/wp-includes/feed.php @@ -733,7 +733,9 @@ function get_feed_build_date( $format ) { } // Determine the maximum modified time. - $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', max( $modified_times ), $utc ); + if ( ! empty( $modified_times ) ) { + $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', max( $modified_times ), $utc ); + } } if ( false === $datetime ) { diff --git a/tests/phpunit/tests/date/getFeedBuildDate.php b/tests/phpunit/tests/date/getFeedBuildDate.php index d884c0baef05c..54a4d0189c131 100644 --- a/tests/phpunit/tests/date/getFeedBuildDate.php +++ b/tests/phpunit/tests/date/getFeedBuildDate.php @@ -40,6 +40,45 @@ public function test_should_return_correct_feed_build_date() { $this->assertSame( '2018-07-23T03:13:23+00:00', get_feed_build_date( DATE_RFC3339 ) ); } + /** + * Test that get_feed_build_date() does not throw a ValueError + * when wp_list_pluck() returns an empty array from posts that + * lack the 'post_modified_gmt' property. + * + * @ticket 59956 + */ + public function test_should_not_error_when_modified_times_is_empty() { + global $wp_query; + + $datetime = new DateTimeImmutable( 'now', wp_timezone() ); + $datetime_utc = $datetime->setTimezone( new DateTimeZone( 'UTC' ) ); + + // Create a real post so the fallback has something to return. + self::factory()->post->create( + array( + 'post_date' => $datetime->format( 'Y-m-d H:i:s' ), + ) + ); + + // Simulate a query where have_posts() is true but posts lack 'post_modified_gmt'. + $wp_query = new WP_Query(); + $incomplete_post = new stdClass(); + $incomplete_post->ID = 1; + $incomplete_post->post_title = 'Test'; + + $wp_query->posts = array( $incomplete_post ); + $wp_query->post_count = 1; + + $result = get_feed_build_date( DATE_RFC3339 ); + + $this->assertEqualsWithDelta( + strtotime( $datetime_utc->format( DATE_RFC3339 ) ), + strtotime( $result ), + 2, + 'Should fall back to last post modified when modified_times is empty.' + ); + } + /** * Test that get_feed_build_date() works with invalid post dates. * From eeb7bd58f6495468fff135bdb14925a7e072e9f4 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Sun, 29 Mar 2026 04:35:36 +0000 Subject: [PATCH 2/3] Fix PHPCS: align equals signs in test assignments. Aligns variable assignments in the test to satisfy the Generic.Formatting.MultipleStatementAlignment sniff. --- tests/phpunit/tests/date/getFeedBuildDate.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/date/getFeedBuildDate.php b/tests/phpunit/tests/date/getFeedBuildDate.php index 54a4d0189c131..e42d1074b4fa6 100644 --- a/tests/phpunit/tests/date/getFeedBuildDate.php +++ b/tests/phpunit/tests/date/getFeedBuildDate.php @@ -61,8 +61,9 @@ public function test_should_not_error_when_modified_times_is_empty() { ); // Simulate a query where have_posts() is true but posts lack 'post_modified_gmt'. - $wp_query = new WP_Query(); - $incomplete_post = new stdClass(); + $wp_query = new WP_Query(); + + $incomplete_post = new stdClass(); $incomplete_post->ID = 1; $incomplete_post->post_title = 'Test'; From 5b79996a4b8ab3c180b33d2f305fb6544c5ca129 Mon Sep 17 00:00:00 2001 From: Chris Huber Date: Sun, 29 Mar 2026 04:48:22 +0000 Subject: [PATCH 3/3] Tests: Fix test to match actual production trigger for empty modified_times. The production failure occurs when the posts array contains scalar values (e.g. post IDs) rather than post objects. wp_list_pluck() emits a _doing_it_wrong notice and returns an empty array, which then triggers the max() ValueError. Update the test to use an integer in the posts array and call setExpectedIncorrectUsage() to properly handle the expected notice. See #59956. --- tests/phpunit/tests/date/getFeedBuildDate.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/phpunit/tests/date/getFeedBuildDate.php b/tests/phpunit/tests/date/getFeedBuildDate.php index e42d1074b4fa6..9889508dc91e6 100644 --- a/tests/phpunit/tests/date/getFeedBuildDate.php +++ b/tests/phpunit/tests/date/getFeedBuildDate.php @@ -42,8 +42,8 @@ public function test_should_return_correct_feed_build_date() { /** * Test that get_feed_build_date() does not throw a ValueError - * when wp_list_pluck() returns an empty array from posts that - * lack the 'post_modified_gmt' property. + * when wp_list_pluck() returns an empty array because the posts + * array contains non-object, non-array values. * * @ticket 59956 */ @@ -60,16 +60,17 @@ public function test_should_not_error_when_modified_times_is_empty() { ) ); - // Simulate a query where have_posts() is true but posts lack 'post_modified_gmt'. + // Simulate a query where have_posts() is true but wp_list_pluck() + // returns an empty array because the posts array contains scalar + // values (neither objects nor arrays). This triggers the _doing_it_wrong + // notice in WP_List_Util::pluck() and produces an empty result. $wp_query = new WP_Query(); - $incomplete_post = new stdClass(); - $incomplete_post->ID = 1; - $incomplete_post->post_title = 'Test'; - - $wp_query->posts = array( $incomplete_post ); + $wp_query->posts = array( 1 ); $wp_query->post_count = 1; + $this->setExpectedIncorrectUsage( 'WP_List_Util::pluck' ); + $result = get_feed_build_date( DATE_RFC3339 ); $this->assertEqualsWithDelta(