wp_delete_term

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

WordPress Version: 5.9

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    $ids = term_exists($term, $taxonomy);
    if (!$ids) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' === $taxonomy) {
        $defaults['default'] = (int) get_option('default_category');
        if ($defaults['default'] === $term) {
            return 0;
            // Don't delete the default category.
        }
    }
    // Don't delete the default custom taxonomy term.
    $taxonomy_object = get_taxonomy($taxonomy);
    if (!empty($taxonomy_object->default_term)) {
        $defaults['default'] = (int) get_option('default_term_' . $taxonomy);
        if ($defaults['default'] === $term) {
            return 0;
        }
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent.
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        if (!isset($default)) {
            wp_remove_object_terms($object_id, $term, $taxonomy);
            continue;
        }
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 === count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * The {@see 'delete_$taxonomy'} hook is also available for targeting a specific
     * taxonomy.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param WP_Term $deleted_term Copy of the already-deleted term.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * Possible hook names include:
     *
     *  - `delete_category`
     *  - `delete_post_tag`
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param WP_Term $deleted_term Copy of the already-deleted term.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 5.8

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    $ids = term_exists($term, $taxonomy);
    if (!$ids) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' === $taxonomy) {
        $defaults['default'] = (int) get_option('default_category');
        if ($defaults['default'] === $term) {
            return 0;
            // Don't delete the default category.
        }
    }
    // Don't delete the default custom taxonomy term.
    $taxonomy_object = get_taxonomy($taxonomy);
    if (!empty($taxonomy_object->default_term)) {
        $defaults['default'] = (int) get_option('default_term_' . $taxonomy);
        if ($defaults['default'] === $term) {
            return 0;
        }
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent.
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        if (!isset($default)) {
            wp_remove_object_terms($object_id, $term, $taxonomy);
            continue;
        }
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 === count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * The {@see 'delete_$taxonomy'} hook is also available for targeting a specific
     * taxonomy.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param WP_Term $deleted_term Copy of the already-deleted term.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * Possible hook names include:
     *
     *  - `delete_category`
     *  - `delete_post_tag`
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param WP_Term $deleted_term Copy of the already-deleted term.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 5.7

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    $ids = term_exists($term, $taxonomy);
    if (!$ids) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' === $taxonomy) {
        $defaults['default'] = (int) get_option('default_category');
        if ($defaults['default'] === $term) {
            return 0;
            // Don't delete the default category.
        }
    }
    // Don't delete the default custom taxonomy term.
    $taxonomy_object = get_taxonomy($taxonomy);
    if (!empty($taxonomy_object->default_term)) {
        $defaults['default'] = (int) get_option('default_term_' . $taxonomy);
        if ($defaults['default'] === $term) {
            return 0;
        }
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent.
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        if (!isset($default)) {
            wp_remove_object_terms($object_id, $term, $taxonomy);
            continue;
        }
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 === count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * The {@see 'delete_$taxonomy'} hook is also available for targeting a specific
     * taxonomy.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param WP_Term $deleted_term Copy of the already-deleted term.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param WP_Term $deleted_term Copy of the already-deleted term.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 5.6

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    $ids = term_exists($term, $taxonomy);
    if (!$ids) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' === $taxonomy) {
        $defaults['default'] = (int) get_option('default_category');
        if ($defaults['default'] === $term) {
            return 0;
            // Don't delete the default category.
        }
    }
    // Don't delete the default custom taxonomy term.
    $taxonomy_object = get_taxonomy($taxonomy);
    if (!empty($taxonomy_object->default_term)) {
        $defaults['default'] = (int) get_option('default_term_' . $taxonomy);
        if ($defaults['default'] === $term) {
            return 0;
        }
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent.
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 === count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * The {@see 'delete_$taxonomy'} hook is also available for targeting a specific
     * taxonomy.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param WP_Term $deleted_term Copy of the already-deleted term.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param WP_Term $deleted_term Copy of the already-deleted term.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 5.5

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    $ids = term_exists($term, $taxonomy);
    if (!$ids) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' === $taxonomy) {
        $defaults['default'] = (int) get_option('default_category');
        if ($defaults['default'] === $term) {
            return 0;
            // Don't delete the default category.
        }
    }
    // Don't delete the default custom taxonomy term.
    $taxonomy_object = get_taxonomy($taxonomy);
    if (!empty($taxonomy_object->default_term)) {
        $defaults['default'] = (int) get_option('default_term_' . $taxonomy);
        if ($defaults['default'] === $term) {
            return 0;
        }
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent.
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 === count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 5.4

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    $ids = term_exists($term, $taxonomy);
    if (!$ids) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' === $taxonomy) {
        $defaults['default'] = (int) get_option('default_category');
        if ($defaults['default'] === $term) {
            return 0;
            // Don't delete the default category.
        }
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent.
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 === count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 5.3

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    $ids = term_exists($term, $taxonomy);
    if (!$ids) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' === $taxonomy) {
        $defaults['default'] = (int) get_option('default_category');
        if ($defaults['default'] === $term) {
            return 0;
            // Don't delete the default category
        }
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 === count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 5.1

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!$ids = term_exists($term, $taxonomy)) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
            // Don't delete the default category
        }
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 4.5

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args {
 *     Optional. Array of arguments to override the default term ID. Default empty array.
 *
 *     @type int  $default       The term ID to make the default term. This will only override
 *                               the terms found if there is only one term found. Any other and
 *                               the found terms are used.
 *     @type bool $force_default Optional. Whether to force the supplied term as default to be
 *                               assigned even if the object was not going to be term-less.
 *                               Default false.
 * }
 * @return bool|int|WP_Error True on success, false if term does not exist. Zero on attempted
 *                           deletion of default Category. WP_Error if the taxonomy does not exist.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!$ids = term_exists($term, $taxonomy)) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
        }
        // Don't delete the default category
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $object_ids = (array) $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ($object_ids as $object_id) {
        $terms = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object_id, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($object_ids, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term, $object_ids);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     * @since 4.5.0 Introduced the `$object_ids` argument.
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     * @param array   $object_ids   List of term object IDs.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term, $object_ids);
    return true;
}

