_split_shared_term

The timeline below displays how wordpress function _split_shared_term has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.1

/**
 * Creates a new term for a term_taxonomy item that currently shares its term
 * with another term_taxonomy.
 *
 * @ignore
 * @since 4.2.0
 * @since 4.3.0 Introduced `$record` parameter. Also, `$term_id` and
 *              `$term_taxonomy_id` can now accept objects.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|object $term_id          ID of the shared term, or the shared term object.
 * @param int|object $term_taxonomy_id ID of the term_taxonomy item to receive a new term, or the term_taxonomy object
 *                                     (corresponding to a row from the term_taxonomy table).
 * @param bool       $record           Whether to record data about the split term in the options table. The recording
 *                                     process has the potential to be resource-intensive, so during batch operations
 *                                     it can be beneficial to skip inline recording and do it just once, after the
 *                                     batch is processed. Only set this to `false` if you know what you are doing.
 *                                     Default: true.
 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current
 *                      database schema), `$term_id` is returned. When the term is successfully split, the
 *                      new term_id is returned. A WP_Error is returned for miscellaneous errors.
 */
function _split_shared_term($term_id, $term_taxonomy_id, $record = true)
{
    global $wpdb;
    if (is_object($term_id)) {
        $shared_term = $term_id;
        $term_id = (int) $shared_term->term_id;
    }
    if (is_object($term_taxonomy_id)) {
        $term_taxonomy = $term_taxonomy_id;
        $term_taxonomy_id = (int) $term_taxonomy->term_taxonomy_id;
    }
    // If there are no shared term_taxonomy rows, there's nothing to do here.
    $shared_tt_count = (int) $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;
    }
    /*
     * Verify that the term_taxonomy_id passed to the function is actually associated with the term_id.
     * If there's a mismatch, it may mean that the term is already split. Return the actual term_id from the db.
     */
    $check_term_id = (int) $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    if ($check_term_id !== $term_id) {
        return $check_term_id;
    }
    // Pull up data about the currently shared slug, which we'll use to populate the new one.
    if (empty($shared_term)) {
        $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));
    // Reassign child terms to the new parent.
    if (empty($term_taxonomy)) {
        $term_taxonomy = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    }
    $children_tt_ids = $wpdb->get_col($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy));
    if (!empty($children_tt_ids)) {
        foreach ($children_tt_ids as $child_tt_id) {
            $wpdb->update($wpdb->term_taxonomy, array('parent' => $new_term_id), array('term_taxonomy_id' => $child_tt_id));
            clean_term_cache((int) $child_tt_id, '', false);
        }
    } else {
        // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
        clean_term_cache($new_term_id, $term_taxonomy->taxonomy, false);
    }
    clean_term_cache($term_id, $term_taxonomy->taxonomy, false);
    /*
     * Taxonomy cache clearing is delayed to avoid race conditions that may occur when
     * regenerating the taxonomy's hierarchy tree.
     */
    $taxonomies_to_clean = array($term_taxonomy->taxonomy);
    // Clean the cache for term taxonomies formerly shared with the current term.
    $shared_term_taxonomies = $wpdb->get_col($wpdb->prepare("SELECT taxonomy FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term_id));
    $taxonomies_to_clean = array_merge($taxonomies_to_clean, $shared_term_taxonomies);
    foreach ($taxonomies_to_clean as $taxonomy_to_clean) {
        clean_taxonomy_cache($taxonomy_to_clean);
    }
    // Keep a record of term_ids that have been split, keyed by old term_id. See wp_get_split_term().
    if ($record) {
        $split_term_data = get_option('_split_terms', array());
        if (!isset($split_term_data[$term_id])) {
            $split_term_data[$term_id] = array();
        }
        $split_term_data[$term_id][$term_taxonomy->taxonomy] = $new_term_id;
        update_option('_split_terms', $split_term_data);
    }
    // If we've just split the final shared term, set the "finished" flag.
    $shared_terms_exist = $wpdb->get_results("SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt\n\t\t LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id\n\t\t GROUP BY t.term_id\n\t\t HAVING term_tt_count > 1\n\t\t LIMIT 1");
    if (!$shared_terms_exist) {
        update_option('finished_splitting_shared_terms', true);
    }
    /**
     * Fires after a previously shared taxonomy term is split into two separate terms.
     *
     * @since 4.2.0
     *
     * @param int    $term_id          ID of the formerly shared term.
     * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
     * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
     * @param string $taxonomy         Taxonomy for the split term.
     */
    do_action('split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy);
    return $new_term_id;
}

WordPress Version: 5.6

/**
 * Create a new term for a term_taxonomy item that currently shares its term
 * with another term_taxonomy.
 *
 * @ignore
 * @since 4.2.0
 * @since 4.3.0 Introduced `$record` parameter. Also, `$term_id` and
 *              `$term_taxonomy_id` can now accept objects.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|object $term_id          ID of the shared term, or the shared term object.
 * @param int|object $term_taxonomy_id ID of the term_taxonomy item to receive a new term, or the term_taxonomy object
 *                                     (corresponding to a row from the term_taxonomy table).
 * @param bool       $record           Whether to record data about the split term in the options table. The recording
 *                                     process has the potential to be resource-intensive, so during batch operations
 *                                     it can be beneficial to skip inline recording and do it just once, after the
 *                                     batch is processed. Only set this to `false` if you know what you are doing.
 *                                     Default: true.
 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current
 *                      database schema), `$term_id` is returned. When the term is successfully split, the
 *                      new term_id is returned. A WP_Error is returned for miscellaneous errors.
 */
function _split_shared_term($term_id, $term_taxonomy_id, $record = true)
{
    global $wpdb;
    if (is_object($term_id)) {
        $shared_term = $term_id;
        $term_id = (int) $shared_term->term_id;
    }
    if (is_object($term_taxonomy_id)) {
        $term_taxonomy = $term_taxonomy_id;
        $term_taxonomy_id = (int) $term_taxonomy->term_taxonomy_id;
    }
    // If there are no shared term_taxonomy rows, there's nothing to do here.
    $shared_tt_count = (int) $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;
    }
    /*
     * Verify that the term_taxonomy_id passed to the function is actually associated with the term_id.
     * If there's a mismatch, it may mean that the term is already split. Return the actual term_id from the db.
     */
    $check_term_id = (int) $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    if ($check_term_id !== $term_id) {
        return $check_term_id;
    }
    // Pull up data about the currently shared slug, which we'll use to populate the new one.
    if (empty($shared_term)) {
        $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));
    // Reassign child terms to the new parent.
    if (empty($term_taxonomy)) {
        $term_taxonomy = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    }
    $children_tt_ids = $wpdb->get_col($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy));
    if (!empty($children_tt_ids)) {
        foreach ($children_tt_ids as $child_tt_id) {
            $wpdb->update($wpdb->term_taxonomy, array('parent' => $new_term_id), array('term_taxonomy_id' => $child_tt_id));
            clean_term_cache((int) $child_tt_id, '', false);
        }
    } else {
        // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
        clean_term_cache($new_term_id, $term_taxonomy->taxonomy, false);
    }
    clean_term_cache($term_id, $term_taxonomy->taxonomy, false);
    /*
     * Taxonomy cache clearing is delayed to avoid race conditions that may occur when
     * regenerating the taxonomy's hierarchy tree.
     */
    $taxonomies_to_clean = array($term_taxonomy->taxonomy);
    // Clean the cache for term taxonomies formerly shared with the current term.
    $shared_term_taxonomies = $wpdb->get_col($wpdb->prepare("SELECT taxonomy FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term_id));
    $taxonomies_to_clean = array_merge($taxonomies_to_clean, $shared_term_taxonomies);
    foreach ($taxonomies_to_clean as $taxonomy_to_clean) {
        clean_taxonomy_cache($taxonomy_to_clean);
    }
    // Keep a record of term_ids that have been split, keyed by old term_id. See wp_get_split_term().
    if ($record) {
        $split_term_data = get_option('_split_terms', array());
        if (!isset($split_term_data[$term_id])) {
            $split_term_data[$term_id] = array();
        }
        $split_term_data[$term_id][$term_taxonomy->taxonomy] = $new_term_id;
        update_option('_split_terms', $split_term_data);
    }
    // If we've just split the final shared term, set the "finished" flag.
    $shared_terms_exist = $wpdb->get_results("SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt\n\t\t LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id\n\t\t GROUP BY t.term_id\n\t\t HAVING term_tt_count > 1\n\t\t LIMIT 1");
    if (!$shared_terms_exist) {
        update_option('finished_splitting_shared_terms', true);
    }
    /**
     * Fires after a previously shared taxonomy term is split into two separate terms.
     *
     * @since 4.2.0
     *
     * @param int    $term_id          ID of the formerly shared term.
     * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
     * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
     * @param string $taxonomy         Taxonomy for the split term.
     */
    do_action('split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy);
    return $new_term_id;
}

WordPress Version: 5.3

/**
 * Create a new term for a term_taxonomy item that currently shares its term
 * with another term_taxonomy.
 *
 * @ignore
 * @since 4.2.0
 * @since 4.3.0 Introduced `$record` parameter. Also, `$term_id` and
 *              `$term_taxonomy_id` can now accept objects.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|object $term_id          ID of the shared term, or the shared term object.
 * @param int|object $term_taxonomy_id ID of the term_taxonomy item to receive a new term, or the term_taxonomy object
 *                                     (corresponding to a row from the term_taxonomy table).
 * @param bool       $record           Whether to record data about the split term in the options table. The recording
 *                                     process has the potential to be resource-intensive, so during batch operations
 *                                     it can be beneficial to skip inline recording and do it just once, after the
 *                                     batch is processed. Only set this to `false` if you know what you are doing.
 *                                     Default: true.
 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current
 *                      database schema), `$term_id` is returned. When the term is successfully split, the
 *                      new term_id is returned. A WP_Error is returned for miscellaneous errors.
 */
function _split_shared_term($term_id, $term_taxonomy_id, $record = true)
{
    global $wpdb;
    if (is_object($term_id)) {
        $shared_term = $term_id;
        $term_id = intval($shared_term->term_id);
    }
    if (is_object($term_taxonomy_id)) {
        $term_taxonomy = $term_taxonomy_id;
        $term_taxonomy_id = intval($term_taxonomy->term_taxonomy_id);
    }
    // If there are no shared term_taxonomy rows, there's nothing to do here.
    $shared_tt_count = (int) $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;
    }
    /*
     * Verify that the term_taxonomy_id passed to the function is actually associated with the term_id.
     * If there's a mismatch, it may mean that the term is already split. Return the actual term_id from the db.
     */
    $check_term_id = (int) $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    if ($check_term_id !== $term_id) {
        return $check_term_id;
    }
    // Pull up data about the currently shared slug, which we'll use to populate the new one.
    if (empty($shared_term)) {
        $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));
    // Reassign child terms to the new parent.
    if (empty($term_taxonomy)) {
        $term_taxonomy = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    }
    $children_tt_ids = $wpdb->get_col($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy));
    if (!empty($children_tt_ids)) {
        foreach ($children_tt_ids as $child_tt_id) {
            $wpdb->update($wpdb->term_taxonomy, array('parent' => $new_term_id), array('term_taxonomy_id' => $child_tt_id));
            clean_term_cache((int) $child_tt_id, '', false);
        }
    } else {
        // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
        clean_term_cache($new_term_id, $term_taxonomy->taxonomy, false);
    }
    clean_term_cache($term_id, $term_taxonomy->taxonomy, false);
    /*
     * Taxonomy cache clearing is delayed to avoid race conditions that may occur when
     * regenerating the taxonomy's hierarchy tree.
     */
    $taxonomies_to_clean = array($term_taxonomy->taxonomy);
    // Clean the cache for term taxonomies formerly shared with the current term.
    $shared_term_taxonomies = $wpdb->get_col($wpdb->prepare("SELECT taxonomy FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term_id));
    $taxonomies_to_clean = array_merge($taxonomies_to_clean, $shared_term_taxonomies);
    foreach ($taxonomies_to_clean as $taxonomy_to_clean) {
        clean_taxonomy_cache($taxonomy_to_clean);
    }
    // Keep a record of term_ids that have been split, keyed by old term_id. See wp_get_split_term().
    if ($record) {
        $split_term_data = get_option('_split_terms', array());
        if (!isset($split_term_data[$term_id])) {
            $split_term_data[$term_id] = array();
        }
        $split_term_data[$term_id][$term_taxonomy->taxonomy] = $new_term_id;
        update_option('_split_terms', $split_term_data);
    }
    // If we've just split the final shared term, set the "finished" flag.
    $shared_terms_exist = $wpdb->get_results("SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt\n\t\t LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id\n\t\t GROUP BY t.term_id\n\t\t HAVING term_tt_count > 1\n\t\t LIMIT 1");
    if (!$shared_terms_exist) {
        update_option('finished_splitting_shared_terms', true);
    }
    /**
     * Fires after a previously shared taxonomy term is split into two separate terms.
     *
     * @since 4.2.0
     *
     * @param int    $term_id          ID of the formerly shared term.
     * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
     * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
     * @param string $taxonomy         Taxonomy for the split term.
     */
    do_action('split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy);
    return $new_term_id;
}

WordPress Version: 4.9

/**
 * Create a new term for a term_taxonomy item that currently shares its term
 * with another term_taxonomy.
 *
 * @ignore
 * @since 4.2.0
 * @since 4.3.0 Introduced `$record` parameter. Also, `$term_id` and
 *              `$term_taxonomy_id` can now accept objects.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|object $term_id          ID of the shared term, or the shared term object.
 * @param int|object $term_taxonomy_id ID of the term_taxonomy item to receive a new term, or the term_taxonomy object
 *                                     (corresponding to a row from the term_taxonomy table).
 * @param bool       $record           Whether to record data about the split term in the options table. The recording
 *                                     process has the potential to be resource-intensive, so during batch operations
 *                                     it can be beneficial to skip inline recording and do it just once, after the
 *                                     batch is processed. Only set this to `false` if you know what you are doing.
 *                                     Default: true.
 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current
 *                      database schema), `$term_id` is returned. When the term is successfully split, the
 *                      new term_id is returned. A WP_Error is returned for miscellaneous errors.
 */
function _split_shared_term($term_id, $term_taxonomy_id, $record = true)
{
    global $wpdb;
    if (is_object($term_id)) {
        $shared_term = $term_id;
        $term_id = intval($shared_term->term_id);
    }
    if (is_object($term_taxonomy_id)) {
        $term_taxonomy = $term_taxonomy_id;
        $term_taxonomy_id = intval($term_taxonomy->term_taxonomy_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;
    }
    /*
     * Verify that the term_taxonomy_id passed to the function is actually associated with the term_id.
     * If there's a mismatch, it may mean that the term is already split. Return the actual term_id from the db.
     */
    $check_term_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    if ($check_term_id != $term_id) {
        return $check_term_id;
    }
    // Pull up data about the currently shared slug, which we'll use to populate the new one.
    if (empty($shared_term)) {
        $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));
    // Reassign child terms to the new parent.
    if (empty($term_taxonomy)) {
        $term_taxonomy = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    }
    $children_tt_ids = $wpdb->get_col($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy));
    if (!empty($children_tt_ids)) {
        foreach ($children_tt_ids as $child_tt_id) {
            $wpdb->update($wpdb->term_taxonomy, array('parent' => $new_term_id), array('term_taxonomy_id' => $child_tt_id));
            clean_term_cache((int) $child_tt_id, '', false);
        }
    } else {
        // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
        clean_term_cache($new_term_id, $term_taxonomy->taxonomy, false);
    }
    clean_term_cache($term_id, $term_taxonomy->taxonomy, false);
    /*
     * Taxonomy cache clearing is delayed to avoid race conditions that may occur when
     * regenerating the taxonomy's hierarchy tree.
     */
    $taxonomies_to_clean = array($term_taxonomy->taxonomy);
    // Clean the cache for term taxonomies formerly shared with the current term.
    $shared_term_taxonomies = $wpdb->get_col($wpdb->prepare("SELECT taxonomy FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term_id));
    $taxonomies_to_clean = array_merge($taxonomies_to_clean, $shared_term_taxonomies);
    foreach ($taxonomies_to_clean as $taxonomy_to_clean) {
        clean_taxonomy_cache($taxonomy_to_clean);
    }
    // Keep a record of term_ids that have been split, keyed by old term_id. See wp_get_split_term().
    if ($record) {
        $split_term_data = get_option('_split_terms', array());
        if (!isset($split_term_data[$term_id])) {
            $split_term_data[$term_id] = array();
        }
        $split_term_data[$term_id][$term_taxonomy->taxonomy] = $new_term_id;
        update_option('_split_terms', $split_term_data);
    }
    // If we've just split the final shared term, set the "finished" flag.
    $shared_terms_exist = $wpdb->get_results("SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt\n\t\t LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id\n\t\t GROUP BY t.term_id\n\t\t HAVING term_tt_count > 1\n\t\t LIMIT 1");
    if (!$shared_terms_exist) {
        update_option('finished_splitting_shared_terms', true);
    }
    /**
     * Fires after a previously shared taxonomy term is split into two separate terms.
     *
     * @since 4.2.0
     *
     * @param int    $term_id          ID of the formerly shared term.
     * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
     * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
     * @param string $taxonomy         Taxonomy for the split term.
     */
    do_action('split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy);
    return $new_term_id;
}

WordPress Version: 4.6

/**
 * Create a new term for a term_taxonomy item that currently shares its term
 * with another term_taxonomy.
 *
 * @ignore
 * @since 4.2.0
 * @since 4.3.0 Introduced `$record` parameter. Also, `$term_id` and
 *              `$term_taxonomy_id` can now accept objects.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|object $term_id          ID of the shared term, or the shared term object.
 * @param int|object $term_taxonomy_id ID of the term_taxonomy item to receive a new term, or the term_taxonomy object
 *                                     (corresponding to a row from the term_taxonomy table).
 * @param bool       $record           Whether to record data about the split term in the options table. The recording
 *                                     process has the potential to be resource-intensive, so during batch operations
 *                                     it can be beneficial to skip inline recording and do it just once, after the
 *                                     batch is processed. Only set this to `false` if you know what you are doing.
 *                                     Default: true.
 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current
 *                      database schema), `$term_id` is returned. When the term is successfully split, the
 *                      new term_id is returned. A WP_Error is returned for miscellaneous errors.
 */
function _split_shared_term($term_id, $term_taxonomy_id, $record = true)
{
    global $wpdb;
    if (is_object($term_id)) {
        $shared_term = $term_id;
        $term_id = intval($shared_term->term_id);
    }
    if (is_object($term_taxonomy_id)) {
        $term_taxonomy = $term_taxonomy_id;
        $term_taxonomy_id = intval($term_taxonomy->term_taxonomy_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;
    }
    /*
     * Verify that the term_taxonomy_id passed to the function is actually associated with the term_id.
     * If there's a mismatch, it may mean that the term is already split. Return the actual term_id from the db.
     */
    $check_term_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    if ($check_term_id != $term_id) {
        return $check_term_id;
    }
    // Pull up data about the currently shared slug, which we'll use to populate the new one.
    if (empty($shared_term)) {
        $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));
    // Reassign child terms to the new parent.
    if (empty($term_taxonomy)) {
        $term_taxonomy = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    }
    $children_tt_ids = $wpdb->get_col($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy));
    if (!empty($children_tt_ids)) {
        foreach ($children_tt_ids as $child_tt_id) {
            $wpdb->update($wpdb->term_taxonomy, array('parent' => $new_term_id), array('term_taxonomy_id' => $child_tt_id));
            clean_term_cache($term_id, $term_taxonomy->taxonomy);
        }
    } else {
        // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
        clean_term_cache($new_term_id, $term_taxonomy->taxonomy);
    }
    // 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));
    if ($shared_term_taxonomies) {
        foreach ($shared_term_taxonomies as $shared_term_taxonomy) {
            clean_term_cache($term_id, $shared_term_taxonomy);
        }
    }
    // Keep a record of term_ids that have been split, keyed by old term_id. See wp_get_split_term().
    if ($record) {
        $split_term_data = get_option('_split_terms', array());
        if (!isset($split_term_data[$term_id])) {
            $split_term_data[$term_id] = array();
        }
        $split_term_data[$term_id][$term_taxonomy->taxonomy] = $new_term_id;
        update_option('_split_terms', $split_term_data);
    }
    // If we've just split the final shared term, set the "finished" flag.
    $shared_terms_exist = $wpdb->get_results("SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt\n\t\t LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id\n\t\t GROUP BY t.term_id\n\t\t HAVING term_tt_count > 1\n\t\t LIMIT 1");
    if (!$shared_terms_exist) {
        update_option('finished_splitting_shared_terms', true);
    }
    /**
     * Fires after a previously shared taxonomy term is split into two separate terms.
     *
     * @since 4.2.0
     *
     * @param int    $term_id          ID of the formerly shared term.
     * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
     * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
     * @param string $taxonomy         Taxonomy for the split term.
     */
    do_action('split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy);
    return $new_term_id;
}

WordPress Version: 4.4

/**
 * Create a new term for a term_taxonomy item that currently shares its term
 * with another term_taxonomy.
 *
 * @ignore
 * @since 4.2.0
 * @since 4.3.0 Introduced `$record` parameter. Also, `$term_id` and
 *              `$term_taxonomy_id` can now accept objects.
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int|object $term_id          ID of the shared term, or the shared term object.
 * @param int|object $term_taxonomy_id ID of the term_taxonomy item to receive a new term, or the term_taxonomy object
 *                                     (corresponding to a row from the term_taxonomy table).
 * @param bool       $record           Whether to record data about the split term in the options table. The recording
 *                                     process has the potential to be resource-intensive, so during batch operations
 *                                     it can be beneficial to skip inline recording and do it just once, after the
 *                                     batch is processed. Only set this to `false` if you know what you are doing.
 *                                     Default: true.
 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current
 *                      database schema), `$term_id` is returned. When the term is successfully split, the
 *                      new term_id is returned. A WP_Error is returned for miscellaneous errors.
 */
function _split_shared_term($term_id, $term_taxonomy_id, $record = true)
{
    global $wpdb;
    if (is_object($term_id)) {
        $shared_term = $term_id;
        $term_id = intval($shared_term->term_id);
    }
    if (is_object($term_taxonomy_id)) {
        $term_taxonomy = $term_taxonomy_id;
        $term_taxonomy_id = intval($term_taxonomy->term_taxonomy_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;
    }
    /*
     * Verify that the term_taxonomy_id passed to the function is actually associated with the term_id.
     * If there's a mismatch, it may mean that the term is already split. Return the actual term_id from the db.
     */
    $check_term_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    if ($check_term_id != $term_id) {
        return $check_term_id;
    }
    // Pull up data about the currently shared slug, which we'll use to populate the new one.
    if (empty($shared_term)) {
        $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));
    // Reassign child terms to the new parent.
    if (empty($term_taxonomy)) {
        $term_taxonomy = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    }
    $children_tt_ids = $wpdb->get_col($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy));
    if (!empty($children_tt_ids)) {
        foreach ($children_tt_ids as $child_tt_id) {
            $wpdb->update($wpdb->term_taxonomy, array('parent' => $new_term_id), array('term_taxonomy_id' => $child_tt_id));
            clean_term_cache($term_id, $term_taxonomy->taxonomy);
        }
    } else {
        // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
        clean_term_cache($new_term_id, $term_taxonomy->taxonomy);
    }
    // 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));
    if ($shared_term_taxonomies) {
        foreach ($shared_term_taxonomies as $shared_term_taxonomy) {
            clean_term_cache($term_id, $shared_term_taxonomy);
        }
    }
    // Keep a record of term_ids that have been split, keyed by old term_id. See {@see wp_get_split_term()}.
    if ($record) {
        $split_term_data = get_option('_split_terms', array());
        if (!isset($split_term_data[$term_id])) {
            $split_term_data[$term_id] = array();
        }
        $split_term_data[$term_id][$term_taxonomy->taxonomy] = $new_term_id;
        update_option('_split_terms', $split_term_data);
    }
    // If we've just split the final shared term, set the "finished" flag.
    $shared_terms_exist = $wpdb->get_results("SELECT tt.term_id, t.*, count(*) as term_tt_count FROM {$wpdb->term_taxonomy} tt\n\t\t LEFT JOIN {$wpdb->terms} t ON t.term_id = tt.term_id\n\t\t GROUP BY t.term_id\n\t\t HAVING term_tt_count > 1\n\t\t LIMIT 1");
    if (!$shared_terms_exist) {
        update_option('finished_splitting_shared_terms', true);
    }
    /**
     * Fires after a previously shared taxonomy term is split into two separate terms.
     *
     * @since 4.2.0
     *
     * @param int    $term_id          ID of the formerly shared term.
     * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
     * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
     * @param string $taxonomy         Taxonomy for the split term.
     */
    do_action('split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy);
    return $new_term_id;
}

WordPress Version: 4.3

/**
 * Create a new term for a term_taxonomy item that currently shares its term
 * with another term_taxonomy.
 *
 * @ignore
 * @since 4.2.0
 * @since 4.3.0 Introduced `$record` parameter. Also, `$term_id` and
 *              `$term_taxonomy_id` can now accept objects.
 *
 * @global wpdb $wpdb
 *
 * @param int|object $term_id          ID of the shared term, or the shared term object.
 * @param int|object $term_taxonomy_id ID of the term_taxonomy item to receive a new term, or the term_taxonomy object
 *                                     (corresponding to a row from the term_taxonomy table).
 * @param bool       $record           Whether to record data about the split term in the options table. The recording
 *                                     process has the potential to be resource-intensive, so during batch operations
 *                                     it can be beneficial to skip inline recording and do it just once, after the
 *                                     batch is processed. Only set this to `false` if you know what you are doing.
 *                                     Default: true.
 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current
 *                      database schema), `$term_id` is returned. When the term is successfully split, the
 *                      new term_id is returned. A WP_Error is returned for miscellaneous errors.
 */
function _split_shared_term($term_id, $term_taxonomy_id, $record = true)
{
    global $wpdb;
    if (is_object($term_id)) {
        $shared_term = $term_id;
        $term_id = intval($shared_term->term_id);
    }
    if (is_object($term_taxonomy_id)) {
        $term_taxonomy = $term_taxonomy_id;
        $term_taxonomy_id = intval($term_taxonomy->term_taxonomy_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;
    }
    /*
     * Verify that the term_taxonomy_id passed to the function is actually associated with the term_id.
     * If there's a mismatch, it may mean that the term is already split. Return the actual term_id from the db.
     */
    $check_term_id = $wpdb->get_var($wpdb->prepare("SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    if ($check_term_id != $term_id) {
        return $check_term_id;
    }
    // Pull up data about the currently shared slug, which we'll use to populate the new one.
    if (empty($shared_term)) {
        $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));
    // Reassign child terms to the new parent.
    if (empty($term_taxonomy)) {
        $term_taxonomy = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    }
    $children_tt_ids = $wpdb->get_col($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $term_id, $term_taxonomy->taxonomy));
    if (!empty($children_tt_ids)) {
        foreach ($children_tt_ids as $child_tt_id) {
            $wpdb->update($wpdb->term_taxonomy, array('parent' => $new_term_id), array('term_taxonomy_id' => $child_tt_id));
            clean_term_cache($term_id, $term_taxonomy->taxonomy);
        }
    } else {
        // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
        clean_term_cache($new_term_id, $term_taxonomy->taxonomy);
    }
    // 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));
    if ($shared_term_taxonomies) {
        foreach ($shared_term_taxonomies as $shared_term_taxonomy) {
            clean_term_cache($term_id, $shared_term_taxonomy);
        }
    }
    // Keep a record of term_ids that have been split, keyed by old term_id. See {@see wp_get_split_term()}.
    if ($record) {
        $split_term_data = get_option('_split_terms', array());
        if (!isset($split_term_data[$term_id])) {
            $split_term_data[$term_id] = array();
        }
        $split_term_data[$term_id][$term_taxonomy->taxonomy] = $new_term_id;
        update_option('_split_terms', $split_term_data);
    }
    /**
     * Fires after a previously shared taxonomy term is split into two separate terms.
     *
     * @since 4.2.0
     *
     * @param int    $term_id          ID of the formerly shared term.
     * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
     * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
     * @param string $taxonomy         Taxonomy for the split term.
     */
    do_action('split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy);
    return $new_term_id;
}

WordPress Version: 4.2

/**
 * Create a new term for a term_taxonomy item that currently shares its term with another term_taxonomy.
 *
 * @ignore
 * @since 4.2.0
 *
 * @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.
 * @return int|WP_Error When the current term does not need to be split (or cannot be split on the current
 *                      database schema), `$term_id` is returned. When the term is successfully split, the
 *                      new term_id is returned. A WP_Error is returned for miscellaneous errors.
 */
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));
    // Reassign child terms to the new parent.
    $term_taxonomy = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $term_taxonomy_id));
    $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));
    if (!empty($children_tt_ids)) {
        foreach ($children_tt_ids as $child_tt_id) {
            $wpdb->update($wpdb->term_taxonomy, array('parent' => $new_term_id), array('term_taxonomy_id' => $child_tt_id));
            clean_term_cache($term_id, $term_taxonomy->taxonomy);
        }
    } else {
        // If the term has no children, we must force its taxonomy cache to be rebuilt separately.
        clean_term_cache($new_term_id, $term_taxonomy->taxonomy);
    }
    // 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));
    if ($shared_term_taxonomies) {
        foreach ($shared_term_taxonomies as $shared_term_taxonomy) {
            clean_term_cache($term_id, $shared_term_taxonomy);
        }
    }
    // Keep a record of term_ids that have been split, keyed by old term_id. See {@see wp_get_split_term()}.
    $split_term_data = get_option('_split_terms', array());
    if (!isset($split_term_data[$term_id])) {
        $split_term_data[$term_id] = array();
    }
    $split_term_data[$term_id][$term_taxonomy->taxonomy] = $new_term_id;
    update_option('_split_terms', $split_term_data);
    /**
     * Fires after a previously shared taxonomy term is split into two separate terms.
     *
     * @since 4.2.0
     *
     * @param int    $term_id          ID of the formerly shared term.
     * @param int    $new_term_id      ID of the new term created for the $term_taxonomy_id.
     * @param int    $term_taxonomy_id ID for the term_taxonomy row affected by the split.
     * @param string $taxonomy         Taxonomy for the split term.
     */
    do_action('split_shared_term', $term_id, $new_term_id, $term_taxonomy_id, $term_taxonomy->taxonomy);
    return $new_term_id;
}