wp_delete_attachment

The timeline below displays how wordpress function wp_delete_attachment has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.1

/**
 * Trashes or deletes 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);
    }
    /**
     * Filters whether an attachment deletion should take place.
     *
     * @since 5.5.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_attachment', null, $post, $force_delete);
    if (null !== $check) {
        return $check;
    }
    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() && is_string($file) && !empty($file)) {
        clean_dirsize_cache($file);
    }
    /**
     * Fires before an attachment is deleted, at the start of wp_delete_attachment().
     *
     * @since 2.0.0
     * @since 5.5.0 Added the `$post` parameter.
     *
     * @param int     $post_id Attachment ID.
     * @param WP_Post $post    Post object.
     */
    do_action('delete_attachment', $post_id, $post);
    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 ORDER BY comment_ID DESC", $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, $post);
    $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, $post);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 5.9

/**
 * 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);
    }
    /**
     * Filters whether an attachment deletion should take place.
     *
     * @since 5.5.0
     *
     * @param bool|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_attachment', null, $post, $force_delete);
    if (null !== $check) {
        return $check;
    }
    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() && is_string($file) && !empty($file)) {
        clean_dirsize_cache($file);
    }
    /**
     * Fires before an attachment is deleted, at the start of wp_delete_attachment().
     *
     * @since 2.0.0
     * @since 5.5.0 Added the `$post` parameter.
     *
     * @param int     $post_id Attachment ID.
     * @param WP_Post $post    Post object.
     */
    do_action('delete_attachment', $post_id, $post);
    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 ORDER BY comment_ID DESC", $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, $post);
    $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, $post);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 5.6

/**
 * 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);
    }
    /**
     * Filters whether an attachment deletion should take place.
     *
     * @since 5.5.0
     *
     * @param bool|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_attachment', null, $post, $force_delete);
    if (null !== $check) {
        return $check;
    }
    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()) {
        clean_dirsize_cache($file);
    }
    /**
     * Fires before an attachment is deleted, at the start of wp_delete_attachment().
     *
     * @since 2.0.0
     * @since 5.5.0 Added the `$post` parameter.
     *
     * @param int     $post_id Attachment ID.
     * @param WP_Post $post    Post object.
     */
    do_action('delete_attachment', $post_id, $post);
    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, $post);
    $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, $post);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 5.5

/**
 * 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);
    }
    /**
     * Filters whether an attachment deletion should take place.
     *
     * @since 5.5.0
     *
     * @param bool|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_attachment', null, $post, $force_delete);
    if (null !== $check) {
        return $check;
    }
    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
     * @since 5.5.0 Added the `$post` parameter.
     *
     * @param int     $post_id Attachment ID.
     * @param WP_Post $post    Post object.
     */
    do_action('delete_attachment', $post_id, $post);
    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, $post);
    $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, $post);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 5.4

