I need to take the post meta from a post, and create a custom post type post. I'm using the code below but think it's creating an infinite loop.

When wp_insert_post fires I have create_cptpost function execute which gets the PID of the post created $post_id gets a custom field ac_1 then I need to create a new post in the cpt post type and update the post meta. Is there another way to do this? I'm basically trying to copy the first normal post content to a new custom post type post.

function create_mycpt( $post_id ) {

$post = get_post($post_id, ARRAY_A);

    if ( wp_is_post_revision( $post_id ) )

$ac1 = get_field('ac_1',$post_id);

$my_post = array(
  'post_title'    => 'The title',
  'post_type' => 'mycpt'

$pid = wp_insert_post( $my_post );

update_post_meta($pid, 'ac_1', $ac1);

add_action( 'wp_insert_post', 'create_mycpt' );

2 Answers 2


Yeah, that would be an infinite loop.

Why not have your function check to make sure that the post is something you'd actually want to insert a new cpt post for, and return if not. You're already checking for revisions. You could easily check for your own type too.

  • would this filter be a better method to use since I can work with the post data before it's inserted? codex.wordpress.org/Plugin_API/Filter_Reference/…
    – Anagio
    Oct 28, 2013 at 18:30
  • You already have the post data, you're calling get_post() specifically to get it there in your code.
    – Otto
    Oct 28, 2013 at 18:32
  • I need all posts to be copied, i'm not sure how then to write another conditional that wouldn't create an infinite loop
    – Anagio
    Oct 28, 2013 at 18:34
  • Add an entry in the postmeta table that says it's been copied to the cpt and check against that Oct 28, 2013 at 18:36

There's a really easy way to avoid creating an infinite loop like this - remove your action before it would be run again, and then re-add it afterwards.

For example:

function create_mycpt( $post_id ) {

  // ... your earlier code here

  // directly before calling wp_insert_post, remove your action
  remove_action( 'wp_insert_post', 'create_mycpt');

  // run wp_insert_post as normal
  $pid = wp_insert_post( $my_post );

  // directly afterwards, add your action again in case there's a next time
  add_action( 'wp_insert_post, 'create_mycpt');

  // ... the rest of your code here


add_action( 'wp_insert_post', 'create_mycpt' );

This will ensure that when you call the wp_insert_post() function, it doesn't know about your hook, so no infinite loop will result. You could probably get away with not even adding it again, since it is unlikely there'll be a second post being inserted on the same request. For consistency's sake, however, we might as well add it again, because it could happen!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.