WordPress Version: 6.1
/**
* Creates term and taxonomy relationships.
*
* Relates an object (post, link, etc.) to a term and taxonomy type. Creates the
* term and taxonomy relationship if it doesn't already exist. Creates a term if
* it doesn't exist (using the slug).
*
* A relationship means that the term is grouped in or belongs to the taxonomy.
* A term has no meaning until it is given context by defining which taxonomy it
* exists under.
*
* @since 2.3.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param int $object_id The object to relate to.
* @param string|int|array $terms A single term slug, single term ID, or array of either term slugs or IDs.
* Will replace all existing related terms in this taxonomy. Passing an
* empty value will remove all related terms.
* @param string $taxonomy The context in which to relate the term to the object.
* @param bool $append Optional. If false will delete difference of terms. Default false.
* @return array|WP_Error Term taxonomy IDs of the affected terms or WP_Error on failure.
*/
function wp_set_object_terms($object_id, $terms, $taxonomy, $append = false)
{
global $wpdb;
$object_id = (int) $object_id;
if (!taxonomy_exists($taxonomy)) {
return new WP_Error('invalid_taxonomy', __('Invalid taxonomy.'));
}
if (!is_array($terms)) {
$terms = array($terms);
}
if (!$append) {
$old_tt_ids = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'tt_ids', 'orderby' => 'none', 'update_term_meta_cache' => false));
} else {
$old_tt_ids = array();
}
$tt_ids = array();
$term_ids = array();
$new_tt_ids = array();
foreach ((array) $terms as $term) {
if ('' === trim($term)) {
continue;
}
$term_info = term_exists($term, $taxonomy);
if (!$term_info) {
// Skip if a non-existent term ID is passed.
if (is_int($term)) {
continue;
}
$term_info = wp_insert_term($term, $taxonomy);
}
if (is_wp_error($term_info)) {
return $term_info;
}
$term_ids[] = $term_info['term_id'];
$tt_id = $term_info['term_taxonomy_id'];
$tt_ids[] = $tt_id;
if ($wpdb->get_var($wpdb->prepare("SELECT term_taxonomy_id FROM {$wpdb->term_relationships} WHERE object_id = %d AND term_taxonomy_id = %d", $object_id, $tt_id))) {
continue;
}
/**
* Fires immediately before an object-term relationship is added.
*
* @since 2.9.0
* @since 4.7.0 Added the `$taxonomy` parameter.
*
* @param int $object_id Object ID.
* @param int $tt_id Term taxonomy ID.
* @param string $taxonomy Taxonomy slug.
*/
do_action('add_term_relationship', $object_id, $tt_id, $taxonomy);
$wpdb->insert($wpdb->term_relationships, array('object_id' => $object_id, 'term_taxonomy_id' => $tt_id));
/**
* Fires immediately after an object-term relationship is added.
*
* @since 2.9.0
* @since 4.7.0 Added the `$taxonomy` parameter.
*
* @param int $object_id Object ID.
* @param int $tt_id Term taxonomy ID.
* @param string $taxonomy Taxonomy slug.
*/
do_action('added_term_relationship', $object_id, $tt_id, $taxonomy);
$new_tt_ids[] = $tt_id;
}
if ($new_tt_ids) {
wp_update_term_count($new_tt_ids, $taxonomy);
}
if (!$append) {
$delete_tt_ids = array_diff($old_tt_ids, $tt_ids);
if ($delete_tt_ids) {
$in_delete_tt_ids = "'" . implode("', '", $delete_tt_ids) . "'";
$delete_term_ids = $wpdb->get_col($wpdb->prepare("SELECT tt.term_id FROM {$wpdb->term_taxonomy} AS tt WHERE tt.taxonomy = %s AND tt.term_taxonomy_id IN ({$in_delete_tt_ids})", $taxonomy));
$delete_term_ids = array_map('intval', $delete_term_ids);
$remove = wp_remove_object_terms($object_id, $delete_term_ids, $taxonomy);
if (is_wp_error($remove)) {
return $remove;
}
}
}
$t = get_taxonomy($taxonomy);
if (!$append && isset($t->sort) && $t->sort) {
$values = array();
$term_order = 0;
$final_tt_ids = wp_get_object_terms($object_id, $taxonomy, array('fields' => 'tt_ids', 'update_term_meta_cache' => false));
foreach ($tt_ids as $tt_id) {
if (in_array((int) $tt_id, $final_tt_ids, true)) {
$values[] = $wpdb->prepare('(%d, %d, %d)', $object_id, $tt_id, ++$term_order);
}
}
if ($values) {
if (false === $wpdb->query("INSERT INTO {$wpdb->term_relationships} (object_id, term_taxonomy_id, term_order) VALUES " . implode(',', $values) . ' ON DUPLICATE KEY UPDATE term_order = VALUES(term_order)')) {
return new WP_Error('db_insert_error', __('Could not insert term relationship into the database.'), $wpdb->last_error);
}
}
}
wp_cache_delete($object_id, $taxonomy . '_relationships');
wp_cache_delete('last_changed', 'terms');
/**
* Fires after an object's terms have been set.
*
* @since 2.8.0
*
* @param int $object_id Object ID.
* @param array $terms An array of object term IDs or slugs.
* @param array $tt_ids An array of term taxonomy IDs.
* @param string $taxonomy Taxonomy slug.
* @param bool $append Whether to append new terms to the old terms.
* @param array $old_tt_ids Old array of term taxonomy IDs.
*/
do_action('set_object_terms', $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids);
return $tt_ids;
}