WordPress Version: 9.3
/**
* Trash or delete an attachment.
*
* When an attachment is permanently deleted, the file will also be removed.
* Deletion removes all post meta fields, taxonomy, comments, etc. associated
* with the attachment (except the main post).
*
* The attachment is moved to the trash instead of permanently deleted unless trash
* for media is disabled, item is already in the trash, or $force_delete is true.
*
* @since 2.0.0
*
* @global wpdb $wpdb WordPress database abstraction object.
*
* @param int $post_id Attachment ID.
* @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_attachment($post_id, $force_delete = false)
{
global $wpdb;
$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id));
if (!$post) {
return $post;
}
$post = get_post($post);
if ('attachment' !== $post->post_type) {
return false;
}
if (!$force_delete && EMPTY_TRASH_DAYS && MEDIA_TRASH && 'trash' !== $post->post_status) {
return wp_trash_post($post_id);
}
delete_post_meta($post_id, '_wp_trash_meta_status');
delete_post_meta($post_id, '_wp_trash_meta_time');
$meta = wp_get_attachment_metadata($post_id);
$backup_sizes = get_post_meta($post->ID, '_wp_attachment_backup_sizes', true);
$file = get_attached_file($post_id);
if (is_multisite()) {
delete_transient('dirsize_cache');
}
/**
* Fires before an attachment is deleted, at the start of wp_delete_attachment().
*
* @since 2.0.0
*
* @param int $post_id Attachment ID.
*/
do_action('delete_attachment', $post_id);
wp_delete_object_term_relationships($post_id, array('category', 'post_tag'));
wp_delete_object_term_relationships($post_id, get_object_taxonomies($post->post_type));
// Delete all for any posts.
delete_metadata('post', null, '_thumbnail_id', $post_id, true);
wp_defer_comment_counting(true);
$comment_ids = $wpdb->get_col($wpdb->prepare("SELECT comment_ID FROM {$wpdb->comments} WHERE comment_post_ID = %d", $post_id));
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 ", $post_id));
foreach ($post_meta_ids as $mid) {
delete_metadata_by_mid('post', $mid);
}
/** This action is documented in wp-includes/post.php */
do_action('delete_post', $post_id);
$result = $wpdb->delete($wpdb->posts, array('ID' => $post_id));
if (!$result) {
return false;
}
/** This action is documented in wp-includes/post.php */
do_action('deleted_post', $post_id);
$uploadpath = wp_get_upload_dir();
if (!empty($meta['thumb'])) {
// Don't delete the thumb if another attachment uses it.
if (!$wpdb->get_row($wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attachment_metadata' AND meta_value LIKE %s AND post_id <> %d", '%' . $wpdb->esc_like($meta['thumb']) . '%', $post_id))) {
$thumbfile = str_replace(basename($file), $meta['thumb'], $file);
/** This filter is documented in wp-includes/functions.php */
$thumbfile = apply_filters('wp_delete_file', $thumbfile);
@unlink(path_join($uploadpath['basedir'], $thumbfile));
}
}
// Remove intermediate and backup images if there are any.
if (isset($meta['sizes']) && is_array($meta['sizes'])) {
foreach ($meta['sizes'] as $size => $sizeinfo) {
$intermediate_file = str_replace(basename($file), $sizeinfo['file'], $file);
/** This filter is documented in wp-includes/functions.php */
$intermediate_file = apply_filters('wp_delete_file', $intermediate_file);
@unlink(path_join($uploadpath['basedir'], $intermediate_file));
}
}
if (is_array($backup_sizes)) {
foreach ($backup_sizes as $size) {
$del_file = path_join(dirname($meta['file']), $size['file']);
/** This filter is documented in wp-includes/functions.php */
$del_file = apply_filters('wp_delete_file', $del_file);
@unlink(path_join($uploadpath['basedir'], $del_file));
}
}
wp_delete_file($file);
clean_post_cache($post);
return $post;
}