Changeset 31418
- Timestamp:
- 02/11/2015 07:41:54 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/default-filters.php
r31168 r31418 307 307 add_filter( 'determine_current_user', 'wp_validate_logged_in_cookie', 20 ); 308 308 309 // Split term updates. 310 add_action( 'split_shared_term', '_wp_check_split_default_terms', 10, 4 ); 311 add_action( 'split_shared_term', '_wp_check_split_terms_in_menus', 10, 4 ); 312 309 313 /** 310 314 * Filters formerly mixed into wp-includes -
trunk/src/wp-includes/taxonomy.php
r31367 r31418 3431 3431 $tt_id = $wpdb->get_var( $wpdb->prepare( "SELECT tt.term_taxonomy_id FROM $wpdb->term_taxonomy AS tt INNER JOIN $wpdb->terms AS t ON tt.term_id = t.term_id WHERE tt.taxonomy = %s AND t.term_id = %d", $taxonomy, $term_id) ); 3432 3432 3433 // Check whether this is a shared term that needs splitting. 3434 $_term_id = _split_shared_term( $term_id, $tt_id ); 3435 if ( ! is_wp_error( $_term_id ) ) { 3436 $term_id = $_term_id; 3437 } 3438 3433 3439 /** 3434 3440 * Fires immediately before the given terms are edited. … … 4090 4096 do_action( 'edited_term_taxonomy', $term, $taxonomy ); 4091 4097 } 4098 } 4099 4100 /** 4101 * Create a new term for a term_taxonomy item that currently shares its term with another term_taxonomy. 4102 * 4103 * @since 4.2.0 4104 * @access private 4105 * 4106 * @param int $term_id ID of the shared term. 4107 * @param int $term_taxonomy_id ID of the term_taxonomy item to receive a new term. 4108 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current database 4109 * schema), `$term_id` is returned. When the term is successfully split, the new term_id is 4110 * returned. A `WP_Error` is returned for miscellaneous errors. 4111 */ 4112 function _split_shared_term( $term_id, $term_taxonomy_id ) { 4113 global $wpdb; 4114 4115 // Don't try to split terms if database schema does not support shared slugs. 4116 $current_db_version = get_option( 'db_version' ); 4117 if ( $current_db_version < 30133 ) { 4118 return $term_id; 4119 } 4120 4121 // If there are no shared term_taxonomy rows, there's nothing to do here. 4122 $shared_tt_count = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM $wpdb->term_taxonomy tt WHERE tt.term_id = %d AND tt.term_taxonomy_id != %d", $term_id, $term_taxonomy_id ) ); 4123 if ( ! $shared_tt_count ) { 4124 return $term_id; 4125 } 4126 4127 // Pull up data about the currently shared slug, which we'll use to populate the new one. 4128 $shared_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.* FROM $wpdb->terms t WHERE t.term_id = %d", $term_id ) ); 4129 4130 $new_term_data = array( 4131 'name' => $shared_term->name, 4132 'slug' => $shared_term->slug, 4133 'term_group' => $shared_term->term_group, 4134 ); 4135 4136 if ( false === $wpdb->insert( $wpdb->terms, $new_term_data ) ) { 4137 return new WP_Error( 'db_insert_error', __( 'Could not split shared term.' ), $wpdb->last_error ); 4138 } 4139 4140 $new_term_id = (int) $wpdb->insert_id; 4141 4142 // Update the existing term_taxonomy to point to the newly created term. 4143 $wpdb->update( $wpdb->term_taxonomy, 4144 array( 'term_id' => $new_term_id ), 4145 array( 'term_taxonomy_id' => $term_taxonomy_id ) 4146 ); 4147 4148 // Reassign child terms to the new parent. 4149 $term_taxonomy = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = %d", $term_taxonomy_id ) ); 4150 $children_tt_ids = $wpdb->get_col( $wpdb->prepare( "SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = %s AND parent = %d", $term_taxonomy->taxonomy, $term_id ) ); 4151 4152 if ( ! empty( $children_tt_ids ) ) { 4153 foreach ( $children_tt_ids as $child_tt_id ) { 4154 $wpdb->update( $wpdb->term_taxonomy, 4155 array( 'parent' => $new_term_id ), 4156 array( 'term_taxonomy_id' => $child_tt_id ) 4157 ); 4158 clean_term_cache( $term_id, $term_taxonomy->taxonomy ); 4159 } 4160 } else { 4161 // If the term has no children, we must force its taxonomy cache to be rebuilt separately. 4162 clean_term_cache( $new_term_id, $term_taxonomy->taxonomy ); 4163 } 4164 4165 // Clean the cache for term taxonomies formerly shared with the current term. 4166 $shared_term_taxonomies = $wpdb->get_row( $wpdb->prepare( "SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d", $term_id ) ); 4167 if ( $shared_term_taxonomies ) { 4168 foreach ( $shared_term_taxonomies as $shared_term_taxonomy ) { 4169 clean_term_cache( $term_id, $shared_term_taxonomy ); 4170 } 4171 } 4172 4173 // Keep a record of term_ids that have been split, keyed by old term_id. See {@see wp_get_split_term()}. 4174 $split_term_data = get_option( '_split_terms', array() ); 4175 if ( ! isset( $split_term_data[ $term_id ] ) ) { 4176 $split_term_data[ $term_id ] = array(); 4177 } 4178 4179 $split_term_data[ $term_id ][ $term_taxonomy->taxonomy ] = $new_term_id; 4180 4181 update_option( '_split_terms', $split_term_data ); 4182 4183 /** 4184 * Fires after a previously shared taxonomy term is split into two separate terms. 4185 * 4186 * @since 4.2.0 4187 * 4188 * @param int $term_id ID of the formerly shared term. 4189 * @param int $new_term_id ID of the new term created for the $term_taxonomy_id. 4190 * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split. 4191 * @param string $taxonomy Taxonomy for the split term. 4192 */ 4193 do_action( 'split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy ); 4194 4195 return $new_term_id; 4196 } 4197 4198 /** 4199 * Check default categories when a term gets split to see if any of them need to be updated. 4200 * 4201 * @since 4.2.0 4202 * @access private 4203 * 4204 * @param int $term_id ID of the formerly shared term. 4205 * @param int $new_term_id ID of the new term created for the $term_taxonomy_id. 4206 * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split. 4207 * @param string $taxonomy Taxonomy for the split term. 4208 */ 4209 function _wp_check_split_default_terms( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { 4210 if ( 'category' != $taxonomy ) { 4211 return; 4212 } 4213 4214 foreach ( array( 'default_category', 'default_link_category', 'default_email_category' ) as $option ) { 4215 if ( $term_id == get_option( $option, -1 ) ) { 4216 update_option( $option, $new_term_id ); 4217 } 4218 } 4219 } 4220 4221 /** 4222 * Check menu items when a term gets split to see if any of them need to be updated. 4223 * 4224 * @since 4.2.0 4225 * @access private 4226 * 4227 * @param int $term_id ID of the formerly shared term. 4228 * @param int $new_term_id ID of the new term created for the $term_taxonomy_id. 4229 * @param int $term_taxonomy_id ID for the term_taxonomy row affected by the split. 4230 * @param string $taxonomy Taxonomy for the split term. 4231 */ 4232 function _wp_check_split_terms_in_menus( $term_id, $new_term_id, $term_taxonomy_id, $taxonomy ) { 4233 global $wpdb; 4234 $post_ids = $wpdb->get_col( $wpdb->prepare( 4235 "SELECT m1.post_id 4236 FROM {$wpdb->postmeta} AS m1 4237 INNER JOIN {$wpdb->postmeta} AS m2 ON ( m2.post_id = m1.post_id ) 4238 INNER JOIN {$wpdb->postmeta} AS m3 ON ( m3.post_id = m1.post_id ) 4239 WHERE ( m1.meta_key = '_menu_item_type' AND m1.meta_value = 'taxonomy' ) 4240 AND ( m2.meta_key = '_menu_item_object' AND m2.meta_value = '%s' ) 4241 AND ( m3.meta_key = '_menu_item_object_id' AND m3.meta_value = %d )", 4242 $taxonomy, 4243 $term_id 4244 ) ); 4245 4246 if ( $post_ids ) { 4247 foreach ( $post_ids as $post_id ) { 4248 update_post_meta( $post_id, '_menu_item_object_id', $new_term_id, $term_id ); 4249 } 4250 } 4251 } 4252 4253 /** 4254 * Get data about terms that previously shared a single term_id, but have since been split. 4255 * 4256 * @since 4.2.0 4257 * 4258 * @param int $old_term_id Term ID. This is the old, pre-split term ID. 4259 * @return array Array of new term IDs, keyed by taxonomy. 4260 */ 4261 function wp_get_split_terms( $old_term_id ) { 4262 $split_terms = get_option( '_split_terms', array() ); 4263 4264 $terms = array(); 4265 if ( isset( $split_terms[ $old_term_id ] ) ) { 4266 $terms = $split_terms[ $old_term_id ]; 4267 } 4268 4269 return $terms; 4270 } 4271 4272 /** 4273 * Get the new term ID corresponding to a previously split term. 4274 * 4275 * @since 4.2.0 4276 * 4277 * @param int $old_term_id Term ID. This is the old, pre-split term ID. 4278 * @param string $taxonomy Taxonomy that the term belongs to. 4279 * @return bool|int If a previously split term is found corresponding to the old term_id and taxonomy, the new term_id 4280 * will be returned. If no previously split term is found matching the parameters, returns false. 4281 */ 4282 function wp_get_split_term( $old_term_id, $taxonomy ) { 4283 $split_terms = wp_get_split_terms( $old_term_id ); 4284 4285 $term_id = false; 4286 if ( isset( $split_terms[ $taxonomy ] ) ) { 4287 $term_id = (int) $split_terms[ $taxonomy ]; 4288 } 4289 4290 return $term_id; 4092 4291 } 4093 4292 -
trunk/tests/phpunit/tests/term.php
r31287 r31418 761 761 } 762 762 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 763 845 public function test_wp_update_term_alias_of_no_term_group() { 764 846 register_taxonomy( 'wptests_tax', 'post' );
Note: See TracChangeset
for help on using the changeset viewer.