June 29, 2019

How to Prevent Users from Deleting Specific Post Types in WordPress

When developing a custom system using WordPress—such as an order management platform—there are times when you need to ensure that certain content (like orders) cannot be deleted by users. This is critical for maintaining data integrity and security.

In this guide, we’ll demonstrate how to prevent users from deleting posts from specific custom post types (CPTs) in WordPress. This includes disabling individual delete permissions and removing the “Move to Trash” option from the bulk actions menu in the admin dashboard.


Use Case: Preventing Deletion of Order Posts

In our example, we’ve built an order management system where customer service reps can view and update orders submitted from the front end. These orders are stored as a custom post type. To prevent accidental deletions, we need to restrict their ability to delete these order posts while still allowing them to view and edit them.


1. Remove Delete Permission for Certain Post Types

WordPress uses a capability mapping system to determine what actions a user can perform. We can hook into this system using the map_meta_cap filter to block the delete_post capability for certain post types.

Here’s how to do it:

add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id, $args ) {
    // Only act on the delete_post capability
    if ( 'delete_post' !== $cap || empty( $args[0] ) ) {
        return $caps;
    }

    // Restrict deletion for specific post types
    if ( in_array( get_post_type( $args[0] ), [ 'messages', 'transaction' ], true ) ) {
        $caps[] = 'do_not_allow';
    }

    return $caps;
}, 10, 4 );

This will effectively disable the “Delete” link for any posts belonging to the messages or transaction post types. Only the “Edit” action will remain available in the post row actions.


2. Remove “Move to Trash” from Bulk Actions

While individual delete actions are now disabled, the “Move to Trash” option might still appear in the bulk actions dropdown. If users attempt this action, they’ll receive a permissions error—but it’s better UX to remove the option altogether.

Here’s how to remove the “Move to Trash” option from the bulk actions menu:

add_filter( 'bulk_actions-edit-message', function ( $actions ) {
    unset( $actions['trash'] );
    return $actions;
} );

You can repeat this filter for other post types by replacing 'message' in edit-message with the relevant post type slug.


Final Thoughts

With just a few lines of code, you can significantly improve the safety of your WordPress admin interface by restricting delete actions for sensitive post types. This technique is particularly useful for use cases like:

  • Order management systems
  • Contact form message storage
  • Transactional logs
  • Critical user-generated content

For additional permission control, WordPress offers a robust role and capabilities system. You can find more in the official WordPress Roles and Capabilities documentation.