WordPress Version: 4.4

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * Metadata associated with the term will be deleted.
 *
 * The `$args` 'default' will only override the terms found, if there is only one
 * term found. Any other and the found terms are used.
 *
 * The $args 'force_default' will force the term supplied as default to be
 * assigned even if the object was not going to be termless
 *
 * @todo Document $args as a hash notation.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args     Optional. Change 'default' term id and override found term ids.
 * @return bool|int|WP_Error Returns false if not term; true if completes delete action.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!$ids = term_exists($term, $taxonomy)) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
        }
        // Don't delete the default category
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    // Get the term before deleting it or its term relationships so we can pass to actions below.
    $deleted_term = get_term($term, $taxonomy);
    $objects = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ((array) $objects as $object) {
        $terms = wp_get_object_terms($object, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($objects, $object_type);
    }
    $term_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->termmeta} WHERE term_id = %d ", $term));
    foreach ($term_meta_ids as $mid) {
        delete_metadata_by_mid('term', $mid);
    }
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term);
    return true;
}

WordPress Version: 4.3

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * The `$args` 'default' will only override the terms found, if there is only one
 * term found. Any other and the found terms are used.
 *
 * The $args 'force_default' will force the term supplied as default to be
 * assigned even if the object was not going to be termless
 *
 * @todo Document $args as a hash notation.
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int          $term     Term ID.
 * @param string       $taxonomy Taxonomy Name.
 * @param array|string $args     Optional. Change 'default' term id and override found term ids.
 * @return bool|int|WP_Error Returns false if not term; true if completes delete action.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!$ids = term_exists($term, $taxonomy)) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
        }
        // Don't delete the default category
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    $objects = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ((array) $objects as $object) {
        $terms = wp_get_object_terms($object, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term.
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($objects, $object_type);
    }
    // Get the object before deletion so we can pass to actions below
    $deleted_term = get_term($term, $taxonomy);
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term);
    return true;
}

