WordPress Version: 6.1
/**
* Trashes or deletes a post or page.
*
* When the post and page is permanently deleted, everything that is tied to
* it is deleted also. This includes comments, post meta fields, and terms
* associated with the post.
*
* The post or page is moved to Trash instead of permanently deleted unless
* Trash is disabled, item is already in the Trash, or $force_delete is true.
*
* @since 1.0.0
*
* @global wpdb $wpdb WordPress database abstraction object.
* @see wp_delete_attachment()
* @see wp_trash_post()
*
* @param int $postid Optional. Post ID. Default 0.
* @param bool $force_delete Optional. Whether to bypass Trash and force deletion.
* Default false.
* @return WP_Post|false|null Post data on success, false or null on failure.
*/
function wp_delete_post($postid = 0, $force_delete = false)
{
global $wpdb;
$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $postid));
if (!$post) {
return $post;
}
$post = get_post($post);
if (!$force_delete && ('post' === $post->post_type || 'page' === $post->post_type) && 'trash' !== get_post_status($postid) && EMPTY_TRASH_DAYS) {
return wp_trash_post($postid);
}
if ('attachment' === $post->post_type) {
return wp_delete_attachment($postid, $force_delete);
}
/**
* Filters whether a post deletion should take place.
*
* @since 4.4.0
*
* @param WP_Post|false|null $delete Whether to go forward with deletion.
* @param WP_Post $post Post object.
* @param bool $force_delete Whether to bypass the Trash.
*/
$check = apply_filters('pre_delete_post', null, $post, $force_delete);
if (null !== $check) {
return $check;
}
/**
* Fires before a post is deleted, at the start of wp_delete_post().
*
* @since 3.2.0
* @since 5.5.0 Added the `$post` parameter.
*
* @see wp_delete_post()
*
* @param int $postid Post ID.
* @param WP_Post $post Post object.
*/
do_action('before_delete_post', $postid, $post);
delete_post_meta($postid, '_wp_trash_meta_status');
delete_post_meta($postid, '_wp_trash_meta_time');
wp_delete_object_term_relationships($postid, get_object_taxonomies($post->post_type));
$parent_data = array('post_parent' => $post->post_parent);
$parent_where = array('post_parent' => $postid);
if (is_post_type_hierarchical($post->post_type)) {
// Point children of this page to its parent, also clean the cache of affected children.
$children_query = $wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE post_parent = %d AND post_type = %s", $postid, $post->post_type);
$children = $wpdb->get_results($children_query);
if ($children) {
$wpdb->update($wpdb->posts, $parent_data, $parent_where + array('post_type' => $post->post_type));
}
}
// Do raw query. wp_get_post_revisions() is filtered.
$revision_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_parent = %d AND post_type = 'revision'", $postid));
// Use wp_delete_post (via wp_delete_post_revision) again. Ensures any meta/misplaced data gets cleaned up.
foreach ($revision_ids as $revision_id) {
wp_delete_post_revision($revision_id);
}
// Point all attachments to this post up one level.
$wpdb->update($wpdb->posts, $parent_data, $parent_where + array('post_type' => 'attachment'));
wp_defer_comment_counting(true);
$comment_ids = $wpdb->get_col($wpdb->prepare("SELECT comment_ID FROM {$wpdb->comments} WHERE comment_post_ID = %d ORDER BY comment_ID DESC", $postid));
foreach ($comment_ids as $comment_id) {
wp_delete_comment($comment_id, true);
}
wp_defer_comment_counting(false);
$post_meta_ids = $wpdb->get_col($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = %d ", $postid));
foreach ($post_meta_ids as $mid) {
delete_metadata_by_mid('post', $mid);
}
/**
* Fires immediately before a post is deleted from the database.
*
* @since 1.2.0
* @since 5.5.0 Added the `$post` parameter.
*
* @param int $postid Post ID.
* @param WP_Post $post Post object.
*/
do_action('delete_post', $postid, $post);
$result = $wpdb->delete($wpdb->posts, array('ID' => $postid));
if (!$result) {
return false;
}
/**
* Fires immediately after a post is deleted from the database.
*
* @since 2.2.0
* @since 5.5.0 Added the `$post` parameter.
*
* @param int $postid Post ID.
* @param WP_Post $post Post object.
*/
do_action('deleted_post', $postid, $post);
clean_post_cache($post);
if (is_post_type_hierarchical($post->post_type) && $children) {
foreach ($children as $child) {
clean_post_cache($child);
}
}
wp_clear_scheduled_hook('publish_future_post', array($postid));
/**
* Fires after a post is deleted, at the conclusion of wp_delete_post().
*
* @since 3.2.0
* @since 5.5.0 Added the `$post` parameter.
*
* @see wp_delete_post()
*
* @param int $postid Post ID.
* @param WP_Post $post Post object.
*/
do_action('after_delete_post', $postid, $post);
return $post;
}