0

I'm having an issue where the attachment is being deleted despite me returning false

function action_maybe_delete( $id ) { 

  echo "Let's not delete Attachment id: " . $id ;
  // prevent the attachment from actually being deleted
  if( 1 == 1 ) { // made up condition 
    return false; 
  }
};
// add the action 
add_action( 'delete_attachment', 'action_maybe_delete', 10, 1 ); 

When i run code similar to the above from the media library, it calls admin_ajax.php it echos the mesage Let's not delete Attachmend id: 123 in the http response, but it still deletes the file entry the media library.

Shouldn't it NOT delete the file?

My end goal is to run some statements that remove the file from my Amazon S3 container and if that fails, NOT delete the local file ( but rather tell user that the process failed )... or something like that.

1 Answer 1

4

Updated answer for WordPress 5.5.0+

As of 5.5.0, a new filter has been added to wp_delete_attachment:


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

This "short-circuit" filter is before almost any meaningful action is made, save for trashing the attachment if certain conditions are met. A cleaner approach would now be:


function action_maybe_delete( $id ) { 
  echo "Let's not delete Attachment id: " . $id ;
  // prevent the attachment from actually being deleted
  if( 1 == 1 ) { // made up condition 
    return false; 
  }
};
// add the action 
add_action( 'pre_delete_attachment', 'action_maybe_delete', 10, 1 ); 
  • Returning anything other than null from this will prevent wp_delete_attachment from going any further, and instead the result of the filter will be returned.

Old Answer from pre 5.5.0

First, let's take a look at where delete_attachment is fired in core. This happens on line 5062 of wp-includes/post.php in the wp_delete_attachment function. Here's the relevant snippet:

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

We can see that WordPress core is calling do_action - this method does not care what's returned; unlike apply_filters, do_action simply fires a hook and then processing continue despite any return values. Looking further at the source of wp_delete_attachment, there doesn't appear to be a way to "short-circuit" this process and prevent deleting the attachment.

Except, technically, you could use PHP's die or exit statements to end processing of the script, which should effectively prevent the file from being deleted.

function action_maybe_delete( $id ) {
    echo "Let's not delete Attachment id: " . $id ;
    // prevent the attachment from actually being deleted
    if( 1 == 1 ) { // made up condition
        die; // Prevent the script from continuing.
    }
};
// add the action
add_action( 'delete_attachment', 'action_maybe_delete', 10, 1 ); ?php
3
  • Thanks! I'm going to try this out to see if it works, but I'm pretty sure the first thing that I tried is die Commented Oct 19, 2018 at 15:18
  • Upon further reflection, using die is definitely a pretty harsh way to prevent the deletion anyhow, I'm thinking there must be another hook earlier in the process. Commented Oct 19, 2018 at 15:34
  • @Armstrongest just a note, since version 5.5 in 2020, a new filter was added called pre_delete_attachment that can be short-circuited to stop a delete from happening.
    – phatskat
    Commented May 1, 2022 at 2:18

Your Answer

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

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