This hooks into the update action for any post. It’ll copy all terms for a given set of taxonomies from a parent to it’s children.
/**
* Update all children of a post with the same terms as itself.
*
* @param int $post_ID
* @param object $post
*/
function __update_children_with_terms( $post_ID, $post )
{
global $wpdb;
// array of taxonomies to be copied to children, if the post type supports it
$taxonomies = array( 'section' );
if ( ! is_post_type_hierarchical( $post->post_type ) )
return; // bail
// all child IDs for current post
$children = $wpdb->get_col( "SELECT ID FROM $wpdb->posts WHERE post_parent = " . ( int ) $post_ID );
// loop over each taxonomy for the current post type
foreach ( get_object_taxonomies( $post->post_type ) as $taxonomy ) {
if ( ! in_array( $taxonomy, $taxonomies ) )
continue; // bail, term copy not supported for this tax
if ( ! $terms = wp_get_object_terms( $post_ID, $taxonomy, array( 'fields' => 'ids' ) ) )
continue; // bail, no terms for this tax
// essential, otherwise wp_set_object_terms treats them as strings and creates new terms!
$terms = wp_parse_id_list( $terms );
// loop over children and append the terms
foreach ( $children as $child ) {
wp_set_object_terms( $child, $terms, $taxonomy, true );
// this will rescursively iterate down the tree but at a cost!!
// remove it if you only need parent => direct child copying
wp_update_post( array( 'ID' => ( int ) $child ) );
}
}
}
add_action( 'wp_insert_post', '__update_children_with_terms', 10, 2 );
Note the last line of the inner foreach
loop – if you only have Top Level Parent => Children
, and not Parent => Child => Grandchild
, I highly recommend removing the following line;
wp_update_post( array( 'ID' => ( int ) $child ) );
It’s a recursive situation, that will loop over children and run the same process, continuing to iterate until the whole tree has been processed.