Make WordPress Core


Ignore:
Timestamp:
02/11/2015 07:41:54 PM (12 years ago)
Author:
boonebgorges
Message:

Split shared taxonomy terms on 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.

In cases where a plugin or theme stores term IDs in the database, term splitting
can cause backward compatibility issues. The current changeset introduces
two utilities to aid developers with the transition. The 'split_shared_term'
action fires when the split takes place, and should be used to catch changes in
term_id. In cases where 'split_shared_term' cannot be used, the
wp_get_split_term() function gives developers access to data about terms
that have previously been split. Documentation for these functions, with
examples, can be found in the Plugin Developer Handbook. WordPress itself
stores term IDs in this way in two places; _wp_check_split_default_terms()
and _wp_check_split_terms_in_menus() are hooked to 'split_shared_term' to
perform the necessary cleanup.

See [30241] for a previous attempt at the split. It was reverted in [30585]
for 4.1.0.

Props boonebgorges, mboynes.
See #5809.

File:
1 edited

Legend:

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

    r31287 r31418  
    761761        }
    762762
     763        /**
     764         * @ticket 5809
     765         */
     766        public function test_wp_update_term_should_split_shared_term() {
     767                global $wpdb;
     768
     769                register_taxonomy( 'wptests_tax', 'post' );
     770                register_taxonomy( 'wptests_tax_2', 'post' );
     771
     772                $t1 = wp_insert_term( 'Foo', 'wptests_tax' );
     773                $t2 = wp_insert_term( 'Foo', 'wptests_tax_2' );
     774
     775                // Manually modify because split terms shouldn't naturally occur.
     776                $wpdb->update( $wpdb->term_taxonomy,
     777                        array( 'term_id' => $t1['term_id'] ),
     778                        array( 'term_taxonomy_id' => $t2['term_taxonomy_id'] ),
     779                        array( '%d' ),
     780                        array( '%d' )
     781                );
     782
     783                $posts = $this->factory->post->create_many( 2 );
     784                wp_set_object_terms( $posts[0], array( 'Foo' ), 'wptests_tax' );
     785                wp_set_object_terms( $posts[1], array( 'Foo' ), 'wptests_tax_2' );
     786
     787                // Verify that the terms are shared.
     788                $t1_terms = wp_get_object_terms( $posts[0], 'wptests_tax' );
     789                $t2_terms = wp_get_object_terms( $posts[1], 'wptests_tax_2' );
     790                $this->assertSame( $t1_terms[0]->term_id, $t2_terms[0]->term_id );
     791
     792                wp_update_term( $t2_terms[0]->term_id, 'wptests_tax_2', array(
     793                        'name' => 'New Foo',
     794                ) );
     795
     796                $t1_terms = wp_get_object_terms( $posts[0], 'wptests_tax' );
     797                $t2_terms = wp_get_object_terms( $posts[1], 'wptests_tax_2' );
     798                $this->assertNotEquals( $t1_terms[0]->term_id, $t2_terms[0]->term_id );
     799        }
     800
     801        /**
     802         * @ticket 5809
     803         */
     804        public function test_wp_update_term_should_not_split_shared_term_before_410_schema_change() {
     805                global $wpdb;
     806
     807                $db_version = get_option( 'db_version' );
     808                update_option( 'db_version', 30055 );
     809
     810                register_taxonomy( 'wptests_tax', 'post' );
     811                register_taxonomy( 'wptests_tax_2', 'post' );
     812
     813                $t1 = wp_insert_term( 'Foo', 'wptests_tax' );
     814                $t2 = wp_insert_term( 'Foo', 'wptests_tax_2' );
     815
     816                // Manually modify because split terms shouldn't naturally occur.
     817                $wpdb->update( $wpdb->term_taxonomy,
     818                        array( 'term_id' => $t1['term_id'] ),
     819                        array( 'term_taxonomy_id' => $t2['term_taxonomy_id'] ),
     820                        array( '%d' ),
     821                        array( '%d' )
     822                );
     823
     824                $posts = $this->factory->post->create_many( 2 );
     825                wp_set_object_terms( $posts[0], array( 'Foo' ), 'wptests_tax' );
     826                wp_set_object_terms( $posts[1], array( 'Foo' ), 'wptests_tax_2' );
     827
     828                // Verify that the term is shared.
     829                $t1_terms = wp_get_object_terms( $posts[0], 'wptests_tax' );
     830                $t2_terms = wp_get_object_terms( $posts[1], 'wptests_tax_2' );
     831                $this->assertSame( $t1_terms[0]->term_id, $t2_terms[0]->term_id );
     832
     833                wp_update_term( $t2_terms[0]->term_id, 'wptests_tax_2', array(
     834                        'name' => 'New Foo',
     835                ) );
     836
     837                // Term should still be shared.
     838                $t1_terms = wp_get_object_terms( $posts[0], 'wptests_tax' );
     839                $t2_terms = wp_get_object_terms( $posts[1], 'wptests_tax_2' );
     840                $this->assertSame( $t1_terms[0]->term_id, $t2_terms[0]->term_id );
     841
     842                update_option( 'db_version', $db_version );
     843        }
     844
    763845        public function test_wp_update_term_alias_of_no_term_group() {
    764846                register_taxonomy( 'wptests_tax', 'post' );
Note: See TracChangeset for help on using the changeset viewer.