3

For whatever reason, I have a post and a page with the same slug name and it causes the db to hang. I can't alter the slug on either so I need to go manually delete the posts from the database and start over.

Now, I am willing to go pull up the post ID from wp_posts and wp_postmeta and manually delete each entry. Will this screw up anything else in the database assuming I have no comments on either post or page?

EDIT

I found this script and I think it's ok but I'm not sure if this takes care of revisions or anything else I would leave behind from manually deleting the post

DELETE a,b,c
FROM wp_posts a
LEFT JOIN wp_term_relationships b ON ( a.ID = b.object_id )
LEFT JOIN wp_postmeta c ON ( a.ID = c.post_id )
WHERE a.ID = xxx;
0

5 Answers 5

5

Drop this into a file in your plugin directory and you should be able to do this from your WP installation using a query string.

/*
Plugin Name: Delete Specific Post
Description: Rid the post forever!
Version: 0.1
Author: WPSE
License: GPL2
*/

add_filter('query_vars', 'delete_post_query_var');
function delete_post_query_var($vars){
    $vars[] = 'delete_post';
    return $vars;
}

add_action('admin_init', 'manually_delete_post', 0);
function manually_delete_post(){

    if(!is_user_logged_in())
        return;

    if(!current_user_can('manage_options'))
        return;

    if(get_query_var('delete_post')){
        $id = esc_attr(get_query_var('delete_post'));
        $delete = wp_delete_post($id, true); //True force deletes the post and doesn't send it to the Trash
        if($delete)
            echo "Post $id deleted successfully!";
        else
            echo "Post $id was not deleted.";
        exit;
    }
}

All you need to do is make sure you're logged into an administrator account, then visit: http://yourdomain.com/wp-admin/?delete_post=POSTID

6
  • Nice! This is an alternative I can work with. I've been told that having too many plugins slows down the site though...I'm still leaning toward the SQL query.
    – AlxVallejo
    Commented Aug 23, 2012 at 18:34
  • @AlxVallejo WordPress is basically a collection of plugins hooking into other functionality and providing more hooks. That said, it will not slow your site down to have third-party scripts in your plugins folder -- that's a complete myth. The only time a plugin can slow down your system is if it's active. Activate this when you need, deactivate it when you don't need it. Commented Aug 23, 2012 at 18:37
  • I'll give you credit but I still believe that manually deleting posts on a WP db is an essential skill that should be publicized in case a post is causing problems. I don't know why everyone's against writing SQL - the act of activating a plugin just to remove a post from the DB seems, imho, silly. Thanks for the write-up, I could actually use this format for other functions I think of using the query_var param.
    – AlxVallejo
    Commented Aug 23, 2012 at 18:43
  • @AlxVallejo I'm not against using MYSQL for this. 3-3.me/6DUn I've used this in the past, but for me logging into mysql (via client or command line and running this query is just as much work as activating a plugin in my directory and typing a query string.) Commented Aug 23, 2012 at 18:47
  • @AlxVallejo someone else made a comment today on an answer of mine re: why would you use a plugin when you can do it with a line of code or SQL. My point is that MANY people want a hassle-free option just like saying "dont you know there is a plugin (app) for that" and it's these same people who love to use WordPress (vs Drupal or many other CMS's)
    – Damien
    Commented Aug 24, 2012 at 16:34
3

I recently had this issue with a post-type I wanted to nuke, relationships everywhere and no DB enforced FK cascade.

/* DELETE REVISIONS */
DELETE posts
FROM
    `prefix_posts` AS posts
INNER JOIN `prefix_posts` AS parents ON posts.post_parent = parents.ID
WHERE
    parents.post_type = "myposttype"; /*REPLACE W/ parents.ID = "yourID"*/


/* DELETE POSTS */
DELETE
FROM
    `prefix_posts`
WHERE
    post_type = "myposttype"; /*REPLACE W/ ID = "yourID"*/


/* DELETE ORPHANED POST META */
DELETE
FROM
    `prefix_postmeta`
WHERE
`prefix_postmeta`.`post_id` NOT IN(
    SELECT
        `prefix_posts`.`ID`
    FROM
        `prefix_posts`
);

Are you using any plugins that create tables? (like post-2-post)

/* ORPHANED POST2POSTS */
DELETE
FROM
    `prefix_p2p`
WHERE
    `prefix_p2p`.`p2p_from` NOT IN(
        SELECT
            `prefix_posts`.`ID`
        FROM
            `prefix_posts`
);

DELETE
FROM
`prefix_p2p`
WHERE
    `prefix_p2p`.`p2p_to` NOT IN(
        SELECT
            `prefix_posts`.`ID`
        FROM
            `prefix_posts`
    );

