Make WordPress Core


Ignore:
Timestamp:
11/05/2014 02:02:48 AM (11 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/src/wp-includes/taxonomy.php

    r30240 r30241  
    33863386    }
    33873387
     3388    $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) );
     3389
     3390    // Check whether this is a shared term that needs splitting.
     3391    $_term_id = _split_shared_term( $term_id, $tt_id );
     3392    if ( ! is_wp_error( $_term_id ) ) {
     3393        $term_id = $_term_id;
     3394    }
     3395
    33883396    /**
    33893397     * Fires immediately before the given terms are edited.
     
    34103418     */
    34113419    do_action( 'edited_terms', $term_id, $taxonomy );
    3412 
    3413     $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) );
    34143420
    34153421    /**
     
    40394045        do_action( 'edited_term_taxonomy', $term, $taxonomy );
    40404046    }
     4047}
     4048
     4049/**
     4050 * Create a new term for a term_taxonomy item that currently shares its term.
     4051 *
     4052 * @since 4.1.0
     4053 * @access private
     4054 *
     4055 * @param int   $term_id          ID of the shared term.
     4056 * @param int   $term_taxonomy_id ID of the term taxonomy item to receive a new term.
     4057 * @param array $shared_tts       Sibling term taxonomies, used for busting caches.
     4058 * @return int  Term ID.
     4059 */
     4060function _split_shared_term( $term_id, $term_taxonomy_id ) {
     4061    global $wpdb;
     4062
     4063    // Don't try to split terms if database schema does not support shared slugs.
     4064    $current_db_version = get_option( 'db_version' );
     4065    if ( $current_db_version < 30133 ) {
     4066        return $term_id;
     4067    }
     4068
     4069    // If there are no shared term_taxonomy rows, there's nothing to do here.
     4070    $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 ) );
     4071    if ( ! $shared_tt_count ) {
     4072        return $term_id;
     4073    }
     4074
     4075    // Pull up data about the currently shared slug, which we'll use to populate the new one.
     4076    $shared_term = $wpdb->get_row( $wpdb->prepare( "SELECT t.* FROM $wpdb->terms t WHERE t.term_id = %d", $term_id ) );
     4077
     4078    $new_term_data = array(
     4079        'name' => $shared_term->name,
     4080        'slug' => $shared_term->slug,
     4081        'term_group' => $shared_term->term_group,
     4082    );
     4083
     4084    if ( false === $wpdb->insert( $wpdb->terms, $new_term_data ) ) {
     4085        return new WP_Error( 'db_insert_error', __( 'Could not split shared term.' ), $wpdb->last_error );
     4086    }
     4087
     4088    $new_term_id = (int) $wpdb->insert_id;
     4089
     4090    // Update the existing term_taxonomy to point to the newly created term.
     4091    $wpdb->update( $wpdb->term_taxonomy,
     4092        array( 'term_id' => $new_term_id ),
     4093        array( 'term_taxonomy_id' => $term_taxonomy_id )
     4094    );
     4095
     4096    // Clean the cache for term taxonomies formerly shared with the current term.
     4097    $shared_term_taxonomies = $wpdb->get_row( $wpdb->prepare( "SELECT taxonomy FROM $wpdb->term_taxonomy WHERE term_id = %d", $term_id ) );
     4098    foreach ( (array) $shared_term_taxonomies as $shared_term_taxonomy ) {
     4099        clean_term_cache( $term_id, $shared_term_taxonomy );
     4100    }
     4101
     4102    return $new_term_id;
    40414103}
    40424104
Note: See TracChangeset for help on using the changeset viewer.