Opened 12 months ago
Last modified 13 days ago
#62468 new defect (bug)
wp_update_post overwrites post_date when updating post_status
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Future Release | Priority: | normal |
| Severity: | normal | Version: | |
| Component: | Posts, Post Types | Keywords: | has-patch has-unit-tests changes-requested |
| Focuses: | Cc: |
Description
Steps to reproduce the bug:
- Create a post with the status
pending. - Use
wp_update_postto update the post status tofutureand setpost_dateto a specific future date. - Observe that the
post_datevalue is reset, and the post is immediately published.
Expected behavior:
When updating the post status to future and setting a future post_date, the post should be scheduled for publication at the specified date and not published immediately.
Actual behavior:
The post_date is recalculated based on the current date and time due to the existing post status, causing the post to be published immediately.
Cause:
The wp_update_post function uses the current post status to determine whether the post_date should be modified. This logic does not account for updates to the post status in the same operation.
Suggested fix:
Adjust the logic in wp_update_post to prioritize updates to the post status before checking conditions that modify the post_date. Adding the edit_date flag to enforce the use of the provided post_date is a temporary workaround, but a deeper fix is needed to handle this logic cleanly.
Patch:
A proposed patch file is attached, which modifies the wp_update_post function to handle this scenario correctly.
Attachments (5)
Change History (38)
#1
@
12 months ago
Hi @aguerra07,
Thank you for bringing this up. I attempted to reproduce the issue, but I was unable to replicate it. Below are the details of my implementation:
My create_pending_post() Function:
function create_pending_post() {
$post_data = array(
'post_title' => 'Your Post Title',
'post_content' => 'Your post content goes here.',
'post_status' => 'pending',
'post_author' => 1,
'post_type' => 'post',
);
$post_id = wp_insert_post( $post_data );
if ( ! is_wp_error( $post_id ) ) {
return 'Post created successfully with ID: ' . $post_id;
} else {
return 'Error creating post: ' . $post_id->get_error_message();
}
}
My schedule_post_for_future() Function
function schedule_post_for_future( $post_id ) {
$post_id = 62;
$future_date = '2024-12-25 14:30:00';
if ( ! strtotime( $future_date ) ) {
return 'Invalid date format';
}
$post_data = array(
'ID' => $post_id,
'post_status' => 'future',
'post_date' => $future_date,
'post_date_gmt' => get_gmt_from_date( $future_date ),
);
$updated_post = wp_update_post( $post_data, true );
if ( is_wp_error( $updated_post ) ) {
return 'Error updating post: ' . $updated_post->get_error_message();
}
return 'Post successfully scheduled for: ' . $future_date;
}
My Post Dashboard:
Database Info:
Could you please let me know if there’s something I might have overlooked or if there are additional steps I should try to reproduce the issue?
WordPress Version: 6.7
#2
@
12 months ago
Test Report
Description
This report validates whether the indicated patch works as expected.
Patch tested: https://core.trac.wordpress.org/attachment/ticket/62468/fix-wp-update-post.patch
Environment
- WordPress: 6.8-alpha-59274-src
- PHP: 8.2.22
- Server: nginx/1.27.0
- Database: mysqli (Server: 8.0.39 / Client: mysqlnd 8.2.22)
- Browser: Chrome 129.0.0.0
- OS: Linux
- Theme: Twenty Twenty-Five 1.0
- MU Plugins: None activated
- Plugins:
- Test Reports 1.2.0
Actual Results
- ✅ Issue resolved with patch.
This ticket was mentioned in Slack in #core-performance by mukeshpanchal27. View the logs.
12 months ago
#4
@
12 months ago
- Focuses performance coding-standards php-compatibility removed
- Keywords needs-unit-tests reporter-feedback added
Hi @aguerra07,
Welcome to Trac!
This one will definitely require unit tests that first demonstrate the initial problem, and then demonstrate the changes work as expected with out side effects.
Creating a pull request on GitHub will run the entire test suite against your suggested code changes to confirm there are no unexpected consequences.
Also, can you proved more context to the problem? Did this just start happening after updating to 6.7? Or was has this always been the behavior?
This ticket was mentioned in PR #8118 on WordPress/wordpress-develop by @sukhendu2002.
10 months ago
#6
- Keywords has-unit-tests added; needs-unit-tests removed
Trac ticket: https://core.trac.wordpress.org/ticket/62468
#8
@
3 months ago
I verified that the added tests in the PR fail without the patch and pass with the rest of the patch applied.
This ticket was mentioned in Slack in #core-test by sirlouen. View the logs.
3 months ago
#10
@
3 months ago
- Milestone changed from Awaiting Review to Future Release
Combined Reproduction & Test Report
Description
This report validates whether the indicated patch works as expected.
Patch tested:
Fix: https://core.trac.wordpress.org/attachment/ticket/62468/fix-wp-update-post.patch
Tests: https://github.com/WordPress/wordpress-develop/pull/8118.diff
Environment
- WordPress: 6.9-alpha-60093-src
- PHP: 8.2.29
- Server: nginx/1.29.1
- Database: mysqli (Server: 8.4.6 / Client: mysqlnd 8.2.29)
- Browser: Chrome 140.0.0.0
- OS: Windows 10/11
- Theme: Twenty Twenty-Five 1.3
- MU Plugins: None activated
- Plugins:
- Testing Dolly 1.0.0
- Test Reports 1.2.0
Testing Instructions
- The ones provided in the OP
- Create a new post with Draft Status (or Pending Review)
- Add some code to a plugin to execute
wp_update_postfunction withpost_statustoFuture, andpost_datesomewhere in the future (Example:gmdate( 'Y-m-d H:i:s', strtotime( '+1 day' ) - Check if the post is scheduled for the date in the future, or if its Published.
Actual Results
- ✅ Issue resolved with patch.
Additional Notes
- @aguerra07 why would we be interested on preserving the date on
publishorprivate?
- I'm going to do a little revamp on the test and take the advantage that its another
wp_update_posttest coverage, to merge all into a new file made for this. I believe that this function is relevant enough to have its own testing file.
This ticket was mentioned in PR #9699 on WordPress/wordpress-develop by @SirLouen.
3 months ago
#11
For this reviewed patch I've considered these elements:
- I've taken as the fix: https://core.trac.wordpress.org/attachment/ticket/62468/fix-wp-update-post.patch
It was unnecesary to preserving date of publish and private on draft/pending posts. Only future is relevant in this scenario
- For the unit tests I've taken this one by @sukhendu2002, removing all the extra AI fluff. The data provider feels a bit overkill but I think it will don't do any harm.
- Finally, given that here is a good opportunity to open a specific file to cover
wp_update_postsI've brought all the tests covering this function and merged them all into this file for Unit Tests organizational purposes.
Trac ticket: https://core.trac.wordpress.org/ticket/62468
@SirLouen commented on PR #9699:
3 months ago
#12
@peterwilsoncc as a rule of thumb, I don't like to add tests that cannot be proven with and without the patch. But I've taken advantage of the dataProvider to add a number of cases, including those you mentioned (some are implicit, for example, a publish to future in the past, ending in publish as expected).
This ticket was mentioned in Slack in #core-test by sirlouen. View the logs.
3 months ago
This ticket was mentioned in Slack in #core-test by nikunj8866. View the logs.
3 months ago
This ticket was mentioned in Slack in #core-test by sirlouen. View the logs.
2 months ago
This ticket was mentioned in Slack in #core-test by sirlouen. View the logs.
2 months ago
#17
@
2 months ago
Test Report
Description
This report validates whether the indicated patch works as expected.
Patch tested: https://github.com/WordPress/wordpress-develop/pull/9699
Environment
- WordPress: 6.9-alpha-60093-src
- PHP: 8.2.29
- Server: nginx/1.29.1
- Database: mysqli (Server: 8.4.6 / Client: mysqlnd 8.2.29)
- Browser: Chrome 140.0.0.0
- OS: Windows 10/11
- Theme: Twenty Twenty-Five 1.3
- MU Plugins: None activated
- Plugins:
- Test Reports 1.2.0
Testing Instructions
- Use this code to create a new post with Pending Review Status or use UI:
function create_pending_post() { $post_data = array( 'post_title' => 'Pending Status Post', 'post_content' => '', 'post_status' => 'pending', 'post_author' => 1, 'post_type' => 'post', ); $post_id = wp_insert_post( $post_data ); if ( ! is_wp_error( $post_id ) ) { die( 'Post created successfully with ID: ' . esc_html( $post_id ) ); } else { die( 'Error creating post: ' . esc_html( $post_id->get_error_message() ) ); } } add_action( 'wp_ajax_create_pending_post', 'create_pending_post' );
- Update the post status and post date:
function schedule_post_for_future() { $post_id = 12; $future_date = '2025-09-30 22:00:00'; if ( ! strtotime( $future_date ) ) { return 'Invalid date format'; } $post_data = array( 'ID' => $post_id, 'post_title' => 'Future Status Post', 'post_status' => 'future', 'post_date' => $future_date, 'post_date_gmt' => get_gmt_from_date( $future_date ), ); $updated_post = wp_update_post( $post_data, true ); if ( is_wp_error( $updated_post ) ) { die( 'Error updating post: ' . esc_html( $updated_post->get_error_message() ) ); } die( 'Post successfully scheduled for: ' . esc_html( $future_date ) ); } add_action( 'wp_ajax_schedule_post_for_future', 'schedule_post_for_future' );
- Check if the post is scheduled for the date in the future, or if its Published.
Actual Results
- ✅ Issue resolved with patch.
#18
@
2 months ago
- Keywords commit added; needs-testing removed
- Milestone changed from Future Release to 6.9
So now all testing is done, everything review and pretty much now it's ready to be shipped.
This ticket was mentioned in Slack in #core-test by sirlouen. View the logs.
2 months ago
#20
@
7 weeks ago
Test Report
Description
This report validates whether the indicated patch works as expected.
Patch tested: https://github.com/WordPress/wordpress-develop/pull/9699/
Environment
- WordPress: 6.8.3
- PHP: 8.2.27
- Server: nginx/1.26.1
- Database: mysqli (Server: 8.0.35 / Client: mysqlnd 8.2.27)
- Browser: Chrome 140.0.0.0
- OS: Linux
- Theme: Twenty Twenty-Five 1.3
- MU Plugins: None activated
- Plugins:
- Test Reports 1.2.0
Actual Results
- ✅ Issue resolved with patch.
Additional Notes
- Tested using Local WP since my Docker having an issue.
- Only test the code update from this line https://github.com/WordPress/wordpress-develop/pull/9699/files#diff-ef9c5475561d459917dac57d21e08a6dfeb36f8b1c44b978d3696aec8b97c405R5215
- Wasn't able to run the test unit due to Docker issue I have right now, so hopefully someone can give it a try on their end.
- Code used on Step 2 in the trac description:
// Trac #62468 Reproduction: wp_update_post overwrites post_date when updating post_status add_action( 'init', 'trac_62468_reproduction' ); function trac_62468_reproduction() { if ( ! current_user_can( 'manage_options' ) ) { return; } // Update the value here to match with your test post $post_id = 24; if ( is_wp_error( $post_id ) ) { error_log( 'Error creating post: ' . $post_id->get_error_message() ); return; } $future_date = date( 'Y-m-d H:i:s', strtotime( '+100 day' ) ); wp_update_post( array( 'ID' => $post_id, 'post_status' => 'future', 'post_date' => $future_date, ) ); }
Supplemental Artifacts
Before Patch:
- Edit post - https://i.imgur.com/IuxiFxz.png
- Post table - https://i.imgur.com/ydLq5Iu.png
- After modifying the status and future dates - https://i.imgur.com/bkOZ7Vt.png | https://i.imgur.com/COyoxjW.png
After Patch:
- Edit Post - https://i.imgur.com/Eq4XkfA.png
- Post table - https://i.imgur.com/XdzWjpy.png
This ticket was mentioned in Slack in #core by sirlouen. View the logs.
4 weeks ago
This ticket was mentioned in Slack in #core by sirlouen. View the logs.
3 weeks ago
3 weeks ago
#23
Finally, given that here is a good opportunity to open a specific file to cover wp_update_posts I've brought all the tests covering this function and merged them all into this file for Unit Tests organizational purposes.
This makes it harder to review this patch since it's not easy to see what the new tests are exactly. I think that should happen in a separate ticket.
@SirLouen commented on PR #9699:
3 weeks ago
#24
Finally, given that here is a good opportunity to open a specific file to cover wp_update_posts I've brought all the tests covering this function and merged them all into this file for Unit Tests organizational purposes.
This makes it harder to review this patch since it's not easy to see what the new tests are exactly. I think that should happen in a separate ticket.
@aaronjorbin there are only 3 functions merged.
test_update_invalid_post_id
test_update_post_should_only_modify_post_tags_if_different_tags_input_was_provided
and
test_wp_update_post_with_content_filtering
They are literally copy/paste, so nothing to review there. Just for reunification purposes and I don't want that they are forgot specially if there are any future plans to move to PHPUnit higher version.
There is only one function test_update_post_preserves_date_for_future_posts that targets this patch with a dataprovider. And its the last one.
By now I think it was finally reviewed by @peterwilsoncc
The fix was very straight forward, and some of the examples in the dataprovider were a good idea of Peter.
I think it's a straightforward merge at this point.
#25
@
2 weeks ago
- Keywords changes-requested added; commit removed
There is unresolved feedback remaining on PR 9699, so I have changed the status of this ticket.
This ticket was mentioned in Slack in #core by sirlouen. View the logs.
2 weeks ago
#27
@
13 days ago
- Keywords commit added; changes-requested removed
I thought that @peterwilsoncc was going to merge it yesterday.
I finished with the last review and this ready to go.
#28
follow-up:
↓ 29
@
13 days ago
- Milestone changed from 6.9 to 7.0
With open questions remaining and 6.9 RC1 releasing shortly, moving this to 7.0.
If any committer feels the remaining issues can be resolved in time for 6.9 RC1 and wish to assume ownership, feel free to update the milestone accordingly.
#29
in reply to:
↑ 28
@
13 days ago
Replying to davidbaumwald:
With open questions remaining and 6.9 RC1 releasing shortly, moving this to
7.0.
If any committer feels the remaining issues can be resolved in time for 6.9 RC1 and wish to assume ownership, feel free to update the milestone accordingly.
I stayed yesterday later at night to resolve the remaining issues for nothing. ☠️🪦
@peterwilsoncc commented on PR #9699:
13 days ago
#30
I'm unclear on the purpose of https://github.com/WordPress/wordpress-develop/pull/9699/commits/af483f2b158d206f28b7fb3c47bb6a033e761b66, when calling wp_update|insert_post() it's far more common to use the post_date argument rather than the post_date_gmt argument so it's of higher priority to test the former but both should probably be tested.
If the test is modified to compare ensure the timestamps for both date and date_gmt increases/decreases as appropriate, I'm seeing failures.
public function test_update_post_preserves_date_for_future_posts( $initial_status, $time_offset, $expected_status ) {
$post_id = self::factory()->post->create(
array(
'post_status' => $initial_status,
)
);
$initial_date_timestamp = strtotime( get_post( $post_id )->post_date );
$initial_date_gmt_timestamp = strtotime( get_post( $post_id )->post_date_gmt );
$future_date = gmdate( 'Y-m-d H:i:s', strtotime( $time_offset ) );
$update_data = array(
'ID' => $post_id,
'post_status' => 'future',
'post_date_gmt' => $future_date,
);
wp_update_post( $update_data );
$updated_post = get_post( $post_id );
$updated_date_timestamp = strtotime( get_post( $post_id )->post_date );
$updated_date_gmt_timestamp = strtotime( get_post( $post_id )->post_date_gmt );
if ( substr( $time_offset, 0, 1 ) === '+' ) {
$this->assertGreaterThan( $initial_date_timestamp, $updated_date_timestamp, 'Post date should be in the future compared to initial date.' );
$this->assertGreaterThan( $initial_date_gmt_timestamp, $updated_date_gmt_timestamp, 'Post date GMT should be in the future compared to initial date GMT.' );
} else {
$this->assertLessThan( $initial_date_timestamp, $updated_date_timestamp, 'Post date should be in the past compared to initial date.' );
$this->assertLessThan( $initial_date_gmt_timestamp, $updated_date_gmt_timestamp, 'Post date GMT should be in the past compared to initial date GMT.' );
}
$this->assertSame( $future_date, $updated_post->post_date_gmt, 'Post date should be updated accordingly.' );
$this->assertSame( $expected_status, $updated_post->post_status, "Post status should be '{$expected_status}' after update." );
}
Result
$ phpunit --filter test_update_post_preserves_date_for_future_posts
Installing...
Running as single site... To run multisite, use -c tests/phpunit/multisite.xml
Not running ajax tests. To execute these, use --group ajax.
Not running ms-files tests. To execute these, use --group ms-files.
Not running external-http tests. To execute these, use --group external-http.
PHPUnit 9.6.29 by Sebastian Bergmann and contributors.
Warning: Your XML configuration validates against a deprecated schema.
Suggestion: Migrate your XML configuration using "--migrate-configuration"!
FFFFFF 6 / 6 (100%)
Time: 00:00.835, Memory: 219.89 MB
There were 6 failures:
1) Tests_Post_WpUpdatePost::test_update_post_preserves_date_for_future_posts with data set "pending to future with 1 day more" ('pending', '+1 day', 'future')
Post date should be in the future compared to initial date.
Failed asserting that 1762897192 is greater than 1762897192.
/vagrant/wordpress-develop/tests/phpunit/tests/post/wpUpdatePost.php:224
2) Tests_Post_WpUpdatePost::test_update_post_preserves_date_for_future_posts with data set "draft to future with 1 day more" ('draft', '+1 day', 'future')
Post date should be in the future compared to initial date.
Failed asserting that 1762897192 is greater than 1762897192.
/vagrant/wordpress-develop/tests/phpunit/tests/post/wpUpdatePost.php:224
3) Tests_Post_WpUpdatePost::test_update_post_preserves_date_for_future_posts with data set "publish to future with 1 day more" ('publish', '+1 day', 'future')
Post date should be in the future compared to initial date.
Failed asserting that 1762897192 is greater than 1762897192.
/vagrant/wordpress-develop/tests/phpunit/tests/post/wpUpdatePost.php:224
4) Tests_Post_WpUpdatePost::test_update_post_preserves_date_for_future_posts with data set "draft to future with 1 day less" ('draft', '-1 day', 'publish')
Post date should be in the past compared to initial date.
Failed asserting that 1762897192 is less than 1762897192.
/vagrant/wordpress-develop/tests/phpunit/tests/post/wpUpdatePost.php:227
5) Tests_Post_WpUpdatePost::test_update_post_preserves_date_for_future_posts with data set "pending to future with 1 day less" ('pending', '-1 day', 'publish')
Post date should be in the past compared to initial date.
Failed asserting that 1762897192 is less than 1762897192.
/vagrant/wordpress-develop/tests/phpunit/tests/post/wpUpdatePost.php:227
6) Tests_Post_WpUpdatePost::test_update_post_preserves_date_for_future_posts with data set "publish to future with 1 day less" ('publish', '-1 day', 'publish')
Post date should be in the past compared to initial date.
Failed asserting that 1762897192 is less than 1762897192.
/vagrant/wordpress-develop/tests/phpunit/tests/post/wpUpdatePost.php:227
FAILURES!
Tests: 6, Assertions: 6, Failures: 6.
#31
@
13 days ago
@SirLouen The lead up to RC 1 is always a busy time and I didn't get a chance to review the changes.
Without an explanation on the commit Fix the tests, I prioritised other items that could be reviewed more quickly to allow me to test this this-morning.
I've posted on the pull request.
@SirLouen commented on PR #9699:
13 days ago
#32
Ok, I have updated with those tests. I will give it a second check to see what's going on now.



This patch fixes a bug in wp_update_post that could clear the post_date when updating the post status, ensuring it is preserved when explicitly set.