Taxonomy: Prevent deprecation notices clearing terms.

Prevents `wp_set_object_terms()` throwing a deprecation notice in PHP 8.1+ when passing an empty value as the second parameter to clear the terms.

Props audrasjb, chouby, costdev, jrf, peterwilsoncc, prashantbhivsane, sergeybiryukov.
Fixes #57923.


git-svn-id: https://develop.svn.wordpress.org/trunk@55921 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Peter Wilson
2023-06-14 23:49:36 +00:00
parent a5db7658be
commit 6178829ab0
2 changed files with 69 additions and 21 deletions

View File

@@ -2737,7 +2737,7 @@ function wp_insert_term( $term, $taxonomy, $args = array() ) {
* @param int $object_id The object to relate to.
* @param string|int|array $terms A single term slug, single term ID, or array of either term slugs or IDs.
* Will replace all existing related terms in this taxonomy. Passing an
* empty value will remove all related terms.
* empty array will remove all related terms.
* @param string $taxonomy The context in which to relate the term to the object.
* @param bool $append Optional. If false will delete difference of terms. Default false.
* @return array|WP_Error Term taxonomy IDs of the affected terms or WP_Error on failure.
@@ -2751,7 +2751,9 @@ function wp_set_object_terms( $object_id, $terms, $taxonomy, $append = false ) {
return new WP_Error( 'invalid_taxonomy', __( 'Invalid taxonomy.' ) );
}
if ( ! is_array( $terms ) ) {
if ( empty( $terms ) ) {
$terms = array();
} elseif ( ! is_array( $terms ) ) {
$terms = array( $terms );
}

View File

@@ -4,11 +4,13 @@
* @group taxonomy
*/
class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
protected $taxonomy = 'category';
protected static $taxonomy = 'category';
protected static $post_ids = array();
protected static $term_ids = array();
public static function wpSetUpBeforeClass( WP_UnitTest_Factory $factory ) {
self::$post_ids = $factory->post->create_many( 5 );
self::$term_ids = $factory->term->create_many( 5, array( 'taxonomy' => self::$taxonomy ) );
}
/**
@@ -105,26 +107,26 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
$terms = array();
for ( $i = 0; $i < 3; $i++ ) {
$term = "term_{$i}";
$result = wp_insert_term( $term, $this->taxonomy );
$result = wp_insert_term( $term, self::$taxonomy );
$this->assertIsArray( $result );
$term_id[ $term ] = $result['term_id'];
}
foreach ( $ids as $id ) {
$tt = wp_set_object_terms( $id, array_values( $term_id ), $this->taxonomy );
$tt = wp_set_object_terms( $id, array_values( $term_id ), self::$taxonomy );
// Should return three term taxonomy IDs.
$this->assertCount( 3, $tt );
}
// Each term should be associated with every post.
foreach ( $term_id as $term => $id ) {
$actual = get_objects_in_term( $id, $this->taxonomy );
$actual = get_objects_in_term( $id, self::$taxonomy );
$this->assertSame( $ids, array_map( 'intval', $actual ) );
}
// Each term should have a count of 5.
foreach ( array_keys( $term_id ) as $term ) {
$t = get_term_by( 'name', $term, $this->taxonomy );
$t = get_term_by( 'name', $term, self::$taxonomy );
$this->assertSame( 5, $t->count );
}
}
@@ -139,25 +141,25 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
);
foreach ( $ids as $id ) {
$tt = wp_set_object_terms( $id, $terms, $this->taxonomy );
$tt = wp_set_object_terms( $id, $terms, self::$taxonomy );
// Should return three term taxonomy IDs.
$this->assertCount( 3, $tt );
// Remember which term has which term_id.
for ( $i = 0; $i < 3; $i++ ) {
$term = get_term_by( 'name', $terms[ $i ], $this->taxonomy );
$term = get_term_by( 'name', $terms[ $i ], self::$taxonomy );
$term_id[ $terms[ $i ] ] = (int) $term->term_id;
}
}
// Each term should be associated with every post.
foreach ( $term_id as $term => $id ) {
$actual = get_objects_in_term( $id, $this->taxonomy );
$actual = get_objects_in_term( $id, self::$taxonomy );
$this->assertSame( $ids, array_map( 'intval', $actual ) );
}
// Each term should have a count of 5.
foreach ( $terms as $term ) {
$t = get_term_by( 'name', $term, $this->taxonomy );
$t = get_term_by( 'name', $term, self::$taxonomy );
$this->assertSame( 5, $t->count );
}
}
@@ -253,7 +255,7 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
$terms_1 = array();
for ( $i = 0; $i < 3; $i++ ) {
$term = "term_{$i}";
$result = wp_insert_term( $term, $this->taxonomy );
$result = wp_insert_term( $term, self::$taxonomy );
$this->assertIsArray( $result );
$terms_1[ $i ] = $result['term_id'];
}
@@ -263,17 +265,17 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
$terms_2[0] = $terms_1[1];
$term = 'term';
$result = wp_insert_term( $term, $this->taxonomy );
$result = wp_insert_term( $term, self::$taxonomy );
$terms_2[1] = $result['term_id'];
// Set the initial terms.
$tt_1 = wp_set_object_terms( $post_id, $terms_1, $this->taxonomy );
$tt_1 = wp_set_object_terms( $post_id, $terms_1, self::$taxonomy );
$this->assertCount( 3, $tt_1 );
// Make sure they're correct.
$terms = wp_get_object_terms(
$post_id,
$this->taxonomy,
self::$taxonomy,
array(
'fields' => 'ids',
'orderby' => 'term_id',
@@ -282,13 +284,13 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
$this->assertSame( $terms_1, $terms );
// Change the terms.
$tt_2 = wp_set_object_terms( $post_id, $terms_2, $this->taxonomy );
$tt_2 = wp_set_object_terms( $post_id, $terms_2, self::$taxonomy );
$this->assertCount( 2, $tt_2 );
// Make sure they're correct.
$terms = wp_get_object_terms(
$post_id,
$this->taxonomy,
self::$taxonomy,
array(
'fields' => 'ids',
'orderby' => 'term_id',
@@ -311,13 +313,13 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
$terms_2 = array( 'bar', 'bing' );
// Set the initial terms.
$tt_1 = wp_set_object_terms( $post_id, $terms_1, $this->taxonomy );
$tt_1 = wp_set_object_terms( $post_id, $terms_1, self::$taxonomy );
$this->assertCount( 3, $tt_1 );
// Make sure they're correct.
$terms = wp_get_object_terms(
$post_id,
$this->taxonomy,
self::$taxonomy,
array(
'fields' => 'names',
'orderby' => 'term_id',
@@ -326,13 +328,13 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
$this->assertSame( $terms_1, $terms );
// Change the terms.
$tt_2 = wp_set_object_terms( $post_id, $terms_2, $this->taxonomy );
$tt_2 = wp_set_object_terms( $post_id, $terms_2, self::$taxonomy );
$this->assertCount( 2, $tt_2 );
// Make sure they're correct.
$terms = wp_get_object_terms(
$post_id,
$this->taxonomy,
self::$taxonomy,
array(
'fields' => 'names',
'orderby' => 'term_id',
@@ -430,4 +432,48 @@ class Tests_Term_WpSetObjectTerms extends WP_UnitTestCase {
$this->assertSame( array(), $tt_ids );
}
/**
* Tests that empty values clear an object of all terms.
*
* @ticket 57923
*
* @dataProvider data_empty_value_should_clear_terms
*
* @param mixed $empty_value An empty value.
*/
public function test_empty_value_should_clear_terms( $empty_value ) {
$post_id = self::$post_ids[0];
// Assign some terms.
wp_set_object_terms( $post_id, self::$term_ids, self::$taxonomy );
// Make sure the terms are set.
$terms = wp_get_object_terms( $post_id, self::$taxonomy, array( 'fields' => 'names' ) );
$this->assertNotEmpty( $terms, 'Terms should initially be applied to post object.' );
// Remove terms by passing an empty value.
wp_set_object_terms( $post_id, $empty_value, self::$taxonomy );
// Make sure the terms have been removed.
$terms = wp_get_object_terms( $post_id, self::$taxonomy, array( 'fields' => 'names' ) );
$this->assertEmpty( $terms, 'An empty() value should clear terms from the post object.' );
}
/**
* Data provider.
*
* @return array[]
*/
public function data_empty_value_should_clear_terms() {
return array(
'(bool) false' => array( false ),
'null' => array( null ),
'(int) 0' => array( 0 ),
'(float) 0.0' => array( 0.0 ),
'empty string' => array( '' ),
'(string) 0' => array( '0' ),
'empty array' => array( array() ),
);
}
}