How to prevent WordPress Media Library from removing image?

922 Views Asked by At

I have a custom post type that must have its feature image. Its feature image also appears in the Media Library where user can delete the image/attachment file permanently. But I want to prevent user from deleting the feature image of my custom post type. So I use the following hook to intercept the ajax request, validate if user is deleting the image of my custom post type and stop the process by using wp_die().

add_filter('pre_delete_attachment', 'check_my_custom_post_type', 0, 2);
function check_my_custom_post_type($delete, $post) {
    if (Yes it is image of my custom type) {
        wp_die('My message', 'My title', ['response' => 400]);
    }
}

It works fine on the server side. The image of my custom post type cannot be deleted. But Media Library, on the client side, still removes the image from its views even the image on the server side has not been deleted and an exception 400 has been thrown.

How to prevent Media Library from removing images from its views on the client side if image has not been deleted on the server side?

2

There are 2 best solutions below

2
On

In documentation second parameter is bool|null. Try to return false instead of wp_die

0
On

You can remove the delete link totally using the wp_prepare_attachment_for_js hook.

function remove_media_delete_link_in_grid_view( $response ) {
    $response['nonces']['delete'] = false;

    return $response;
}
add_filter( 'wp_prepare_attachment_for_js', 'remove_media_delete_link_in_grid_view' );

This works also with the "Bulk Delete" action. If the attachment has this nonce value false, it will not be deleted with the other bulk selected attachments .

But this works only with the Grid View that uses the wp_prepare_attachment_for_js hook. The List view doesn't use any Javascript. So, to prevent deleting media files in the List view, you have to:

  • Remove the individual delete link of each media item in the list using the media_row_actions hook.
  • And remove the delete option from the bulk actions menu using the bulk_actions-{$screen} hook.
function remove_media_delete_link_in_list_view( $actions ) {
    unset( $actions['delete'] );

    return $actions;
}
add_filter( 'media_row_actions',   'remove_media_delete_link_in_list_view' );
add_filter( 'bulk_actions-upload', 'remove_media_delete_link_in_list_view' );