From 4cf86b9707be56f73e3e50c0ef427007edaa3d37 Mon Sep 17 00:00:00 2001 From: Michael Etokakpan Date: Sun, 21 Jun 2026 00:03:12 +0100 Subject: [PATCH] Posts, Post Types: Show modified date for pending/draft posts in the list table Date column. The Posts list table Date column labeled non-published posts as "Last Modified" but displayed the post_date instead of the modified date. For a pending or draft post with a future publication date, this resulted in a future date being shown under a "Last Modified" label, which is misleading. This displays the modified date and time (via get_the_modified_time() and get_post_timestamp( $post, 'modified' )) for statuses other than publish and future, so the date shown matches the "Last Modified" label. Published and scheduled posts continue to show the publication date. Adds unit tests covering pending+scheduled, published, and scheduled posts. Fixes #40860. --- .../includes/class-wp-posts-list-table.php | 21 +++- .../phpunit/tests/admin/wpPostsListTable.php | 107 ++++++++++++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/src/wp-admin/includes/class-wp-posts-list-table.php b/src/wp-admin/includes/class-wp-posts-list-table.php index 18c76169eb81c..afb1d6a788a36 100644 --- a/src/wp-admin/includes/class-wp-posts-list-table.php +++ b/src/wp-admin/includes/class-wp-posts-list-table.php @@ -1193,7 +1193,8 @@ public function column_date( $post ) { if ( '0000-00-00 00:00:00' === $post->post_date ) { $t_time = __( 'Unpublished' ); $time_diff = 0; - } else { + } elseif ( 'publish' === $post->post_status || 'future' === $post->post_status ) { + // For published and scheduled posts, show the publication date and time. $t_time = sprintf( /* translators: 1: Post date, 2: Post time. */ __( '%1$s at %2$s' ), @@ -1205,6 +1206,24 @@ public function column_date( $post ) { $time = get_post_timestamp( $post ); $time_diff = time() - $time; + } else { + /* + * For all other statuses (draft, pending, etc.), the "Last Modified" + * label is shown below, so display the modified date and time to match. + * This avoids showing a future scheduled date labeled as "Last Modified", + * for example when a pending post has a future publication date. + */ + $t_time = sprintf( + /* translators: 1: Post modified date, 2: Post modified time. */ + __( '%1$s at %2$s' ), + /* translators: Post modified date format. See https://www.php.net/manual/datetime.format.php */ + get_the_modified_time( __( 'Y/m/d' ), $post ), + /* translators: Post modified time format. See https://www.php.net/manual/datetime.format.php */ + get_the_modified_time( __( 'g:i a' ), $post ) + ); + + $time = get_post_timestamp( $post, 'modified' ); + $time_diff = time() - $time; } if ( 'publish' === $post->post_status ) { diff --git a/tests/phpunit/tests/admin/wpPostsListTable.php b/tests/phpunit/tests/admin/wpPostsListTable.php index 9d2482a034af7..146a546cfea4c 100644 --- a/tests/phpunit/tests/admin/wpPostsListTable.php +++ b/tests/phpunit/tests/admin/wpPostsListTable.php @@ -330,4 +330,111 @@ public function test_get_views_should_return_views_by_default() { $this->assertSame( $expected, $actual ); } + + /** + * Ensures the Date column shows the modified date (not the future + * publication date) for a pending post scheduled in the future. + * + * @ticket 40860 + * + * @covers WP_Posts_List_Table::column_date + */ + public function test_column_date_shows_modified_date_for_pending_scheduled_post() { + global $mode; + + $mode = 'list'; + $table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => 'edit-post' ) ); + + $future_gmt = gmdate( 'Y-m-d H:i:s', time() + WEEK_IN_SECONDS ); + $now = current_time( 'mysql' ); + $now_gmt = current_time( 'mysql', true ); + + $post_id = self::factory()->post->create( + array( + 'post_status' => 'pending', + 'post_date' => get_date_from_gmt( $future_gmt ), + 'post_date_gmt' => $future_gmt, + ) + ); + + // Force a modified date in the past (now), distinct from the future post_date. + global $wpdb; + $wpdb->update( + $wpdb->posts, + array( + 'post_modified' => $now, + 'post_modified_gmt' => $now_gmt, + ), + array( 'ID' => $post_id ) + ); + clean_post_cache( $post_id ); + + $post = get_post( $post_id ); + + ob_start(); + $table->column_date( $post ); + $output = ob_get_clean(); + + $modified_date = get_the_modified_time( __( 'Y/m/d' ), $post ); + $future_date = get_the_time( __( 'Y/m/d' ), $post ); + + $this->assertStringContainsString( 'Last Modified', $output, 'A pending post should display the "Last Modified" status.' ); + $this->assertStringContainsString( $modified_date, $output, 'The Date column should display the post modified date.' ); + $this->assertStringNotContainsString( $future_date, $output, 'The Date column should not display the future publication date for a pending post.' ); + } + + /** + * Ensures the Date column still shows the publication date for + * published and scheduled posts. + * + * @ticket 40860 + * + * @covers WP_Posts_List_Table::column_date + * + * @dataProvider data_column_date_uses_publication_date_for_published_and_scheduled + * + * @param string $post_status The post status to test. + * @param string $expected_text The status label expected in the output. + */ + public function test_column_date_uses_publication_date_for_published_and_scheduled( $post_status, $expected_text ) { + global $mode; + + $mode = 'list'; + $table = _get_list_table( 'WP_Posts_List_Table', array( 'screen' => 'edit-post' ) ); + + if ( 'future' === $post_status ) { + $date_gmt = gmdate( 'Y-m-d H:i:s', time() + DAY_IN_SECONDS ); + } else { + $date_gmt = gmdate( 'Y-m-d H:i:s', time() - DAY_IN_SECONDS ); + } + + $post_id = self::factory()->post->create( + array( + 'post_status' => $post_status, + 'post_date' => get_date_from_gmt( $date_gmt ), + 'post_date_gmt' => $date_gmt, + ) + ); + + $post = get_post( $post_id ); + + ob_start(); + $table->column_date( $post ); + $output = ob_get_clean(); + + $this->assertStringContainsString( $expected_text, $output, 'The Date column should display the expected status label.' ); + $this->assertStringContainsString( get_the_time( __( 'Y/m/d' ), $post ), $output, 'The Date column should display the publication date.' ); + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_column_date_uses_publication_date_for_published_and_scheduled() { + return array( + 'published post' => array( 'publish', 'Published' ), + 'scheduled post' => array( 'future', 'Scheduled' ), + ); + } }