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.
Built from https://develop.svn.wordpress.org/trunk@30241


git-svn-id: http://core.svn.wordpress.org/trunk@30241 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Boone Gorges 2014-11-05 02:03:23 +00:00
parent 32db3d1fe5
commit 3706590afb
2 changed files with 65 additions and 3 deletions

View File

@ -3385,6 +3385,14 @@ function wp_update_term( $term_id, $taxonomy, $args = array() ) {
return new WP_Error('duplicate_term_slug', sprintf(__('The slug “%s” is already in use by another term'), $slug));
}
$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) );
// Check whether this is a shared term that needs splitting.
$_term_id = _split_shared_term( $term_id, $tt_id );
if ( ! is_wp_error( $_term_id ) ) {
$term_id = $_term_id;
}
/**
* Fires immediately before the given terms are edited.
*
@ -3410,8 +3418,6 @@ function wp_update_term( $term_id, $taxonomy, $args = array() ) {
*/
do_action( 'edited_terms', $term_id, $taxonomy );
$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) );
/**
* Fires immediate before a term-taxonomy relationship is updated.
*
@ -4040,6 +4046,62 @@ function _update_generic_term_count( $terms, $taxonomy ) {
}
}
/**
* Create a new term for a term_taxonomy item that currently shares its term.
*
* @since 4.1.0
* @access private
*
* @param int $term_id ID of the shared term.
* @param int $term_taxonomy_id ID of the term taxonomy item to receive a new term.
* @param array $shared_tts Sibling term taxonomies, used for busting caches.
* @return int Term ID.
*/
function _split_shared_term( $term_id, $term_taxonomy_id ) {
global $wpdb;
// Don't try to split terms if database schema does not support shared slugs.
$current_db_version = get_option( 'db_version' );
if ( $current_db_version < 30133 ) {
return $term_id;
}
// If there are no shared term_taxonomy rows, there's nothing to do here.
$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 ) );
if ( ! $shared_tt_count ) {
return $term_id;
}
// Pull up data about the currently shared slug, which we'll use to populate the new one.
$shared_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.* FROM $wpdb->terms t WHERE t.term_id = %d", $term_id ) );
$new_term_data = array(
'name' => $shared_term->name,
'slug' => $shared_term->slug,
'term_group' => $shared_term->term_group,
);
if ( false === $wpdb->insert( $wpdb->terms, $new_term_data ) ) {
return new WP_Error( 'db_insert_error', __( 'Could not split shared term.' ), $wpdb->last_error );
}
$new_term_id = (int) $wpdb->insert_id;
// Update the existing term_taxonomy to point to the newly created term.
$wpdb->update( $wpdb->term_taxonomy,
array( 'term_id' => $new_term_id ),
array( 'term_taxonomy_id' => $term_taxonomy_id )
);
// Clean the cache for term taxonomies formerly shared with the current term.
$shared_term_taxonomies = $wpdb->get_row( $wpdb->prepare( "SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d", $term_id ) );
foreach ( (array) $shared_term_taxonomies as $shared_term_taxonomy ) {
clean_term_cache( $term_id, $shared_term_taxonomy );
}
return $new_term_id;
}
/**
* Generate a permalink for a taxonomy term archive.
*

View File

@ -4,7 +4,7 @@
*
* @global string $wp_version
*/
$wp_version = '4.1-alpha-30240';
$wp_version = '4.1-alpha-30241';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.