diff --git a/src/wp-includes/taxonomy.php b/src/wp-includes/taxonomy.php index eaa48edb5c..013c3d3cdd 100644 --- a/src/wp-includes/taxonomy.php +++ b/src/wp-includes/taxonomy.php @@ -2933,6 +2933,10 @@ function wp_update_term( $term_id, $taxonomy, $args = array() ) { if ( '' == trim($name) ) return new WP_Error('empty_term_name', __('A name is required for this term')); + if ( $parsed_args['parent'] > 0 && ! term_exists( (int) $parsed_args['parent'] ) ) { + return new WP_Error( 'missing_parent', __( 'Parent term does not exist.' ) ); + } + $empty_slug = false; if ( empty( $args['slug'] ) ) { $empty_slug = true; diff --git a/tests/phpunit/tests/term.php b/tests/phpunit/tests/term.php index ef4051765e..d6dedd6c3b 100644 --- a/tests/phpunit/tests/term.php +++ b/tests/phpunit/tests/term.php @@ -631,6 +631,32 @@ class Tests_Term extends WP_UnitTestCase { $this->assertTrue( in_array( $found['term_id'], $cached_children[ $t ] ) ); } + /** + * @ticket 29614 + */ + function test_wp_update_term_parent_does_not_exist() { + register_taxonomy( 'wptests_tax', array( + 'hierarchical' => true, + ) ); + $fake_term_id = 787878; + + $this->assertNull( term_exists( $fake_term_id, 'wptests_tax' ) ); + + $t = $this->factory->term->create( array( + 'taxonomy' => 'wptests_tax', + ) ); + + $found = wp_update_term( $t, 'wptests_tax', array( + 'parent' => $fake_term_id, + ) ); + + $this->assertWPError( $found ); + $this->assertSame( 'missing_parent', $found->get_error_code() ); + + $term = get_term( $t, 'wptests_tax' ); + $this->assertEquals( 0, $term->parent ); + } + public function test_wp_update_term_alias_of_no_term_group() { register_taxonomy( 'wptests_tax', 'post' ); $t1 = $this->factory->term->create( array(