Skip to content

Apply parameters that user create and post update silently discard - #637

Draft
swissspidy wants to merge 4 commits into
mainfrom
claude/wp-cli-issue-5286-n50evd-silent-noop
Draft

Apply parameters that user create and post update silently discard#637
swissspidy wants to merge 4 commits into
mainfrom
claude/wp-cli-issue-5286-n50evd-silent-noop

Conversation

@swissspidy

@swissspidy swissspidy commented Aug 16, 2026

Copy link
Copy Markdown
Member

Draft. These are the two pre-existing bugs noticed while auditing field lists for wp-cli/wp-cli#5286, now with tests. Independent of #636 and #6392 — branched off main and reviewable on its own.

Same failure as #5286 reached from the other side: there the parameter name is wrong and the value is dropped, here the name is right and the value is dropped anyway. Both report success.

What's broken

Command Parameter Behaviour
user create --user_nicename documented, accepted, ignored
user create --rich_editing documented, accepted, ignored
post create --post_modified, --post_modified_gmt documented, accepted, ignored
post update --post_modified, --post_modified_gmt documented, accepted, ignored

User_Command::create() builds an explicit stdClass for wp_insert_user() and never sets either property. wp_insert_post() derives post_modified/post_modified_gmt itself and never reads them from $postarr — on update they are unconditionally current_time( 'mysql' ).

Note user create has no catch-all, so it is already strictly validated. It accepts these two parameters because they are documented, and then drops them.

Commits are test-first

b4355e0 adds the scenarios and fails. aeaa92b makes them pass. Reviewable in that order, and verified in that order with Behat by checking src/ out at each commit:

src/ at b4355e0 (tests only)   5 scenarios (2 passed, 3 failed)
src/ at aeaa92b (fix)          5 scenarios (5 passed)

The two that pass in both states are deliberate controls — nicename falling back to the login, and post_modified defaulting to now when not asked for. Without them a red run would not distinguish a real bug from a broken harness.

Full suites

Run on both database backends; the results are identical.

Suite MySQL SQLite
post.feature 22 scenarios, 22 passed 22 scenarios, 22 passed
post-create-duplicate.feature 5 scenarios, 5 passed 5 scenarios, 5 passed
user.feature 26 scenarios, 25 passed, 1 failed 26 scenarios, 25 passed, 1 failed

The one user.feature failure is pre-existing and unrelated. It is the multisite duplicate-email scenario, which expects Sorry, that email address is already used! while current core trunk returns This email address is already registered. Log in with this address or choose another one. Confirmed by re-running that scenario with src/ checked out at origin/main, where it fails identically. My diff does not touch it.

Tested against WordPress trunk (7.2-alpha), which is what this environment could obtain — worth noting since that is also the source of the message change above.

One regression this surfaced

Making post_modified live exposed a latent bug in post create --from-post. It copies the source post's fields and unsets post_date, post_date_gmt, guid and ID — but not post_modified. Harmless while core ignored it; with this change the duplicate would inherit the original's modification date instead of the current time. Fixed by unsetting it alongside post_date, with a scenario in post-create-duplicate.feature.

The design question

For post_modified the alternative is to remove the parameters from the docblocks rather than make them work. Smaller change, but it drops functionality the documentation has been advertising since it was added, and "set the modification date" is a reasonable thing to want from an admin tool. I went with making them work; inverting it is a small diff if you'd rather.

There is no such question for user create — those two are unambiguous.

🤖 Generated with Claude Code

https://claude.ai/code/session_014SSZzqMJRDTiLiDxQEPYcL

claude added 2 commits August 16, 2026 11:36
Three documented parameters accept a value and drop it:

- `user create --user_nicename` and `--rich_editing`. User_Command::create()
  builds an explicit stdClass for wp_insert_user() and never sets either
  property, so both are read off $assoc_args nowhere.
- `post create` / `post update --post_modified` and `--post_modified_gmt`.
  wp_insert_post() computes both itself and never reads them from $postarr;
  on update they are unconditionally current_time( 'mysql' ).

All three report success. These are the same silent no-op as
wp-cli/wp-cli#5286, reached from the other side:
there the parameter name is wrong, here the name is right and the value is
discarded anyway.

These scenarios fail on main. The fix follows in the next commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SSZzqMJRDTiLiDxQEPYcL
Makes the tests from the previous commit pass.

user create: set user_nicename and rich_editing on the object handed to
wp_insert_user(). Both use the same `false` default as the neighbouring
properties, which core reads as "not supplied" - user_nicename then falls back
to the login and rich_editing to 'true'.

post create / post update: wp_insert_post() derives post_modified and
post_modified_gmt itself and never reads them back from $postarr, so apply the
requested value through the wp_insert_post_data filter, registered around the
insert and removed straight after. When only one of the pair is given the other
is derived from it, so the two never disagree.

That last change makes a previously harmless bug visible: `post create
--from-post` copies the source post's fields, and post_modified was not among
the ones it unset. Core ignored it before, so the duplicate got the current
time; now it would inherit the original's. Unset it alongside post_date, and
cover it with a scenario.

The alternative to all of this is to remove the parameters from the docblocks
instead. That is a smaller change but loses functionality the documentation has
been promising, so it seemed the wrong way round - happy to invert it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SSZzqMJRDTiLiDxQEPYcL
@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4894862d-aba2-44f2-9034-1f64b55a0b1b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the bug label Aug 16, 2026
@codecov

codecov Bot commented Aug 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 26 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/Post_Command.php 0.00% 24 Missing ⚠️
src/User_Command.php 0.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@swissspidy

Copy link
Copy Markdown
Member Author

For post_modified the alternative is to remove the parameters from the docblocks rather than make them work. Smaller change, but it drops functionality the documentation has been advertising since it was added, and "set the modification date" is a reasonable thing to want from an admin tool. I went with making them work; inverting it is a small diff if you'd rather.

@schlessera Any preference?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants