Make WordPress Core


Ignore:
Timestamp:
11/05/2014 02:02:48 AM (12 years ago)
Author:
boonebgorges
Message:

Split shared taxonomy terms during term update.

When updating an existing taxonomy term that shares its term_id with
another term, we generate a new row in wp_terms and associate the updated
term_taxonomy_id with the new term. This separates the terms, such that
updating the name of one term does not change the name of any others.

Note that this term splitting only occurs on installations whose database
schemas have been upgraded to version 30133 or higher. Note also that shared
terms are only split when run through wp_update_term(), as on edit-tags.php;
we will wait until a future release of WordPress to force the splitting of all
shared taxonomy terms.

Props boonebgorges, rmccue, greuben, garyc40, wonderboymusic, imath, jesin.
Fixes #5809.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/term.php

    r30240 r30241  
    638638        }
    639639
     640        /**
     641         * @ticket 5809
     642         */
     643        public function test_wp_update_term_duplicate_slug_same_taxonomy() {
     644                register_taxonomy( 'wptests_tax', 'post' );
     645
     646                $t1 = $this->factory->term->create( array(
     647                        'name' => 'Foo',
     648                        'slug' => 'foo',
     649                        'taxonomy' => 'wptests_tax',
     650                ) );
     651
     652                $t2 = $this->factory->term->create( array(
     653                        'name' => 'Foo',
     654                        'slug' => 'bar',
     655                        'taxonomy' => 'wptests_tax',
     656                ) );
     657
     658                $updated = wp_update_term( $t2, 'wptests_tax', array(
     659                        'slug' => 'foo',
     660                ) );
     661
     662                $this->assertWPError( $updated );
     663                $this->assertSame( 'duplicate_term_slug', $updated->get_error_code() );
     664        }
     665
     666        /**
     667         * @ticket 5809
     668         */
     669        public function test_wp_update_term_duplicate_slug_different_taxonomy() {
     670                register_taxonomy( 'wptests_tax', 'post' );
     671                register_taxonomy( 'wptests_tax_2', 'post' );
     672
     673                $t1 = $this->factory->term->create( array(
     674                        'name' => 'Foo',
     675                        'slug' => 'foo',
     676                        'taxonomy' => 'wptests_tax',
     677                ) );
     678
     679                $t2 = $this->factory->term->create( array(
     680                        'name' => 'Foo',
     681                        'slug' => 'bar',
     682                        'taxonomy' => 'wptests_tax_2',
     683                ) );
     684
     685                $updated = wp_update_term( $t2, 'wptests_tax_2', array(
     686                        'slug' => 'foo',
     687                ) );
     688
     689                $this->assertWPError( $updated );
     690                $this->assertSame( 'duplicate_term_slug', $updated->get_error_code() );
     691        }
     692
     693        /**
     694         * @ticket 5809
     695         */
     696        public function test_wp_update_term_should_split_shared_term() {
     697                global $wpdb;
     698
     699                register_taxonomy( 'wptests_tax', 'post' );
     700                register_taxonomy( 'wptests_tax_2', 'post' );
     701
     702                $t1 = wp_insert_term( 'Foo', 'wptests_tax' );
     703                $t2 = wp_insert_term( 'Foo', 'wptests_tax_2' );
     704
     705                // Manually modify because split terms shouldn't naturally occur.
     706                $wpdb->update( $wpdb->term_taxonomy,
     707                        array( 'term_id' => $t1['term_id'] ),
     708                        array( 'term_taxonomy_id' => $t2['term_taxonomy_id'] ),
     709                        array( '%d' ),
     710                        array( '%d' )
     711                );
     712
     713                $posts = $this->factory->post->create_many( 2 );
     714                wp_set_object_terms( $posts[0], array( 'Foo' ), 'wptests_tax' );
     715                wp_set_object_terms( $posts[1], array( 'Foo' ), 'wptests_tax_2' );
     716
     717                // Verify that the terms are shared.
     718                $t1_terms = wp_get_object_terms( $posts[0], 'wptests_tax' );
     719                $t2_terms = wp_get_object_terms( $posts[1], 'wptests_tax_2' );
     720                $this->assertSame( $t1_terms[0]->term_id, $t2_terms[0]->term_id );
     721
     722                wp_update_term( $t2_terms[0]->term_id, 'wptests_tax_2', array(
     723                        'name' => 'New Foo',
     724                ) );
     725
     726                $t1_terms = wp_get_object_terms( $posts[0], 'wptests_tax' );
     727                $t2_terms = wp_get_object_terms( $posts[1], 'wptests_tax_2' );
     728                $this->assertNotEquals( $t1_terms[0]->term_id, $t2_terms[0]->term_id );
     729        }
     730
     731        /**
     732         * @ticket 5809
     733         */
     734        public function test_wp_update_term_should_not_split_shared_term_before_410_schema_change() {
     735                global $wpdb;
     736
     737                $db_version = get_option( 'db_version' );
     738                update_option( 'db_version', 30055 );
     739
     740                register_taxonomy( 'wptests_tax', 'post' );
     741                register_taxonomy( 'wptests_tax_2', 'post' );
     742
     743                $t1 = wp_insert_term( 'Foo', 'wptests_tax' );
     744                $t2 = wp_insert_term( 'Foo', 'wptests_tax_2' );
     745
     746                // Manually modify because split terms shouldn't naturally occur.
     747                $wpdb->update( $wpdb->term_taxonomy,
     748                        array( 'term_id' => $t1['term_id'] ),
     749                        array( 'term_taxonomy_id' => $t2['term_taxonomy_id'] ),
     750                        array( '%d' ),
     751                        array( '%d' )
     752                );
     753
     754                $posts = $this->factory->post->create_many( 2 );
     755                wp_set_object_terms( $posts[0], array( 'Foo' ), 'wptests_tax' );
     756                wp_set_object_terms( $posts[1], array( 'Foo' ), 'wptests_tax_2' );
     757
     758                // Verify that the term is shared.
     759                $t1_terms = wp_get_object_terms( $posts[0], 'wptests_tax' );
     760                $t2_terms = wp_get_object_terms( $posts[1], 'wptests_tax_2' );
     761                $this->assertSame( $t1_terms[0]->term_id, $t2_terms[0]->term_id );
     762
     763                wp_update_term( $t2_terms[0]->term_id, 'wptests_tax_2', array(
     764                        'name' => 'New Foo',
     765                ) );
     766
     767                // Term should still be shared.
     768                $t1_terms = wp_get_object_terms( $posts[0], 'wptests_tax' );
     769                $t2_terms = wp_get_object_terms( $posts[1], 'wptests_tax_2' );
     770                $this->assertSame( $t1_terms[0]->term_id, $t2_terms[0]->term_id );
     771
     772                update_option( 'db_version', $db_version );
     773        }
     774
    640775        public function test_wp_update_term_alias_of_no_term_group() {
    641776                register_taxonomy( 'wptests_tax', 'post' );
     
    14671602
    14681603        /**
    1469          * @ticket 5809
    1470          */
    1471         function test_update_shared_term() {
    1472                 $random_tax = __FUNCTION__;
    1473 
    1474                 register_taxonomy( $random_tax, 'post' );
    1475 
    1476                 $post_id = $this->factory->post->create();
    1477 
    1478                 $old_name = 'Initial';
    1479 
    1480                 $t1 = wp_insert_term( $old_name, 'category' );
    1481                 $t2 = wp_insert_term( $old_name, 'post_tag' );
    1482 
    1483                 $this->assertEquals( $t1['term_id'], $t2['term_id'] );
    1484 
    1485                 wp_set_post_categories( $post_id, array( $t1['term_id'] ) );
    1486                 wp_set_post_tags( $post_id, array( (int) $t2['term_id'] ) );
    1487 
    1488                 $new_name = 'Updated';
    1489 
    1490                 // create the term in a third taxonomy, just to keep things interesting
    1491                 $t3 = wp_insert_term( $old_name, $random_tax );
    1492                 wp_set_post_terms( $post_id, array( (int) $t3['term_id'] ), $random_tax );
    1493                 $this->assertPostHasTerms( $post_id, array( $t3['term_id'] ), $random_tax );
    1494 
    1495                 $t2_updated = wp_update_term( $t2['term_id'], 'post_tag', array(
    1496                         'name' => $new_name
    1497                 ) );
    1498 
    1499                 $this->assertNotEquals( $t2_updated['term_id'], $t3['term_id'] );
    1500 
    1501                 // make sure the terms have split
    1502                 $this->assertEquals( $old_name, get_term_field( 'name', $t1['term_id'], 'category' ) );
    1503                 $this->assertEquals( $new_name, get_term_field( 'name', $t2_updated['term_id'], 'post_tag' ) );
    1504 
    1505                 // and that they are still assigned to the correct post
    1506                 $this->assertPostHasTerms( $post_id, array( $t1['term_id'] ), 'category' );
    1507                 $this->assertPostHasTerms( $post_id, array( $t2_updated['term_id'] ), 'post_tag' );
    1508                 $this->assertPostHasTerms( $post_id, array( $t3['term_id'] ), $random_tax );
    1509 
    1510                 // clean up
    1511                 unset( $GLOBALS['wp_taxonomies'][ $random_tax ] );
    1512         }
    1513 
    1514         /**
    15151604         * @ticket 25852
    15161605         */
Note: See TracChangeset for help on using the changeset viewer.