Skip to content

Commit 4ecdf88

Browse files
committed
Posts: Only infer the password visibility when the caller sent none.
The inference is meant to fill a gap, not to outrank the caller. Reading it after the caller's own value let the two contradict each other, with the inferred one applied last: - `visibility => 'public'` sent with a non-empty password kept the password, where trunk dropped it. - `visibility => 'private'` sent with a password left the post public and password protected instead of private. Quick Edit reaches this pair through `wp_ajax_inline_save()`, which sets `visibility` to `private` whenever "Private" is ticked. Guarding the inference with `! isset( $post_data['visibility'] )` confines the behaviour change to the reported case, a caller that sends no visibility at all. The `private` characterisation test now sends a password alongside, and the precedence test is inverted: an explicit visibility survives. See #64810.
1 parent 5540b57 commit 4ecdf88

2 files changed

Lines changed: 18 additions & 10 deletions

File tree

‎src/wp-admin/includes/post.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,8 @@ function edit_post( $post_data = null ) {
301301
}
302302
}
303303

304-
// Password visibility.
305-
if ( ! empty( $post_data['post_password'] ) ) {
304+
// Infer the password visibility when the caller did not send one of its own.
305+
if ( ! isset( $post_data['visibility'] ) && ! empty( $post_data['post_password'] ) ) {
306306
$post_data['visibility'] = 'password';
307307
}
308308

‎tests/phpunit/tests/admin/includesPost.php‎

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1492,6 +1492,11 @@ public function test_edit_post_unsticks_the_post_when_visibility_is_password() {
14921492
* Ensures that an explicit `private` visibility privatises the post, drops any
14931493
* password and unsticks it.
14941494
*
1495+
* The password is sent alongside on purpose. Quick Edit posts
1496+
* `visibility => 'private'` whenever "Private" is ticked, so this pair is
1497+
* reachable from the UI, and inferring `password` from the password instead
1498+
* would leave the post public with its password intact.
1499+
*
14951500
* @ticket 64810
14961501
*
14971502
* @covers ::edit_post
@@ -1513,7 +1518,7 @@ public function test_edit_post_privatises_and_unsticks_the_post_when_visibility_
15131518
'post_ID' => $post_id,
15141519
'post_title' => 'Private',
15151520
'post_status' => 'publish',
1516-
'post_password' => '',
1521+
'post_password' => 'secret',
15171522
'sticky' => 'sticky',
15181523
'visibility' => 'private',
15191524
)
@@ -1527,18 +1532,17 @@ public function test_edit_post_privatises_and_unsticks_the_post_when_visibility_
15271532
}
15281533

15291534
/**
1530-
* Documents that a non-empty password wins over a `public` visibility sent alongside it.
1535+
* Ensures that a visibility sent by the caller is never overridden by an inferred one.
15311536
*
1532-
* Inferring the visibility from the password means the two can now contradict each
1533-
* other, and the inferred value is applied last. The editors never send that
1534-
* combination, since selecting "Public" clears the password field, but `edit_post()`
1535-
* is reachable from bulk edit and Quick Edit too, so the precedence is worth pinning.
1537+
* The inference only fills a gap. A caller that sends `public` alongside a
1538+
* non-empty password still reaches `case 'public'` and still has the password
1539+
* dropped, exactly as before this change.
15361540
*
15371541
* @ticket 64810
15381542
*
15391543
* @covers ::edit_post
15401544
*/
1541-
public function test_edit_post_prefers_the_password_over_a_contradicting_public_visibility() {
1545+
public function test_edit_post_keeps_an_explicit_visibility_over_an_inferred_one() {
15421546
wp_set_current_user( self::$admin_id );
15431547

15441548
$post_id = self::factory()->post->create(
@@ -1558,6 +1562,10 @@ public function test_edit_post_prefers_the_password_over_a_contradicting_public_
15581562
)
15591563
);
15601564

1561-
$this->assertSame( 'secret', get_post( $post_id )->post_password );
1565+
$this->assertSame(
1566+
'',
1567+
get_post( $post_id )->post_password,
1568+
'An explicit public visibility was overridden by the inferred one.'
1569+
);
15621570
}
15631571
}

0 commit comments

Comments
 (0)