logo
Ask your WordPress questions! Pay money and get answers fast! (more info)

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.

$50
Create 'duplicate my posts' functionality

I have a competition entry site that stores users' entries as a custom type post with a custom meta_key (entryyear) storing the year (2012). I would like to set up a function that would (a) get all the current user's posts (of specific post type - "contestentry"), and (b) clone/dup all these posts, but change that (entryyear) meta_key's value to 2013, and set the post status to published. I would need to be able to create a link on a page for a logged-in user that would call the function.

I had thought of starting from the code of a plugin like Duplicate Posts and tweaking to my purposes. Anyone interested in whipping this up?

Thanks!!

This question has been answered.

Adam Bundy | 01/28/13 at 6:07pm Edit
Tutorial: How to assign prize money

Previous versions of this question: 01/29/13 at 12:19am

(21) Responses

See a threaded view of answers?

Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

  • avatar
    Last edited:
    01/29/13
    12:11am
    Kiet Luong says:

    Hi, Let me help you do this.
    skype: kioluong

    Regards !

  • avatar
    Last edited:
    01/29/13
    2:22am
    Arnav Joy says:

    so you want that when ever user logged in , show lists of posts that belongs to that user with a link which when clicked change post status to publish and meta key to year 2013?

    I have one question , why you want to duplicate post ? you can also change the post status to publish , please clear this.

    Previous versions of this answer: 01/29/13 at 2:22am

  • avatar
    Last edited:
    01/29/13
    4:37am
    Naveen Chand says:

    Hi Adam,

    Here is the important code that extracts posts of the current user from the custom post type and then duplicates it and then adds a new metakey to the newly created post. Here is it:


    if ( is_user_logged_in() ):

    global $wpdb, $current_user;
    get_currentuserinfo();
    $user_contestentries = $wpdb->get_results(
    "
    SELECT *
    FROM $wpdb->posts
    WHERE post_type = 'contestentry'
    AND post_author = $current_user->ID;
    "
    );

    foreach ( $user_contestentries as $user_contestentry )
    {
    $new_post_title = $user_contestentry->post_title;
    $new_post_content = $user_contestentry->post_content;
    $new_post_type = $user_contestentry->post_type;
    $new_post_author = $user_contestentry->post_author;

    //here is where we create our new post - a duplicate of the above
    // Create post object
    $new_post = array(
    'post_title' => $new_post_title,
    'post_content' => $new_post_content',
    'post_status' => 'publish',
    'post_type' => $new_post_type,
    'post_author' => $new_post_author

    $new_post_id = wp_insert_post( $new_post, $wp_error );

    add_post_meta($new_post_id, 'entryyear', '2013', true);

    );

    }

    else :

    echo "not logged in";

    endif;


    I have to create a link that user clicks. I will be doing that and updating this code shortly. You can wait until then and meanwhile you can study this code. You would need to enter this in a template file - preferably in a new page template and assign that template to a page which users can access. Let me get back to you with the completed code.

  • avatar
    Last edited:
    01/29/13
    12:18am
    Adam Bundy says:

    @Kiet, do you need any additional info? I think the necessary steps are outlined in the original question. Let me know if you have any questions.

  • avatar
    Last edited:
    01/29/13
    12:23am
    Kiet Luong says:

    yes I need some more things such as site..., did you use skype or gmail ? can we discuss via chatting app ?
    Regards !

  • avatar
    Last edited:
    01/29/13
    12:29am
    Adam Bundy says:

    @Kiet, I'd rather not give access to the site. I would prefer to have a generic function created that does the outlined tasks.

  • avatar
    Last edited:
    01/29/13
    12:36am
    Kiet Luong says:

    yes I understand, basic logged-in user can call that function to clone/dup their posts with changed meta value.

  • avatar
    Last edited:
    01/29/13
    5:13am
    Arnav Joy says:

    create a page and select "Create Duplicate Post" as its post template then use following code:-

    <?php 
    /*
    Template Name: Create Duplicate Post
    */

    if ( is_user_logged_in() && $_POST['submit'] ) {
    global $current_user;
    get_currentuserinfo();
    $args=array(
    'author' => $current_user->ID,
    'post_type' => 'contestentry',
    'post_status' => 'draft',
    'posts_per_page' => -1,
    'caller_get_posts'=> 1
    );
    $my_query = null;
    $my_query = new WP_Query($args);
    if( $my_query->have_posts() ) {

    while ($my_query->have_posts()) : $my_query->the_post(); ?>
    <?php
    $already_done = get_post_meta( get_the_ID(),'already_done',true );
    if( $already_done != 1 ) {
    $new_post = array(
    'menu_order' => $post->menu_order,
    'comment_status' => $post->comment_status,
    'ping_status' => $post->ping_status,
    'post_author' => $current_user->ID,
    'post_content' => $post->post_content,
    'post_excerpt' => $post->post_excerpt ,
    'post_mime_type' => $post->post_mime_type,
    'post_parent' => $post->post_parent ,
    'post_password' => $post->post_password,
    'post_status' => 'publish',
    'post_title' => $post->post_title.time(),
    'post_type' => $post->post_type,
    );
    $new_post_id = wp_insert_post($new_post);

    $post_meta_keys = get_post_custom_keys($post->ID);

    if( !empty( $post_meta_keys ) ){
    foreach ($post_meta_keys as $meta_key) {
    $meta_values = get_post_custom_values($meta_key, $post->ID);
    foreach ($meta_values as $meta_value) {
    $meta_value = maybe_unserialize($meta_value);
    if( $meta_key == 'entryyear' )
    add_post_meta( $new_post_id, $meta_key, 2013 );
    else
    add_post_meta( $new_post_id, $meta_key, $meta_value );
    }
    }
    }
    update_post_meta( $new_post_id, 'already_done', 1 );
    }

    endwhile;
    }
    wp_reset_query();
    }

    get_header();

    ?>
    <div>
    <?php
    if ( is_user_logged_in() ) {
    global $current_user;
    get_currentuserinfo();
    $args=array(
    'author' => $current_user->ID,
    'post_type' => 'contestentry',
    'post_status' => 'draft',
    'posts_per_page' => -1,
    'caller_get_posts'=> 1
    );
    $my_query = null;
    $my_query = new WP_Query($args);
    if( $my_query->have_posts() ) {
    echo 'Your Posts';
    while ($my_query->have_posts()) : $my_query->the_post(); ?>

    <p><?php the_title(); ?></p>
    <?php
    endwhile;
    }
    wp_reset_query();
    ?>
    <form action="" method="post">
    <input type="submit" name="submit" value="Create Post" />
    </form>
    <?php
    }
    else
    echo 'Please login to see this page.';
    ?>
    </div>
    <?php get_footer(); ?>

  • avatar
    Last edited:
    01/29/13
    5:15am
    Naveen Chand says:

    Hi Adam,

    Here is the revised code. What it does is this:

    1. First it checks if user is logged in or not.
    2. If user is logged in, it gives him a link to the same page but with a GET variable attached to the link.
    3. If the user clicks on the link, it checks if the GET variable has action=duplicate and then begins the process.
    4. The process begins by checking if the user has already duplicated in the past. If so it will not continue ahead.
    5. If it is the very first time the user is carrying out this action, then the code runs to pull the data, duplicate them, assign the custom field and at the end .. creates a user meta to declare and store that duplicate action is done.

    Here is the code that you MUST insert inside the loop - as I suggested earlier, use this inside the new page template!


    if ( is_user_logged_in() ):
    echo "<a href=" .get_page_link() ."?action=duplicate>Click here to duplicate previous posts</a>";

    if($_GET["action"]='duplicate') {

    global $wpdb, $current_user;
    get_currentuserinfo();
    $check_if_done = get_user_meta($current_user->ID, 'duplicate_action', true);

    if (empty($check_if_done)) {

    $user_contestentries = $wpdb->get_results(
    "
    SELECT *
    FROM $wpdb->posts
    WHERE post_type = 'contestentry'
    AND post_author = $current_user->ID;
    "
    );

    foreach ( $user_contestentries as $user_contestentry )
    {
    $new_post_title = $user_contestentry->post_title;
    $new_post_content = $user_contestentry->post_content;
    $new_post_type = $user_contestentry->post_type;
    $new_post_author = $user_contestentry->post_author;

    //here is where we create our new post - a duplicate of the above
    // Create post object
    $new_post = array(
    'post_title' => $new_post_title,
    'post_content' => $new_post_content',
    'post_status' => 'publish',
    'post_type' => $new_post_type,
    'post_author' => $new_post_author

    $new_post_id = wp_insert_post( $new_post, $wp_error );

    add_post_meta($new_post_id, 'entryyear', '2013', true);

    );

    }
    add_user_meta( $new_post_author, 'duplicate_action', 'done', true); //to keep a record that user has already duplicated

    } //end of if empty check_if_done

    else { echo "You have already duplicated the posts once"; }

    } //end of get if

    else :

    echo "not logged in";

    endif;

  • avatar
    Last edited:
    01/29/13
    1:52pm
    Adam Bundy says:

    @Naveen, looks great! You have understood perfectly what I was looking for - the added user_meta field was even a bonus that I was going to add later! I will test this, but would it be possible to wrap this in a named function declaration, like nc_duplicate_userposts(); so that I could put this in my functions.php and call it anywhere on a template? Thank you!

  • avatar
    Last edited:
    01/29/13
    4:14pm
    Adam Bundy says:

    @Naveen, I tried to use the above code, but it appears there might be some syntax or formatting errors. Could you please make a couple modifications for me and try this in a sandbox environment to make sure formatting is correct?

    1. could the check_if_done occur above the insert for the link so that if it has been done, the link doesn't appear?

    2. I have a few custom taxonomies and custom post_meta keys that aren't being copied over. Is there a way to get those for the existing posts and set them for the new posts comprehensively, or does that have to be done one-by-one?

    Thanks Naveen! If I can get these couple things completed I'll be happy to call it good and award the cash.

  • avatar
    Last edited:
    01/29/13
    5:07pm
    Naveen Chand says:

    Sure Adam, I'll try this in my demo site and get back to you. I'll wrap it in a function and test it. I think it is possible to get the custom taxonomies and custom post_meta. Firstly, let me check for syntax errors. I've coded that in a hurry.

  • avatar
    Last edited:
    01/29/13
    5:11pm
    Adam Bundy says:

    @Naveen, thanks! I look forward to it. I had hoped it was possible to get all the post_meta as an array and assign it to the dup posts all at once rather than having to assign each manually.

  • avatar
    Last edited:
    01/29/13
    6:16pm
    Naveen Chand says:

    @Adam,

    I have rectified the syntax errors. The code is working without any errors. I have tried in a sandbox and it duplicated successfully a post in a custom post-type after I clicked the link. Here is the modified code:


    <?php
    if ( is_user_logged_in() ) {

    echo "<a href='" .get_page_link() ."?action=duplicate'>Click here to duplicate previous posts</a>";

    if($_GET["action"]='duplicate') {

    global $wpdb, $current_user;
    get_currentuserinfo();
    $check_if_done = get_user_meta($current_user->ID, 'duplicate_action', true);

    if (empty($check_if_done)) {

    $user_contestentries = $wpdb->get_results(

    "
    SELECT *
    FROM $wpdb->posts
    WHERE post_type = 'trading-calls'
    AND post_author = $current_user->ID;
    "
    );

    foreach ( $user_contestentries as $user_contestentry )

    {
    $new_post_title = $user_contestentry->post_title;
    $new_post_content = $user_contestentry->post_content;
    $new_post_type = $user_contestentry->post_type;
    $new_post_author = $user_contestentry->post_author;

    //here is where we create our new post - a duplicate of the above

    // Create post object
    $new_post = array(
    'post_title' => $new_post_title,
    'post_content' => $new_post_content,
    'post_status' => 'publish',
    'post_type' => $new_post_type,
    'post_author' => $new_post_author
    );

    $new_post_id = wp_insert_post( $new_post, $wp_error ); //inserted a new post
    add_post_meta($new_post_id, 'entryyear', '2013', true); //inserted post meta to the newly created post
    }

    add_user_meta( $new_post_author, 'duplicate_action', 'done', true); //to keep a record that user has already duplicated

    } //end of if empty check_if_done


    else { echo "You have already duplicated the posts once"; }

    } //end of get if

    } // end of user logged in if-condition
    else {

    echo "not logged in";

    } //end of if user is not logged in else-condition
    ?>


    I will now work on wrapping it in a function and then getting all custom taxonomies attached to original posts. Meanwhile, you can have a look at the code.

  • avatar
    Last edited:
    01/29/13
    7:14pm
    Naveen Chand says:

    Adams,

    Here is the code wrapped in a function which you can call from anywhere. I have also slightly modified the code by echoing the link after checking for check_if_done. Also, in my previous post, I have used my own post_type (trading-calls) that I have in my demo site. But in this code below I have changed it to 'contestentry'.


    function duplicate_custom_posts() {

    if ( is_user_logged_in() ) {

    global $wpdb, $current_user;
    get_currentuserinfo();
    $check_if_done = get_user_meta($current_user->ID, 'duplicate_action', true);

    if (empty($check_if_done)) {

    echo "<a href='" .get_page_link() ."?action=duplicate'>Click here to duplicate previous posts</a>";
    if ( isset( $_GET['action'] ) && !empty( $_GET['action'] ) && ($_GET['action']=="duplicate") ) {

    $user_contestentries = $wpdb->get_results(

    "
    SELECT *
    FROM $wpdb->posts
    WHERE post_type = 'contestentry'
    AND post_author = $current_user->ID;
    "
    );

    foreach ( $user_contestentries as $user_contestentry )

    {
    $new_post_title = $user_contestentry->post_title;
    $new_post_content = $user_contestentry->post_content;
    $new_post_type = $user_contestentry->post_type;
    $new_post_author = $user_contestentry->post_author;

    //here is where we create our new post - a duplicate of the above

    // Create post object
    $new_post = array(
    'post_title' => $new_post_title,
    'post_content' => $new_post_content,
    'post_status' => 'publish',
    'post_type' => $new_post_type,
    'post_author' => $new_post_author
    );

    $new_post_id = wp_insert_post( $new_post, $wp_error ); //inserted a new post
    add_post_meta($new_post_id, 'entryyear', '2013', true); //inserted post meta to the newly created post
    }

    add_user_meta( $new_post_author, 'duplicate_action', 'done', true); //to keep a record that user has already duplicated

    } //end of get if

    } //end of if check_if_done is empty

    else { echo "You have already duplicated the posts once"; }

    } // end of user logged in if-condition
    else {

    echo "not logged in";

    } //end of if user is not logged in else-condition

    } //end of the function duplicate_custom_posts


    Using this below code, you can now call this function anywhere (preferably within any existing wp loop because it uses "get_page_link()"):

    <?php duplicate_custom_posts();?>

  • avatar
    Last edited:
    01/29/13
    8:30pm
    Adam Bundy says:

    @Naveen - awesome. We're really close. I just need to get it to copy over the settings for one custom taxonomy (entrycategory) and, if possible, all of the post's post_meta. If that can't be done all in one shot, I can provide a list of those meta keys.

    Also, your formatting is pretty tough for me to read. Would you mind formatting like this pastebin?

    http://pastebin.com/aRdaDKYu

    Thank you Naveen!

  • avatar
    Last edited:
    01/29/13
    9:27pm
    Naveen Chand says:

    @Adam,

    Here is the code for getting all of the post's meta and attaching them to the newly created posts.


    //Get all the post meta for the existing post that is being processed and attach them to the newly created posts
    $existing_post_id = $user_contestentry->ID;
    $existing_postmeta_query = $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE post_id = $existing_post_id;");
    foreach ( $existing_postmeta as $epm ) {
    add_post_meta($new_post_id, $epm->meta_key, $epm->meta_value, true);
    }


    You must insert above code after this line:

    $new_post_id = wp_insert_post( $new_post, $wp_error ); //inserted a new post


    If this works, then let me attempt a similar coding for getting the taxonomy settings.

    And, Sorry about the formatting.

    Thanks,
    Naveen

  • avatar
    Last edited:
    01/29/13
    9:32pm
    Naveen Chand says:

    @Adam,

    Sorry, there is a small error in my previous post. Please change $existing_postmeta_query to $existing_postmeta. Thanks.

  • avatar
    Last edited:
    01/29/13
    9:48pm
    Adam Bundy says:

    Thanks Naveen - that required a little shuffling but it works! Here is my revised function:

    http://pastebin.com/aRdaDKYu

    If we can get the taxonomy licked, we're done. Thanks!

  • avatar
    Last edited:
    01/29/13
    10:08pm
    Naveen Chand says:

    Adam,

    These two lines should do the taxonomy trick.


    $term_list = wp_get_post_terms($existing_post_id, 'entrycategory', array("fields" => "ids"));
    wp_set_post_terms( $new_post_id, $term_list, 'entrycategory', true );


    $term_list will pull all the term_ids (under 'entrycategory') attached to the existing post. And then we use wp_set_post_terms function to insert this array for our newly created post.

    Let me know if it throws any bugs.

  • avatar
    Last edited:
    01/29/13
    10:42pm
    Adam Bundy says:

    Done! Thanks Naveen!

This question has expired.



Adam Bundy, Gabriel Reguly, Christianto, Arnav Joy, Dbranes voted on this question.



Current status of this question: Completed



Please log in to add additional discourse to this page.





Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.

If the asker does not get an answer then they have 10 days to request a refund.