WordPress Version: 4.1

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * The $args 'default' will only override the terms found, if there is only one
 * term found. Any other and the found terms are used.
 *
 * The $args 'force_default' will force the term supplied as default to be
 * assigned even if the object was not going to be termless
 *
 * @since 2.3.0
 *
 * @global wpdb $wpdb WordPress database abstraction object.
 *
 * @param int $term Term ID
 * @param string $taxonomy Taxonomy Name
 * @param array|string $args Optional. Change 'default' term id and override found term ids.
 * @return bool|WP_Error Returns false if not term; true if completes delete action.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!$ids = term_exists($term, $taxonomy)) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
        }
        // Don't delete the default category
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    /**
     * Fires when deleting a term, before any modifications are made to posts or terms.
     *
     * @since 4.1.0
     *
     * @param int    $term     Term ID.
     * @param string $taxonomy Taxonomy Name.
     */
    do_action('pre_delete_term', $term, $taxonomy);
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_ids = $wpdb->get_results("SELECT term_id, term_taxonomy_id FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        $edit_tt_ids = wp_list_pluck($edit_ids, 'term_taxonomy_id');
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        // Clean the cache for all child terms.
        $edit_term_ids = wp_list_pluck($edit_ids, 'term_id');
        clean_term_cache($edit_term_ids, $taxonomy);
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    $objects = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ((array) $objects as $object) {
        $terms = wp_get_object_terms($object, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($objects, $object_type);
    }
    // Get the object before deletion so we can pass to actions below
    $deleted_term = get_term($term, $taxonomy);
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, `$taxonomy`, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. {@see WP_Error} otherwise.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term);
    return true;
}

WordPress Version: 4.0

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * The $args 'default' will only override the terms found, if there is only one
 * term found. Any other and the found terms are used.
 *
 * The $args 'force_default' will force the term supplied as default to be
 * assigned even if the object was not going to be termless
 *
 * @since 2.3.0
 *
 * @uses $wpdb
 *
 * @param int $term Term ID
 * @param string $taxonomy Taxonomy Name
 * @param array|string $args Optional. Change 'default' term id and override found term ids.
 * @return bool|WP_Error Returns false if not term; true if completes delete action.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!$ids = term_exists($term, $taxonomy)) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
        }
        // Don't delete the default category
    }
    $args = wp_parse_args($args, $defaults);
    if (isset($args['default'])) {
        $default = (int) $args['default'];
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    if (isset($args['force_default'])) {
        $force_default = $args['force_default'];
    }
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_tt_ids = $wpdb->get_col("SELECT `term_taxonomy_id` FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    $objects = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ((array) $objects as $object) {
        $terms = wp_get_object_terms($object, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($objects, $object_type);
    }
    // Get the object before deletion so we can pass to actions below
    $deleted_term = get_term($term, $taxonomy);
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, $taxonomy, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term);
    return true;
}

