From 3af21a237ab64ee98e58e7c74493ba72e17b1b97 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Wed, 5 Aug 2026 15:38:25 +0530 Subject: [PATCH 1/8] Prevent private posts from being sticky by unsticking them and disabling the sticky UI in bulk and inline editors --- src/js/_enqueues/admin/inline-edit-post.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/js/_enqueues/admin/inline-edit-post.js b/src/js/_enqueues/admin/inline-edit-post.js index 6e6e3bef606ed..483096d9c095f 100644 --- a/src/js/_enqueues/admin/inline-edit-post.js +++ b/src/js/_enqueues/admin/inline-edit-post.js @@ -109,14 +109,19 @@ window.wp = window.wp || {}; }); /** - * Disables the password input field when the private post checkbox is checked. + * Disables the password input field and sticky option when the private post checkbox is checked. */ - $('#inline-edit .inline-edit-private input[value="private"]').on( 'click', function(){ - var pw = $('input.inline-edit-password-input'); - if ( $(this).prop('checked') ) { - pw.val('').prop('disabled', true); + $( 'table.widefat' ).on( 'change', '.inline-edit-private input[value="private"]', function() { + var editRow = $( this ).closest( 'tr' ), + pw = $( 'input.inline-edit-password-input', editRow ), + sticky = $( 'input[name="sticky"]', editRow ); + + if ( $( this ).prop( 'checked' ) ) { + pw.val( '' ).prop( 'disabled', true ); + sticky.prop( 'checked', false ).prop( 'disabled', true ); } else { - pw.prop('disabled', false); + pw.prop( 'disabled', false ); + sticky.prop( 'disabled', false ); } }); From b75107d74bf75fc73510e365b26390d7100ef36e Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Wed, 5 Aug 2026 15:39:13 +0530 Subject: [PATCH 2/8] Disable sticky option when the status is set to `Private` in bulk edit. --- src/js/_enqueues/admin/inline-edit-post.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/js/_enqueues/admin/inline-edit-post.js b/src/js/_enqueues/admin/inline-edit-post.js index 483096d9c095f..ee7b6cfcb1dbc 100644 --- a/src/js/_enqueues/admin/inline-edit-post.js +++ b/src/js/_enqueues/admin/inline-edit-post.js @@ -149,6 +149,15 @@ window.wp = window.wp || {}; $('select[name="_status"] option[value="future"]', bulkRow).remove(); + // Disable sticky option when the status is set to 'Private' in bulk edit. + $( '#bulk-edit' ).on( 'change', 'select[name="_status"]', function() { + if ( 'private' === $( this ).val() ) { + $( '#bulk-edit select[name="sticky"]' ).val( '-1' ).prop( 'disabled', true ); + } else { + $( '#bulk-edit select[name="sticky"]' ).prop( 'disabled', false ); + } + }); + /** * Adds onclick events to the apply buttons. */ From cecfa51e58f64d7ba00e061f3b4fa1c8e67d512f Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Wed, 5 Aug 2026 15:39:49 +0530 Subject: [PATCH 3/8] Disable private status when sitcky --- src/js/_enqueues/admin/inline-edit-post.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js/_enqueues/admin/inline-edit-post.js b/src/js/_enqueues/admin/inline-edit-post.js index ee7b6cfcb1dbc..0d5b64bb9a323 100644 --- a/src/js/_enqueues/admin/inline-edit-post.js +++ b/src/js/_enqueues/admin/inline-edit-post.js @@ -463,6 +463,7 @@ window.wp = window.wp || {}; if ( 'private' === status ) { $('input[name="keep_private"]', editRow).prop('checked', true); pw.val( '' ).prop( 'disabled', true ); + $('input[name="sticky"]', editRow).prop('checked', false).prop('disabled', true); } // Remove the current page and children from the parent dropdown. From 4b8b1068d2889ca92109777ba583a1a8ea8f957c Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Wed, 5 Aug 2026 15:40:02 +0530 Subject: [PATCH 4/8] Prevent private posts from becoming sticky during bulk edit operations --- src/wp-admin/includes/post.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php index 39d267b623037..2280c2f9a740d 100644 --- a/src/wp-admin/includes/post.php +++ b/src/wp-admin/includes/post.php @@ -706,7 +706,11 @@ function bulk_edit_posts( $post_data = null ) { update_post_meta( $post_id, '_edit_last', get_current_user_id() ); $updated[] = $post_id; - if ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) { + $post_status = ! empty( $post_data['post_status'] ) ? $post_data['post_status'] : $post->post_status; + + if ( 'private' === $post_status ) { + unstick_post( $post_id ); + } elseif ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) { if ( 'sticky' === $post_data['sticky'] ) { stick_post( $post_id ); } else { From 70accf1f4d100ce0927eacfc3dd9e6e3a6c98efb Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Wed, 5 Aug 2026 15:40:39 +0530 Subject: [PATCH 5/8] Tests: add test case ensuring private posts remain non-sticky during bulk edit --- tests/phpunit/tests/admin/includesPost.php | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/phpunit/tests/admin/includesPost.php b/tests/phpunit/tests/admin/includesPost.php index d9d39d8da727d..fe2d20485bf22 100644 --- a/tests/phpunit/tests/admin/includesPost.php +++ b/tests/phpunit/tests/admin/includesPost.php @@ -258,6 +258,33 @@ public function test_bulk_edit_posts_stomping() { $this->assertSame( 'closed', $post->ping_status ); } + /** + * Private posts should not be made sticky during bulk edit. + * + * @ticket 39946 + */ + public function test_bulk_edit_posts_should_not_make_private_posts_sticky() { + wp_set_current_user( self::$admin_id ); + + $post_id = self::factory()->post->create( + array( + 'post_status' => 'publish', + ) + ); + + $request = array( + 'post_type' => 'post', + 'sticky' => 'sticky', + '_status' => 'private', + 'post' => array( $post_id ), + ); + + bulk_edit_posts( $request ); + + $this->assertSame( 'private', get_post_status( $post_id ) ); + $this->assertFalse( is_sticky( $post_id ) ); + } + /** * The bulk_edit_posts() function should preserve the post format * when it's unchanged. From af13068c2b0ca76a94f12ac3ba59e2b84e67916a Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Wed, 5 Aug 2026 15:41:08 +0530 Subject: [PATCH 6/8] Tests: add test case to ensure bulk edit unsticks existing private posts --- tests/phpunit/tests/admin/includesPost.php | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/phpunit/tests/admin/includesPost.php b/tests/phpunit/tests/admin/includesPost.php index fe2d20485bf22..5d6f9c17ad8be 100644 --- a/tests/phpunit/tests/admin/includesPost.php +++ b/tests/phpunit/tests/admin/includesPost.php @@ -285,6 +285,33 @@ public function test_bulk_edit_posts_should_not_make_private_posts_sticky() { $this->assertFalse( is_sticky( $post_id ) ); } + /** + * Existing private posts should not be made sticky during bulk edit. + * + * @ticket 39946 + */ + public function test_bulk_edit_posts_should_unstick_existing_private_posts() { + wp_set_current_user( self::$admin_id ); + + $post_id = self::factory()->post->create( + array( + 'post_status' => 'private', + ) + ); + stick_post( $post_id ); + + $request = array( + 'post_type' => 'post', + 'sticky' => 'sticky', + '_status' => '-1', + 'post' => array( $post_id ), + ); + + bulk_edit_posts( $request ); + + $this->assertFalse( is_sticky( $post_id ) ); + } + /** * The bulk_edit_posts() function should preserve the post format * when it's unchanged. From 0897a3b63a91ad162546bdcc3e2c295aadcb59ee Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Wed, 12 Aug 2026 14:31:21 +0530 Subject: [PATCH 7/8] Add comment mentioning private posts cannot be sticky --- src/wp-admin/includes/post.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php index 2280c2f9a740d..a754c3aa44c47 100644 --- a/src/wp-admin/includes/post.php +++ b/src/wp-admin/includes/post.php @@ -708,6 +708,7 @@ function bulk_edit_posts( $post_data = null ) { $post_status = ! empty( $post_data['post_status'] ) ? $post_data['post_status'] : $post->post_status; + // Private posts cannot be sticky. if ( 'private' === $post_status ) { unstick_post( $post_id ); } elseif ( isset( $post_data['sticky'] ) && current_user_can( $ptype->cap->edit_others_posts ) ) { From f92ddb3ebb7d139d1675ce71331f0f3fb32020f3 Mon Sep 17 00:00:00 2001 From: Himanshu Pathak Date: Wed, 12 Aug 2026 14:31:36 +0530 Subject: [PATCH 8/8] Add test case to verify non-private posts are made sticky during bulk edit --- tests/phpunit/tests/admin/includesPost.php | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/phpunit/tests/admin/includesPost.php b/tests/phpunit/tests/admin/includesPost.php index 5d6f9c17ad8be..252aa2912db65 100644 --- a/tests/phpunit/tests/admin/includesPost.php +++ b/tests/phpunit/tests/admin/includesPost.php @@ -312,6 +312,32 @@ public function test_bulk_edit_posts_should_unstick_existing_private_posts() { $this->assertFalse( is_sticky( $post_id ) ); } + /** + * Non-private posts should be made sticky during bulk edit. + * + * @ticket 39946 + */ + public function test_bulk_edit_posts_should_make_non_private_posts_sticky() { + wp_set_current_user( self::$admin_id ); + + $post_id = self::factory()->post->create( + array( + 'post_status' => 'publish', + ) + ); + + $request = array( + 'post_type' => 'post', + 'sticky' => 'sticky', + '_status' => '-1', + 'post' => array( $post_id ), + ); + + bulk_edit_posts( $request ); + + $this->assertTrue( is_sticky( $post_id ) ); + } + /** * The bulk_edit_posts() function should preserve the post format * when it's unchanged.