Use the following code with care, it makes direct queries of the relationship tables because of some omissions in the official API.
If cloning a post which has RFGs or child posts in a one-to-many relationship, the child posts/RFGs will be duplicated and then assigned to the newly cloned parent post. If a child post is cloned, the newly cloned post will be assigned to the same existing parent. No action is taken with many-to-many relationships as everyone’s requirements may differ.
/** * Handle related posts (incl. RFGs) when duplicating post with Yoast Duplicate Post plugin * * @param int $new_post_id The newly created post's ID. * @param WP_Post $post The original post's object. * * CASES * * 1. When cloning a post with RFGs, duplicate the RFGs and assign to the cloned post * 2. When cloning a parent post, duplicate the child posts and assign to the cloned post * 3. When cloning a child post, assign to the same parent as the original post * 4. No action with M2M relationships, no clear use case */ add_action( 'dp_duplicate_post', 'ts_clone_posts', 10, 3 ); function ts_clone_posts( $new_post_id, $post, $status ) { /** * First, what relationships—if any—is the cloned post type involved in? * (No API function available, query DB directly) */ global $wpdb; $query = $wpdb->prepare( " SELECT set_id FROM {$wpdb->prefix}toolset_type_sets WHERE type LIKE '%s' ", $post->post_type ); $set_ids_array = $wpdb->get_results( $query, ARRAY_A ); // If not part of any relationships then quit if ( !( isset( $set_ids_array ) && is_array( $set_ids_array ) ) ) return; /** * CASES 1 and 2 * Where the cloned post is a parent (O2M) or has RFGs * Can't just use toolset_get_related_post_types because it doesn't include RFGs, so direct query again */ $set_ids = array_column( $set_ids_array, 'set_id' ); $set_ids_list = implode(",", $set_ids); $relationships = $wpdb->get_results( " SELECT slug FROM {$wpdb->prefix}toolset_relationships WHERE parent_types IN ({$set_ids_list}) ", ARRAY_A ); if ( isset( $relationships ) && is_array( $relationships ) ) { $relationship_slugs = array_column( $relationships, 'slug' ); // This is an array of the relationships where $post->post_type is a parent foreach ($relationship_slugs as $relationship_slug) { $relationship_definition = toolset_get_relationship( $relationship_slug ); $child_type = $relationship_definition['roles']['child']['types'][0]; // Ignore is this is a 'parent' in a M2M relationship if ( isset( $relationship_definition ) && is_array( $relationship_definition ) && $relationship_definition['cardinality']['type'] != 'many-to-many' ) { $children = toolset_get_related_posts( $post, $relationship_slug, array( 'query_by_role' => 'parent', 'role_to_return' => 'child', 'return' => 'post_object' ) ); // Update on the fly duplicate post plugin option for allowed post types to be sure we can duplicate the children add_filter( 'option_duplicate_post_types_enabled', static function( $values ) use ( $child_type ){ if ( is_array( $values ) ){ $values[] = $child_type; } return $values; } ); // Unhook our code first to avoid recursion (optional) remove_action( 'dp_duplicate_post', 'ts_clone_posts' ); // Duplicate the child posts (using the Yoast Duplicate Plugin API) foreach ($children as $key => $child) { $new_child_id = duplicate_post_create_duplicate( $child ); if ( isset( $new_child_id ) ) { toolset_connect_posts( $relationship_slug, $new_post_id, $new_child_id ); } } // add back our hook callback add_action( 'dp_duplicate_post', 'ts_clone_posts', 10, 3 ); } } } /** * CASE 3: Where the cloned post is a child post */ $parent_types = toolset_get_related_post_types( 'parent', $post->post_type ); if ( isset( $parent_types ) && is_array( $parent_types ) ){ foreach ($parent_types as $parent_type => $relationship) { // But are these relationships O2M relationships? $relationship_definition = toolset_get_relationship( $relationship[0] ); if ( isset( $relationship_definition ) && is_array( $relationship_definition ) && $relationship_definition['cardinality']['type'] == 'one-to-many' ) { // In this relationship this post type is a child, and can have only one parent $parent_id = toolset_get_related_post( $post, $relationship[0], 'parent' ); if ( isset( $parent_id ) && $parent_id != 0 ){ // Update the cloned post with the same parent toolset_connect_posts( $relationship[0], $parent_id, $new_post_id ); } } } } }
Let us know if this snippet is not working for you:
This snippet doesn’t work