its probably easier to use the built in WP functions... but if you need SQL calls for this look above.

2

Expanding on @Brian Fegter's answer Above you could use the below plugin to remove posts in bulk. It creates a WP admin page with a text area for ids of pages/posts to remove.

<?php

/*
Plugin Name: Delete Posts By ID
Description: Delete posts and pages by id
Version: 0.1
Author: WPSE
License: GPL2
*/


add_action( 'admin_menu', 'deletePostsMenu' );

function deletePostsMenu() {
    add_menu_page(
        'Delete Posts',
        'Delete Posts',
        'manage_options',
        'delete-posts/delete-posts-admin-page.php',
        'delete_posts_admin_page',
        'dashicons-trash',
        6
    );
}

function delete_posts_admin_page() {
    ?>
    <div class="wrap">
        <h2>Delete Posts By ID</h2>
        <p>Add post/page ids separated by a line break</p>
        <form action="" method="post">
            <label for="deletePostsByID"></label>
            <textarea name="deletePostsByID" id="ids" cols="30" rows="10"></textarea>
            <input type="submit">
        </form>
    </div>
    <?php

    if (isset($_POST['deletePostsByID'])) {
        delete_posts($_POST['deletePostsByID']);
        return;
    }
}

//add_action('admin_init', 'manually_delete_post', 0);
function delete_posts($submittedIDs){

    if(!is_user_logged_in())
        return;

    if(!current_user_can('manage_options'))
        return;

   /* // Strip whitespace
    $stripped = str_replace(' ', '', $submittedIDs);*/

    // Set to array
    $idsArray = explode("\r\n",$submittedIDs);

    echo '<ol>';
    // Delete posts by id
    foreach ($idsArray as $id){
        $delete = wp_delete_post($id, false); //True force deletes the post and doesn't send it to the Trash
        if($delete)
            echo "<li>Post $id deleted successfully!</li>";
        else
            echo "<li>Post $id was not deleted.</li>";

    }

    echo '</ol>';

    exit;
}
1

why not simply use wp_delete_post() ?

When the post and page goes, everything that is tied to it is deleted also. This includes comments, post meta fields, and relationships between the post and taxonomy terms.

8
  • That would essentially require me to build a custom menu and have some sort of field to input the post id. Going straight to phpmyadmin seems faster as long as I hit the right areas. Unless you have a better place for that function?
    – AlxVallejo
    Commented Aug 23, 2012 at 16:48
  • you only need a list(array) of post_id to delete. how do you construct this list (query, manualy,...) is yours... and do a foreach to delete the posts Commented Aug 23, 2012 at 17:30
  • Well you also need a page template to execute the function...how else do you execute a function?
    – AlxVallejo
    Commented Aug 23, 2012 at 17:47
  • there is a lot of way to trigger your function in wordpress... but this is not specific to your question like Brian Fegter sayed: WPSE is for questions not for others doing the work for you. If you need a developer, you should probably look to hire someone Commented Aug 23, 2012 at 17:52
  • Ok but this doesn't answer my question. Using wp_delete_post is incomplete in that you don't explain how to use it and why it would be better than going straight to SQL. You can execute the SQL command in the SQL window of phpmyadmin; With wp_delete_post, you can ... In other words, your answer lacks context.
    – AlxVallejo
    Commented Aug 23, 2012 at 17:55
-2

Ok, if you want to delete it completely, you have to delete post/page from wp_term_relationships table. But if the issue is only in the slug, you can update appropriate record in database and your slugs will be fixed. To update slug you need to run such query:

UPDATE wp_posts SET post_name = 'my-new-slug' WHERE ID = /*your post ID here*/
7
  • wp_term_relationships has object_id. Is that post_id? I thought posts would be separate from taxonomy-term relationships.
    – AlxVallejo
    Commented Apr 6, 2012 at 17:40
  • yes, object_id is post_id Commented Apr 6, 2012 at 19:28
  • Two questions: Can you help me write a script to manually delete a post which includes post_meta and (wp_term_relationships)? for a given post id? And second, Does optimizing the database cleanup the lost meta data for deleted posts?
    – AlxVallejo
    Commented Jul 16, 2012 at 18:05
  • 1
    @AlxVallejo A friendly note: WPSE is for questions not for others doing the work for you. If you need a developer, you should probably look to hire someone. Commented Aug 23, 2012 at 17:47
  • 1
    @AlxVallejo Asking for suggestions or tips is one thing. Asking explicitly for someone to do the work for you i.e. 'Can you help me write a script to manually delete a post?' is not what this forum is for. Commented Aug 23, 2012 at 18:01

Your Answer

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

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