WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

wp_delete_attachment() is very comprehensive and wipes every trace of attachment from database and disk.

Is there easy way to keep original file? Forking under another name is not an option, because other functions like wp_delete_post() will still call original version.

share|improve this question
up vote 5 down vote accepted

Year and some later with much improved skills, behold:


 * Keep original file when deleting attachments.
class Keep_Deleted_Attachment_File {

    static private $file;

    static function on_load() {

        add_action( 'init', array( __CLASS__, 'init' ) );

    static function init() {

        add_action( 'delete_attachment', array( __CLASS__, 'delete_attachment' ) );

     * @param int $post_id attachment being deleted
    static function delete_attachment( $post_id ) {

        self::$file = get_attached_file( $post_id );
        add_filter( 'wp_delete_file', array( __CLASS__, 'wp_delete_file' ) );

     * @param string $file path to file being deleted
     * @return string|bool no change or boolean false to prevent file deletion
    static function wp_delete_file( $file ) {

        if ( ! empty( self::$file ) && self::$file == $file ) {

            remove_filter( current_filter(), array( __CLASS__, __FUNCTION__ ) );
            return false;

        return $file;
share|improve this answer
I'm not sure how much this is related, but as I just stumbled upon it: IMAGE_EDIT_OVERWRITE can be set in the wp_config.php file, as all checks seem to question if it's defined before actually executing code. – kaiser Oct 19 '12 at 2:26
@kaiesr from quick look I don't quite get what that constant does, but it's not involved in final attachment delete ( wp_delete_attachment() ) – Rarst Oct 19 '12 at 9:43

Assuming $attachment_id is the ID of the attachment you want to delete without deleting the file, this should do it:

$wpdb->query( $wpdb->prepare( "DELETE FROM $wpdb->posts, $wpdb->postmeta WHERE $wpdb->posts.ID = %d OR $wpdb->postmeta.post_id = %d", $attachment_id, $attachment_id ) );
share|improve this answer
Yep, I can rip out enough code to do it manually... But if something calls original version - boom, file gone. :( – Rarst Feb 17 '11 at 15:00

Your Answer


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

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