I would like to prevent a user from accidentally deleting their homepage. All the sites I build display a page rather than posts on front/as a homepage.
Please can someone suggest a method that: 1) hides the checkbox and quick edit Trash/Bin tab from the manage pages screen and 2) removes the 'Move to Trash/Bin' link from the edit page screen for the page that has been selected as the site homepage.
I would prefer not to use CSS hacks such as display:none, but am flexible on this point if a CSS solution is in fact the best/easiest method.
Thank you
John Cotton answers:
All those links are only display if this line of code returns true:
current_user_can( "delete_post", $post->ID )
You can filter current_user_can add_filter( 'user_has_cap'....
Check the args for the post id against the id of the homepage and return false if it's the homepage.
designbuildtest comments:
Thanks John, could you wrap/code your proposed solution as a full working function?
John Cotton comments:
There's a good example here:
[[LINK href="http://codex.wordpress.org/Plugin_API/Filter_Reference/user_has_cap"]]http://codex.wordpress.org/Plugin_API/Filter_Reference/user_has_cap[[/LINK]]
John Cotton comments:
function user_cap_filter( $allcaps, $cap, $args ) {
if ( 'delete_post' != $args[0] )
return $allcaps;
if ( get_option( 'page_on_front' ) != $args[2] )
return $allcaps;
$allcaps[$cap[0]] = false;
return $allcaps;
}
add_filter( 'user_has_cap', 'user_cap_filter', 10, 3 );
John Cotton comments:
Actually, I prefer
function user_cap_filter( $allcaps, $cap, $args ) {
if ( 'delete_post' == $args[0] ) {
if ( get_option( 'page_on_front' ) == $args[2] ) {
$allcaps[$cap[0]] = false;
}
}
return $allcaps;
}
add_filter( 'user_has_cap', 'user_cap_filter', 10, 3 );
but the previous structure would be better for multiple tests.
designbuildtest comments:
Thanks John. That worked a treat. Marking this question as solved now.
Kyle answers:
You could put in a last ditch fail safe using the trashed_post action that fires after the post has already been marked as 'trashed'. Such as:
add_action('trashed_post', 'check_if_home');
function check_if_home($post_id){
$home = get_option('page_on_front');
if( $post_id == $home ){
wp_untrash_post( $home );
}
}
Kyle comments:
That is untested, so you'll have to report back
designbuildtest comments:
Thanks Kyle, your code looks like it should work, but I haven't tested it myself. Please could you run a quick test yourself.
Ideally I'm looking to completely remove all visual prompts/actions that suggest the homepage can be sent to the trash in the first place.
Many thanks
Kyle comments:
Tested, and it works except get_option('page_on_front'); is incorrect, bare with me.
Kyle comments:
Okay, it works if you set the actual ID, you can't use the get_option because the trash action disrupts that. The issue being that you need to re set the page as homepage after it has been trashed. If you hardcode the ID, this will work:
add_action('trashed_post', 'check_if_home');
function check_if_home($post_id){
$home = 11; //Your home ID
if( $post_id == $home ){
wp_untrash_post( $home );
update_option( 'page_on_front', $home );
}
}
designbuildtest comments:
Much appreciated Kyle. I've just accepted John's answer below as his solution enabled me to remove all visual trash/bin references.
Kyle comments:
No problem, yes John's answer was better
Jeremy answers:
Better to disable the functionality than trying to change Wordpress Core:
Try either of these plugins:
https://wordpress.org/plugins/prevent-users-from-deleting-pages-posts-custom-post-types/
https://wordpress.org/plugins/lock-pages/
designbuildtest comments:
Cheers Jeremy. Installing a plugin is not my preferred option. I was hoping for a simple, custom function if at all possible.