Skip to content

Commit 935acff

Browse files
committed
Optimize confirm_scheduled_posts query
1 parent 6f75301 commit 935acff

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

__tests__/unit-tests/test-internal-events.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,61 @@ function test_force_publish_missed_schedules() {
176176
$this->assertCount( 1, $future_posts_after, 'One post should still be scheduled.' );
177177
$this->assertCount( 1, $published_posts, 'One post should be published.' );
178178
}
179+
180+
public function test_confirm_scheduled_posts() {
181+
// Create posts with 'future' status.
182+
$future_posts = array(
183+
$this->factory()->post->create(
184+
array(
185+
'post_title' => '1 hour in the future',
186+
'post_status' => 'future',
187+
'post_type' => 'post',
188+
'post_date' => gmdate( 'Y-m-d H:i:s', strtotime( '+1 hour' ) ),
189+
)
190+
),
191+
$this->factory()->post->create(
192+
array(
193+
'post_title' => '2 hours in the future',
194+
'post_status' => 'future',
195+
'post_type' => 'post',
196+
'post_date' => gmdate( 'Y-m-d H:i:s', strtotime( '+2 hours' ) ),
197+
)
198+
),
199+
$this->factory()->post->create(
200+
array(
201+
'post_title' => '3 hours in the future',
202+
'post_status' => 'future',
203+
'post_type' => 'post',
204+
'post_date' => gmdate( 'Y-m-d H:i:s', strtotime( '+3 hours' ) ),
205+
)
206+
),
207+
);
208+
209+
// Clear existing cron events to isolate the test.
210+
Utils::clear_cron_table();
211+
212+
// Query all cron events to confirm none exist.
213+
$events = Cron_Control\Events::query();
214+
$this->assertEmpty( $events, 'No scheduled events should exist initially.' );
215+
216+
// Call the method to confirm scheduled posts.
217+
Cron_Control\Internal_Events::instance()->confirm_scheduled_posts();
218+
219+
// Verify that cron jobs are scheduled for each future post.
220+
foreach ( $future_posts as $future_post_id ) {
221+
$timestamp = wp_next_scheduled( 'publish_future_post', array( $future_post_id ) );
222+
$this->assertNotFalse( $timestamp, "Cron job should be scheduled for post ID: $future_post_id." );
223+
}
224+
225+
// Reschedule one post with a different timestamp and call the method again.
226+
$future_post_gmt_time = strtotime( get_gmt_from_date( get_post( $future_posts[0] )->post_date ) . ' GMT' );
227+
wp_clear_scheduled_hook( 'publish_future_post', array( $future_posts[0] ) );
228+
wp_schedule_single_event( $future_post_gmt_time - 3600, 'publish_future_post', array( $future_posts[0] ) ); // Schedule 1 hour earlier.
229+
230+
Cron_Control\Internal_Events::instance()->confirm_scheduled_posts();
231+
232+
// Verify the post's cron job has been rescheduled to the correct timestamp.
233+
$rescheduled_timestamp = wp_next_scheduled( 'publish_future_post', array( $future_posts[0] ) );
234+
$this->assertEquals( $future_post_gmt_time, $rescheduled_timestamp, 'Cron job for post 1 should be rescheduled to the correct timestamp.' );
235+
}
179236
}

includes/class-internal-events.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public function confirm_scheduled_posts() {
168168

169169
do {
170170
$offset = max( 0, $page - 1 ) * $quantity;
171-
$future_posts = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_date FROM {$wpdb->posts} WHERE post_status = 'future' AND post_date > %s LIMIT %d,%d", current_time( 'mysql', false ), $offset, $quantity ) );
171+
$future_posts = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_date FROM {$wpdb->posts} p JOIN (SELECT DISTINCT post_type FROM {$wpdb->posts}) AS t ON p.post_type = t.post_type WHERE post_status = 'future' AND post_date > %s LIMIT %d,%d", current_time( 'mysql', false ), $offset, $quantity ) );
172172

173173
if ( ! empty( $future_posts ) ) {
174174
foreach ( $future_posts as $future_post ) {

0 commit comments

Comments
 (0)