/**
 * 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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 9.7

/**
 * 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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

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;
}

WordPress Version: .20

/**
 * 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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 9.2

/**
 * 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;
}

WordPress Version: .10

/**
 * 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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 4.9

/**
 * 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;
}

WordPress Version: 8.7

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 8.2

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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;
}

WordPress Version: .10

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 6.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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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;
}

WordPress Version: .20

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 6.2

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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;
}

WordPress Version: .12

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 5.4

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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;
}

WordPress Version: .30

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 5.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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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;
}

WordPress Version: .20

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 5.2

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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;
}

WordPress Version: .15

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 4.5

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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;
}

WordPress Version: 4.4

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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_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;
}

WordPress Version: .30

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 4.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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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_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;
}

WordPress Version: .20

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 4.2

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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_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;
}

WordPress Version: .16

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 4.4

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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_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;
}

WordPress Version: 3.4

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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;
}

WordPress Version: .30

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 3.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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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;
}

WordPress Version: .20

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 3.2

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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;
}

WordPress Version: .17

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 2.4

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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;
}

WordPress Version: .30

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 2.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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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;
}

WordPress Version: .21

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 4.2

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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;
}

WordPress Version: 1.5

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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-admin/custom-header.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-admin/custom-header.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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .40

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 1.4

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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-admin/custom-header.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-admin/custom-header.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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .30

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 1.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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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-admin/custom-header.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-admin/custom-header.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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .24

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 4.1

/**
 * 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 mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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_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-admin/custom-header.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-admin/custom-header.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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: 0.4

/**
 * 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 access abstraction object.
 *
 * @param int  $post_id      Attachment ID.
 * @param bool $force_delete Optional. Whether to bypass trash and force deletion.
 *                           Default false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    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);
    $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);
    }
    $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_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-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // Remove intermediate and backup images if there are any.
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .30

/**
 * 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 access abstraction object.
 *
 * @param int  $post_id      Attachment ID.
 * @param bool $force_delete Optional. Whether to bypass trash and force deletion.
 *                           Default false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 0.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 access abstraction object.
 *
 * @param int  $post_id      Attachment ID.
 * @param bool $force_delete Optional. Whether to bypass trash and force deletion.
 *                           Default false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    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);
    $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);
    }
    $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_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-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // Remove intermediate and backup images if there are any.
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .24

/**
 * 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 access abstraction object.
 *
 * @param int  $post_id      Attachment ID.
 * @param bool $force_delete Optional. Whether to bypass trash and force deletion.
 *                           Default false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $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);
    }
    $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);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 4.0

/**
 * 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 access abstraction object.
 *
 * @param int  $post_id      Attachment ID.
 * @param bool $force_delete Optional. Whether to bypass trash and force deletion.
 *                           Default false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    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);
    $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);
    }
    $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_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-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // Remove intermediate and backup images if there are any.
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: 3.9

/**
 * Trashes or deletes 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
 * @uses $wpdb
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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_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", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: 8.4

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $result = $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    if (!$result) {
        return false;
    }
    do_action('deleted_post', $post_id);
    $uploadpath = wp_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", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .30

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $result = $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    if (!$result) {
        return false;
    }
    do_action('deleted_post', $post_id);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 8.3

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $result = $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    if (!$result) {
        return false;
    }
    do_action('deleted_post', $post_id);
    $uploadpath = wp_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", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .27

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $result = $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    if (!$result) {
        return false;
    }
    do_action('deleted_post', $post_id);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 3.8

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $result = $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    if (!$result) {
        return false;
    }
    do_action('deleted_post', $post_id);
    $uploadpath = wp_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", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: 7.5

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    do_action('deleted_post', $post_id);
    $uploadpath = wp_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", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .40

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    do_action('deleted_post', $post_id);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 7.4

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    do_action('deleted_post', $post_id);
    $uploadpath = wp_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", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .30

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    do_action('deleted_post', $post_id);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 7.3

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    do_action('deleted_post', $post_id);
    $uploadpath = wp_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", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}

WordPress Version: .27

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    do_action('deleted_post', $post_id);
    wp_delete_attachment_files($post_id, $meta, $backup_sizes, $file);
    clean_post_cache($post);
    return $post;
}

WordPress Version: 3.7

/**
 * Trashes or deletes 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
 * @uses $wpdb
 * @uses do_action() Calls 'delete_attachment' hook on Attachment ID.
 *
 * @param int $post_id Attachment ID.
 * @param bool $force_delete Whether to bypass trash and force deletion. Defaults to false.
 * @return mixed False on failure. Post data on success.
 */
function wp_delete_attachment($post_id, $force_delete = false)
{
    global $wpdb;
    if (!$post = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->posts} WHERE ID = %d", $post_id))) {
        return $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);
    $intermediate_sizes = array();
    foreach (get_intermediate_image_sizes() as $size) {
        if ($intermediate = image_get_intermediate_size($post_id, $size)) {
            $intermediate_sizes[] = $intermediate;
        }
    }
    if (is_multisite()) {
        delete_transient('dirsize_cache');
    }
    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_metadata('post', null, '_thumbnail_id', $post_id, true);
    // delete all for any posts.
    $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);
    }
    $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);
    }
    do_action('delete_post', $post_id);
    $wpdb->delete($wpdb->posts, array('ID' => $post_id));
    do_action('deleted_post', $post_id);
    $uploadpath = wp_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", '%' . $meta['thumb'] . '%', $post_id))) {
            $thumbfile = str_replace(basename($file), $meta['thumb'], $file);
            /** This filter is documented in wp-admin/custom-header.php */
            $thumbfile = apply_filters('wp_delete_file', $thumbfile);
            @unlink(path_join($uploadpath['basedir'], $thumbfile));
        }
    }
    // remove intermediate and backup images if there are any
    foreach ($intermediate_sizes as $intermediate) {
        /** This filter is documented in wp-admin/custom-header.php */
        $intermediate_file = apply_filters('wp_delete_file', $intermediate['path']);
        @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-admin/custom-header.php */
            $del_file = apply_filters('wp_delete_file', $del_file);
            @unlink(path_join($uploadpath['basedir'], $del_file));
        }
    }
    /** This filter is documented in wp-admin/custom-header.php */
    $file = apply_filters('wp_delete_file', $file);
    if (!empty($file)) {
        @unlink($file);
    }
    clean_post_cache($post);
    return $post;
}