Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I need to be able to merge two or more posts. What is the exact query (or queries) to make this happen?

The scenario is multiple recommendations that need to be merged into one. I have already sorted out comments merging and meta merging.

Let's say a user recommends Bill Gates, another one Gates Bill and another one makes a typo and adds Bil Gates. I need to merge these three posts and choose the destination one.

UPDATE:

What I need is a complete SQL query for deleting a post and all references to that post. Something like this pseudo-code:

DELETE FROM wp_posts WHERE id = X;
DELETE FROM wp_posts_meta WHERE id = X;
DELETE FROM wp_another_table WHERE id = X;
DELETE FROM wp_yet_another_table WHERE id = X;

where X is the ID of my post.

The code (or plugin) shouldn't auto-detect duplicates. I will present the user a dropdown with a list of posts and the "Delete" option. Before deleting, I will copy the post content from one post to the other using an SQL UPDATE query.

UPDATE 2:

I think I found something, I'll have to check though:

    $custom_field_keys = get_post_custom_keys($postid);
    foreach($custom_field_keys as  $key => $value) {
        $valuet = trim($value);
        if('_' != $valuet{0} ){
               delete_post_meta($postid, $key, '');
        }
   }
   $result = wp_delete_post($postid);
share|improve this question
    
I take it "recommendations" are a custom post type? Have you thought about searching for the "recommendation" first before you add it? –  Joseph Sep 6 '12 at 23:51
    
No, recommendations are simple posts. They are added via a frontend form. I've been searching for "merging posts" for the last three days, with no luck. –  Ciprian Sep 6 '12 at 23:54
    
Your question is confusing, are you literally merging post content? Are you choosing which one to publish? How do you find the relation of posts that need to be "merged".. –  Wyck Sep 9 '12 at 14:42
    
I need to literally merge post content. Yes, I need to choose which one to publish, but this is easy. Posts to be merged should be regular WordPress posts. I'll build a drop-down of posts and select Merge X with Y and Keep Y (this is just an example). –  Ciprian Sep 9 '12 at 15:55
    
What does merge actually mean? Do you want to append the content of X to the content of Y? –  kaiser Sep 10 '12 at 12:20

1 Answer 1

up vote 7 down vote accepted
+50

The requirements you are describing require much more of an explanation than is really suitable here. A simple solution might be to mark the duplicate posts as duplicates via a meta box on the post screen. This meta box would have one input: A reference to another post.

Check out this tutorial on how to build a custom meta box.

Suppose you've set up a meta box that will allow the user to mark a post that is a duplicate of another post. Say the duplicate post is marked with a meta key _duplicate_of_post, whose meta value is the canonical post's post ID.

You can then on filter the_posts filter to pull together any duplicates, folding the the canonical post together with any of its duplicates:

function my_the_posts_filter( $posts, $query ) {
    // Only operate on the main query.
    if( !$query->is_main_query() )
         return $posts;

    // Store canonical posts here. 
    $canonicals = array();

    // Store the duplicates here, keyed by canonical post ID
    $duplicates = array();

    foreach( $posts as $post ) {
        if( $dupe_id = get_post_meta( $post->ID, '_duplicate_of_post', true ) ) {
           $canonicals[] = get_post( $dupe_id ); 

           $duplicates[$dupe_id] = get_posts( array( 'meta_key' => '_duplicate_of_post', 'meta_value' => $dupe_id, 'posts_per_page' => -1, 'post__not_in' => $post->ID ) );
        }
        else {
           $canonicals[] = $post;

           // Get all posts who have this marked as duplicate
           $duplicates[$post->ID] = get_posts( array( 'meta_key' => '_duplicate_of_post', 'meta_value' => $post->ID, 'posts_per_page' => -1 ) );
        }
    }

    // Append all of the other post content to the canonicals separated
    // by two newlines
    foreach( $canonicals as $post )
       $post->post_content .= array_join( "\n\n", wp_list_pluck( $duplicates[$dupe_id], 'post_content' ) );

    return $canonicals;
}
add_filter( 'the_posts', 'my_the_posts_filter', 10, 2 );

One caveat in implementation of the post reference meta box is that you'd have to implement the logic to ensure that you can't set a post as a duplicate post is if it's already marked as a "master" post by another post. Without that restriction, the example above will break in unexpected ways.

Update

You can also hook on save_post, combine, then trash posts marked as duplicates:

function my_save_post( $post ) {
    // Don't do on autosave
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

    if( isset( $_POST['_duplicate_of_post'] ) && ( $dupe_of_id = (int) $_POST['_duplicate_of_post'] ) && ( $source = get_post( $dupe_of_id ) ) ) {  
       // Add this post's content to the canonical version               
       $update = array( 'ID' => $source->ID, 'post_content' => $source->post_content );
       $update['post_content'] .= "\n\n" . $post->post_content;

       // Update canonical
       wp_update_post( $update );

       // Trash this post
       wp_trash_post( $post->ID );
    }
}
add_action( 'save_post', 'my_save_post' );

This is the most basic of examples. It's expecting a form field on the edit post screen named _duplicate_of_post which contains the canonical post's ID. Note that I'm using ONLY the WordPress API, which is something you should always aspire to do while developing theme and plugin code.

share|improve this answer
    
+1 for the answer. I have many duplicates and I'd really love to delete the "slave" one. Your implementation looks nice and useful, but I'd be more interested in a complete SQL query for deleting a post and all references to that post. UPDATE: didn't know about the wp_list_pluck() function. Thanks. –  Ciprian Sep 10 '12 at 21:42
    
There are SQL queries that will delete the duplicates, but then you'd be losing information, and if you are using caching, those caches could get invalidated if you directly manipulate the database. = –  Bendoh Sep 10 '12 at 22:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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