WordPress Version: 3.9

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * The $args 'default' will only override the terms found, if there is only one
 * term found. Any other and the found terms are used.
 *
 * The $args 'force_default' will force the term supplied as default to be
 * assigned even if the object was not going to be termless
 *
 * @since 2.3.0
 *
 * @uses $wpdb
 *
 * @param int $term Term ID
 * @param string $taxonomy Taxonomy Name
 * @param array|string $args Optional. Change 'default' term id and override found term ids.
 * @return bool|WP_Error Returns false if not term; true if completes delete action.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!$ids = term_exists($term, $taxonomy)) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
        }
        // Don't delete the default category
    }
    $args = wp_parse_args($args, $defaults);
    extract($args, EXTR_SKIP);
    if (isset($default)) {
        $default = (int) $default;
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_tt_ids = $wpdb->get_col("SELECT `term_taxonomy_id` FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        /**
         * Fires immediately before a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        /**
         * Fires immediately after a term to delete's children are reassigned a parent.
         *
         * @since 2.9.0
         *
         * @param array $edit_tt_ids An array of term taxonomy IDs for the given term.
         */
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    $objects = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ((array) $objects as $object) {
        $terms = wp_get_object_terms($object, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($objects, $object_type);
    }
    // Get the object before deletion so we can pass to actions below
    $deleted_term = get_term($term, $taxonomy);
    /**
     * Fires immediately before a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    /**
     * Fires immediately after a term taxonomy ID is deleted.
     *
     * @since 2.9.0
     *
     * @param int $tt_id Term taxonomy ID.
     */
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    /**
     * Fires after a term is deleted from the database and the cache is cleaned.
     *
     * @since 2.5.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param string  $taxonomy     Taxonomy slug.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term);
    /**
     * Fires after a term in a specific taxonomy is deleted.
     *
     * The dynamic portion of the hook name, $taxonomy, refers to the specific
     * taxonomy the term belonged to.
     *
     * @since 2.3.0
     *
     * @param int     $term         Term ID.
     * @param int     $tt_id        Term taxonomy ID.
     * @param mixed   $deleted_term Copy of the already-deleted term, in the form specified
     *                              by the parent function. WP_Error otherwise.
     */
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term);
    return true;
}

WordPress Version: 3.7

/**
 * Removes a term from the database.
 *
 * If the term is a parent of other terms, then the children will be updated to
 * that term's parent.
 *
 * The $args 'default' will only override the terms found, if there is only one
 * term found. Any other and the found terms are used.
 *
 * The $args 'force_default' will force the term supplied as default to be
 * assigned even if the object was not going to be termless
 * @package WordPress
 * @subpackage Taxonomy
 * @since 2.3.0
 *
 * @uses $wpdb
 * @uses do_action() Calls both 'delete_term' and 'delete_$taxonomy' action
 *	hooks, passing term ID, term taxonomy ID, and deleted term object. 'delete_term'
 *	also gets taxonomy as the third parameter.
 *
 * @param int $term Term ID
 * @param string $taxonomy Taxonomy Name
 * @param array|string $args Optional. Change 'default' term id and override found term ids.
 * @return bool|WP_Error Returns false if not term; true if completes delete action.
 */
function wp_delete_term($term, $taxonomy, $args = array())
{
    global $wpdb;
    $term = (int) $term;
    if (!$ids = term_exists($term, $taxonomy)) {
        return false;
    }
    if (is_wp_error($ids)) {
        return $ids;
    }
    $tt_id = $ids['term_taxonomy_id'];
    $defaults = array();
    if ('category' == $taxonomy) {
        $defaults['default'] = get_option('default_category');
        if ($defaults['default'] == $term) {
            return 0;
        }
        // Don't delete the default category
    }
    $args = wp_parse_args($args, $defaults);
    extract($args, EXTR_SKIP);
    if (isset($default)) {
        $default = (int) $default;
        if (!term_exists($default, $taxonomy)) {
            unset($default);
        }
    }
    // Update children to point to new parent
    if (is_taxonomy_hierarchical($taxonomy)) {
        $term_obj = get_term($term, $taxonomy);
        if (is_wp_error($term_obj)) {
            return $term_obj;
        }
        $parent = $term_obj->parent;
        $edit_tt_ids = $wpdb->get_col("SELECT `term_taxonomy_id` FROM {$wpdb->term_taxonomy} WHERE `parent` = " . (int) $term_obj->term_id);
        do_action('edit_term_taxonomies', $edit_tt_ids);
        $wpdb->update($wpdb->term_taxonomy, compact('parent'), array('parent' => $term_obj->term_id) + compact('taxonomy'));
        do_action('edited_term_taxonomies', $edit_tt_ids);
    }
    $objects = $wpdb->get_col($wpdb->prepare("SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $tt_id));
    foreach ((array) $objects as $object) {
        $terms = wp_get_object_terms($object, $taxonomy, array('fields' => 'ids', 'orderby' => 'none'));
        if (1 == count($terms) && isset($default)) {
            $terms = array($default);
        } else {
            $terms = array_diff($terms, array($term));
            if (isset($default) && isset($force_default) && $force_default) {
                $terms = array_merge($terms, array($default));
            }
        }
        $terms = array_map('intval', $terms);
        wp_set_object_terms($object, $terms, $taxonomy);
    }
    // Clean the relationship caches for all object types using this term
    $tax_object = get_taxonomy($taxonomy);
    foreach ($tax_object->object_type as $object_type) {
        clean_object_term_cache($objects, $object_type);
    }
    // Get the object before deletion so we can pass to actions below
    $deleted_term = get_term($term, $taxonomy);
    do_action('delete_term_taxonomy', $tt_id);
    $wpdb->delete($wpdb->term_taxonomy, array('term_taxonomy_id' => $tt_id));
    do_action('deleted_term_taxonomy', $tt_id);
    // Delete the term if no taxonomies use it.
    if (!$wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM {$wpdb->term_taxonomy} WHERE term_id = %d", $term))) {
        $wpdb->delete($wpdb->terms, array('term_id' => $term));
    }
    clean_term_cache($term, $taxonomy);
    do_action('delete_term', $term, $tt_id, $taxonomy, $deleted_term);
    do_action("delete_{$taxonomy}", $term, $tt_id, $deleted_term);
    return true;
}