After WordPress has updated a posts’ taxonomy terms it triggers the action:
set_object_terms
(see source) which passes 6 variables:
- Object ID
- Terms that were assigned to the post (or added depending on 5) (could be their slug or term ID).
- Taxonomy-term IDs of above (not term IDs)
- The taxonomy
- Append. If true – terms in 2 are added to existing terms. If false (default) terms replace the existing terms.
- The post’s terms before updating (as taxonomy-term IDs)
Problem 1
Unfortunately there is no way of knowing if that object refers to post, or something (like a user). That might be a way hooking onto set_object_terms
only when you can be sure that when its next fired, it refers to a post.
Problem 2
The IDs are passed are taxonomy-term IDs, not term-IDs – and most WordPress functions use the term ID. So you’ll probably need to get the term ID (and taxonomy) from the taxonomy term ID to do anything useful. A potential work around is, since we know the taxonomy, list all the terms and do a simple foreach
loop and filter them. Better suggestions are welcome
The following is untested.
add_action('set_object_terms','wpse61678_terms_changed',10,6);
function wpse61678_terms_changed($object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids){
//Note problem 1 - we might not necessarily know what $object_id refers to.
//Added terms are specified terms, that did not already exist
$added_tt_ids = array_diff($tt_ids, $old_tt_ids);
if( $append ){
//If appending terms - nothing was removed
$removed_tt_ids = array();
}else{
//Removed terms will be old terms, that were not specified in $tt_ids
$removed_tt_ids = array_diff($old_tt_ids, $tt_ids);
}
/*Note problem 2, we would preferably like the term objects / IDs,
Currently we have the taxonomy term IDs*/
//Get all terms
$all_terms = get_terms( $taxonomy, array('hide_empty'=>0));
$removed_terms =array()
$added_terms =array();
foreach( $all_terms as $term ){
$tt_id = (int) $term->term_taxonomy_id;
if( in_array( $tt_id, $removed_tt_ids) ){
$removed_terms[] = $term;
}elseif( in_array( $tt_id, $added_tt_ids) ){
$added_terms[] = $term;
}
}
//$added_terms contains added term objects
//$removed_terms contains removed term objects
}