For parameter $terms
, integers are interpreted as tag IDs. Some functions may return term_ids as strings which will be interpreted as slugs consisting of numeric characters.
For Return:
- (array) An array of the terms ( as term_taxonomy_ids ! ) affected if successful
- (array) An empty array if the $terms argument was NULL or empty – successmessage for the removing of the term
- (WP_Error) The WordPress Error object on invalid taxonomy (‘invalid_taxonomy’).
- (string) The first offending term if a term given in the $terms parameter is named incorrectly. (Invalid term ids are accepted and inserted).
This function does not check if there is a relationship between the object (=post type) and the taxonomy (like post_tag, category or custom taxonomy). Because of that, any existing term will be paired with the object, whether or not there is a connection between the object and the taxonomy (of this particular term)!! ( Further information in german)
Perhaps the wp_set_post_terms() is a more useful function, since it checks the values, converting taxonomies separated by commas and validating hierarchical terms in integers.
It may be confusing but the returned array consists of term_taxonomy_ids instead of term_ids.
Source
File: wp-includes/taxonomy.php
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 " . join( ',', $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 terms.
* @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;
}