Posts/Post Types: Prevent duplicates in sticky posts option.

In `unstick_post()` if a post ID is duplicated in the `sticky_posts` option remove all instances.

In both `stick_post()` and `unstick_post()` check for duplicate IDs already stored in the `sticky_post` option and remove them if the option is updated.

Props rahmohn, archon810.
Fixes #52007.


git-svn-id: https://develop.svn.wordpress.org/trunk@50380 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Peter Wilson
2021-02-17 22:56:34 +00:00
parent 4f25e74baa
commit 50af962653
2 changed files with 160 additions and 6 deletions
+6 -6
View File
@@ -2626,19 +2626,19 @@ function sanitize_post_field( $field, $value, $post_id, $context = 'display' ) {
function stick_post( $post_id ) {
$post_id = (int) $post_id;
$stickies = get_option( 'sticky_posts' );
$updated = false;
if ( ! is_array( $stickies ) ) {
$stickies = array();
$stickies = array( $post_id );
} else {
$stickies = array_unique( array_map( 'intval', $stickies ) );
}
$stickies = array_map( 'intval', $stickies );
if ( ! in_array( $post_id, $stickies, true ) ) {
$stickies[] = $post_id;
$updated = update_option( 'sticky_posts', array_values( $stickies ) );
}
$updated = update_option( 'sticky_posts', $stickies );
if ( $updated ) {
/**
* Fires once a post has been added to the sticky list.
@@ -2668,7 +2668,7 @@ function unstick_post( $post_id ) {
return;
}
$stickies = array_map( 'intval', $stickies );
$stickies = array_values( array_unique( array_map( 'intval', $stickies ) ) );
if ( ! in_array( $post_id, $stickies, true ) ) {
return;
+154
View File
@@ -1637,4 +1637,158 @@ class Tests_Post extends WP_UnitTestCase {
$resolved_post_date = wp_resolve_post_date( $invalid_date, $invalid_date );
$this->assertFalse( $resolved_post_date );
}
/**
* Ensure sticking post updates option.
*
* @covers ::stick_post
*/
function test_sticky_posts() {
stick_post( 1 );
$this->assertSameSets( array( 1 ), get_option( 'sticky_posts' ) );
stick_post( 2 );
$this->assertSameSets( array( 1, 2 ), get_option( 'sticky_posts' ) );
}
/**
* Ensure sticking posts can not duplicate options.
*
* @ticket 52007
* @covers ::stick_post
* @dataProvider data_sticky_posts_not_duplicate_with_the_same_value
*
* @param mixed $stick Value to pass to stick_post().
*/
function test_sticky_posts_not_duplicate_with_the_same_value( $stick ) {
update_option( 'sticky_posts', array( 1, 2 ) );
stick_post( $stick );
$this->assertSameSets( array( 1, 2 ), get_option( 'sticky_posts' ) );
}
/**
* Data provider for test_sticky_posts_not_duplicate_with_the_same_value().
*
* @return array[] {
* Arguments passed to test.
*
* @type mixed $stick Value to pass to stick_post().
* }
*/
function data_sticky_posts_not_duplicate_with_the_same_value() {
return array(
array( 1 ),
array( '1' ),
array( 2.0 ),
);
}
/**
* Ensure sticking post removes other duplicates.
*
* @ticket 52007
* @covers ::stick_post
*
* @param mixed $stick Value to pass to stick_post().
*/
function test_sticky_posts_remove_duplicate_ids_when_add_new_value() {
update_option( 'sticky_posts', array( 1, 1, 2, 2 ) );
stick_post( 3 );
$this->assertSameSets( array( 1, 2, 3 ), get_option( 'sticky_posts' ) );
}
function test_unsticky_posts() {
update_option( 'sticky_posts', array( 1 ) );
unstick_post( 1 );
$this->assertEmpty( get_option( 'sticky_posts' ) );
update_option( 'sticky_posts', array( 1, 2 ) );
unstick_post( 1 );
$this->assertSameSets( array( 2 ), get_option( 'sticky_posts' ) );
}
/**
* Ensure duplicates removed when unsticking posts.
*
* @ticket 52007
* @covers ::unstick_post
*
* @dataProvider data_unstick_posts_with_duplicate_id
*
* @param array $starting_option Original value of `sticky_posts` option.
* @param mixed $unstick Parameter passed to `unstick_post()`
* @param array $expected
*/
function test_unstick_posts_with_duplicate_id( $starting_option, $unstick, $expected ) {
update_option( 'sticky_posts', $starting_option );
unstick_post( $unstick );
$this->assertSameSets( $expected, get_option( 'sticky_posts' ) );
}
/**
* Data provider for test_unstick_posts_with_duplicate_id
*
* @return array[] {
* Arguments passed to test.
*
* @type array $starting_option Original value of `sticky_posts` option.
* @type mixed $unstick Parameter passed to `unstick_post()`
* @type array $expected
* }
*/
function data_unstick_posts_with_duplicate_id() {
return array(
array(
array( 1, 1 ),
1,
array(),
),
array(
array( 1, 1 ),
'1',
array(),
),
array(
array( 1, 2, 1 ),
1,
array( 2 ),
),
array(
array( 1, 2, 1 ),
2,
array( 1 ),
),
array(
array( 1, 2, 1 ),
2.0,
array( 1 ),
),
);
}
/**
* Ensure sticking duplicate does not trigger db update.
*
* @ticket 52007
* @covers ::stick_post
*/
function test_sticking_dupes_does_not_trigger_update() {
update_option( 'sticky_posts', array( 1, 2, 2 ) );
stick_post( 2 );
$this->assertEquals( array( 1, 2, 2 ), get_option( 'sticky_posts' ) );
}
/**
* Ensure unsticking unstuck post does not trigger db update.
*
* @ticket 52007
* @covers ::unstick_post
*/
function test_unsticking_unstuck_post_does_not_trigger_update() {
update_option( 'sticky_posts', array( 1, 2, 2 ) );
unstick_post( 3 );
$this->assertEquals( array( 1, 2, 2 ), get_option( 'sticky_posts' ) );
}
}