Skip Navigation

[Resolved] Copy taxonomy terms from selected post into a new post created by Forms

This thread is resolved. Here is a description of the problem and solution.

Problem: I have a Form that allows Users to create a new Post. They can select a different post in the Form. I would like to copy all the taxonomy terms applied to the selected post and apply them to the new post.

Solution:
Use the cred_save_data API, along with wp_get_object_terms and wp_set_object_terms, to copy the terms from post A in to post B.

add_action('cred_save_data_2187', 'duplicate_post', 10, 2);
function duplicate_post($post_id, $form_data) {
    // get data of original post
    $post = get_post( $form_data['container_id'], ARRAY_A );
    // update Post Status to PENDING
    $post['post_status'] = 'pending';
    // set author as current user
    $author_id = get_current_user_id();
    $post['post_author'] = $author_id;
    // update the new post with this data
    $post['ID'] = $post_id;
    $post['post_title'] = 'Copy of ' . $post['post_title'];
    wp_update_post( $post );
    // get fields of original post
    $fields = get_post_custom( $form_data['container_id'] );
    // update the new post with these fields
    foreach ($fields as $key => $values) {
        foreach ($values as $value) {   
            add_post_meta($post_id, $key, $value, false);
        }
    }
    // update Taxonomies & Categories
    $original_post_id = $form_data['container_id'];
    $new_post_id = $post_id;
    $original_post = get_post($original_post_id);
    $taxonomies = get_object_taxonomies($original_post->post_type); // returns array of taxonomy slugs for this post type
    foreach ($taxonomies as $taxonomy) {
        $post_terms = wp_get_object_terms($original_post_id, $taxonomy, array('fields' => 'slugs'));
        wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
    }
}

Relevant Documentation:
https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data
https://developer.wordpress.org/reference/functions/wp_get_object_terms/
https://codex.wordpress.org/Function_Reference/wp_set_object_terms

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

This topic contains 6 replies, has 2 voices.

Last updated by Nashaat 3 years, 4 months ago.

Assigned support staff: Christian Cox.

Author
Posts
#953871

I am using following code to duplicate woocommerce products and it works fine!

add_action('cred_save_data_713', 'duplicate_post', 10, 2);
function duplicate_post($post_id, $form_data) {
    // get data of original post
    $post = get_post( $form_data['container_id'], ARRAY_A );
    // update Post Status to PENDING
    $post['post_status'] = 'pending';
    // update the new post with this data
    $post['ID'] = $post_id;
    $post['post_title'] = 'Copy of ' . $post['post_title'];
    wp_update_post( $post );
    // get fields of original post
    $fields = get_post_custom( $form_data['container_id'] );
    // update the new post with these fields
    foreach ($fields as $key => $values) {
        foreach ($values as $value) {   
            add_post_meta($post_id, $key, $value, false);
        }
    }
}

Is it possible to duplicate the product category as well when copying a product? all custom fields are duplicated but taxonomies and product category wont duplicate. is there a way to do this?

#954525

Sure, you can use the wp_get_object_terms API to determine all the terms associated with a post, then you can use wp_set_obect_terms to set those terms on a different post.
https://developer.wordpress.org/reference/functions/wp_get_object_terms/
https://codex.wordpress.org/Function_Reference/wp_set_object_terms

#954541

Is it possible to show me how to do this with the above mentioned code...i am still confused since i am not familiar with php coding and hooks but i promise i will learn that! this would be very helpful!

#954592

Something like this will copy all the terms from all the taxonomies of the original post and apply them to the new post:

$original_post_id = 123;
$new_post_id = 456;
$original_post = get_post($original_post_id);
$taxonomies = get_object_taxonomies($original_post->post_type); // returns array of taxonomy slugs for this post type
foreach ($taxonomies as $taxonomy) {
	$post_terms = wp_get_object_terms($original_post_id, $taxonomy, array('fields' => 'slugs'));
	wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
}
#954682

Hi Christian, i have added the code you mentioned to my code..it still not doing what needed.. am i doing this right ?

add_action('cred_save_data_2187', 'duplicate_post', 10, 2);
function duplicate_post($post_id, $form_data) {
    // get data of original post
    $post = get_post( $form_data['container_id'], ARRAY_A );
  	// update Post Status to PENDING
  	$post['post_status'] = 'pending';
  	// set author as current user
    $author_id = get_current_user_id();
    $post['post_author'] = $author_id;
    // update the new post with this data
    $post['ID'] = $post_id;
    $post['post_title'] = 'Copy of ' . $post['post_title'];
    wp_update_post( $post );
    // get fields of original post
    $fields = get_post_custom( $form_data['container_id'] );
    // update the new post with these fields
    foreach ($fields as $key => $values) {
        foreach ($values as $value) {   
            add_post_meta($post_id, $key, $value, false);
        }
    }
  	// update Taxonomies & Categories
  	$original_post_id = 123;
	$new_post_id = 456;
	$original_post = get_post($original_post_id);
	$taxonomies = get_object_taxonomies($original_post->post_type); // returns array of taxonomy slugs for this post type
	foreach ($taxonomies as $taxonomy) {
    $post_terms = wp_get_object_terms($original_post_id, $taxonomy, array('fields' => 'slugs'));
    wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
	}
}
#954722

The 123 and 456 in the code I provided were just examples using hard-coded post IDs. You should replace those hard-coded numbers with variables that represent the correct original post ID and new post ID. In a cred_save_data callback, the $post_id variable usually represents the new post ID unless you modify it. I'm not exactly sure how you're determining the original post ID, but it looks like it might be $form_data['container_id']. So you would modify lines 23 and 24 in your code snippet to be:

$original_post_id = $form_data['container_id'];
$new_post_id = $post_id;
#954729

AWESOME CHRIS! I am really impressed of your understanding for the issue and the way you provided the solution. Thanks a lot

this is my final code

add_action('cred_save_data_2187', 'duplicate_post', 10, 2);
function duplicate_post($post_id, $form_data) {
    // get data of original post
    $post = get_post( $form_data['container_id'], ARRAY_A );
    // update Post Status to PENDING
    $post['post_status'] = 'pending';
    // set author as current user
    $author_id = get_current_user_id();
    $post['post_author'] = $author_id;
    // update the new post with this data
    $post['ID'] = $post_id;
    $post['post_title'] = 'Copy of ' . $post['post_title'];
    wp_update_post( $post );
    // get fields of original post
    $fields = get_post_custom( $form_data['container_id'] );
    // update the new post with these fields
    foreach ($fields as $key => $values) {
        foreach ($values as $value) {   
            add_post_meta($post_id, $key, $value, false);
        }
    }
  	// update Taxonomies & Categories
  	$original_post_id = $form_data['container_id'];
	$new_post_id = $post_id;
	$original_post = get_post($original_post_id);
	$taxonomies = get_object_taxonomies($original_post->post_type); // returns array of taxonomy slugs for this post type
	foreach ($taxonomies as $taxonomy) {
        $post_terms = wp_get_object_terms($original_post_id, $taxonomy, array('fields' => 'slugs'));
        wp_set_object_terms($new_post_id, $post_terms, $taxonomy, false);
	}
}