Wordpress - Prevent trash/delete action on specific post types
Here's another approach using the map_meta_cap
filter that's applied within the map_meta_cap()
function within the has_cap()
method of the WP_User
class (PHP 5.4+):
add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id, $args )
{
// Nothing to do
if( 'delete_post' !== $cap || empty( $args[0] ) )
return $caps;
// Target the payment and transaction post types
if( in_array( get_post_type( $args[0] ), [ 'payment', 'transaction' ], true ) )
$caps[] = 'do_not_allow';
return $caps;
}, 10, 4 );
where we target the delete_post meta capability and the payment
and transaction
custom post types.
As far as I understand and skimming through the get_post_type_capabilities()
function we don't need the map_meta_cap
argument set as true, in the register_post_type
settings, to target the delete_post
meta capability.
ps:
Here are some good descriptions of the map_meta_cap
filter and helpful examples by Justin Tadlock here and Toscho here. Here I found an old example that I had forgot I wrote, that we could also adjust to avoid trash/delete on some given pages and user roles. Here's an answer by TheDeadMedic that links to an answer by Seamus Leahy regarding register_post_type
approach.
Here are some more examples on this site. Hope it helps!
A better way to prevent deletion would be to disable that capability for all roles. When you register your post types 'payment' and 'transaction' also define a capability_type
with the same name as your post type. This will give you capabilities read_payment
, edit_payment
and delete_payment
(same for transaction).
You can then deny this capability on roles in this way:
$wp_roles->remove_cap( 'editor', 'delete_payment' );
$wp_roles->remove_cap( 'admin', 'delete_payment' );
Always beware that since admins can edit code on your site, they will still be able to circumvent the deletion, unless you block code editing in the backend and restrict ftp and database access. Also read this discussion on getting all available roles.