The problem with the code in your question is it always intercepts. You completely lose the ability to not publish, no drafts possible. Why this leads to untrashable post is something I didn't inspect further. Anyway this isn't what one wants.
I'm glad the javascript solution is working for you, but personally I have two problems with it, first, you can save post as public, second, it makes it harder - because the script always sets the radio button to private - to handle working with drafts. In a way there are now two solutions to the answer.
1. Forcing post type to be private plus visual indication:
This is why I took another look at doing it with post status transitions and, like I said, it can be done with Post Status Transitions.
Code:
add_action( 'transition_post_status', 'wpse118970_post_status_new', 10, 3 );
function wpse118970_post_status_new( $new_status, $old_status, $post ) {
if ( $post->post_type == 'itsme_private_posts' && $new_status == 'publish' && $old_status != $new_status ) {
$post->post_status = 'private';
wp_update_post( $post );
}
}
This forces published posts of your post type to be private. Without interfering with the ability to save drafts. This on it's own would be enough to solve the problem of having a private post type.
But of course it would be nice to have the private nature of the post type represented in the publishing metabox. For this I adjusted the javascript a little bit. Mainly by not setting the checkbox by default, but still changing the text shown, additionally I added a note.
Code:
add_action( 'post_submitbox_misc_actions' , 'wpse118970_change_visibility_metabox' );
function wpse118970_change_visibility_metabox(){
global $post;
if ($post->post_type != 'post')
return;
$message = __('<strong>Note:</strong> Published posts are always <strong>private</strong>.');
$post->post_password = '';
$visibility = 'private';
$visibility_trans = __('Private');
?>
<style type="text/css">
.priv_pt_note {
background-color: lightgreen;
border: 1px solid green;
border-radius: 2px;
margin: 4px;
padding: 4px;
}
</style>
<script type="text/javascript">
(function($){
try {
$('#post-visibility-display').text('<?php echo $visibility_trans; ?>');
$('#hidden-post-visibility').val('<?php echo $visibility; ?>');
} catch(err){}
}) (jQuery);
</script>
<div class="priv_pt_note">
<?php echo $message; ?>
</div>
<?php
}
Source: How to set new posts visibility to private by default?
Note: Compared to the code below I removed the checking of the radio button and additionally added code for the message.
Of course you don't need the javascript to make your post type private, but it's always nice to have things visually indicated. For that reason it's a nice addition.
2. Making private the standard option in the publishing meta box:
I'm keeping this because @its_me accepted the answer for this as solution. Like I said in the comment I found a helpful piece of code, it takes care of setting the visibility at the meta box to private by hooking into post_submitbox_misc_actions
. Like I said in the beginning »I have two problems with it, first, you can save post as public, second, it makes it harder - because the script always sets the radio button to private - to handle working with drafts«. It's still possible to have and work with drafts, just not as intuitive as before, but the private publishing status is in no way enforced.
Code:
add_action( 'post_submitbox_misc_actions' , 'wpse118970_change_visibility_metabox_value' );
function wpse118970_change_visibility_metabox_value(){
global $post;
if ($post->post_type != 'itsme_private_posts')
return;
$post->post_password = '';
$visibility = 'private';
$visibility_trans = __('Private');
?>
<script type="text/javascript">
(function($){
try {
$('#post-visibility-display').text('<?php echo $visibility_trans; ?>');
$('#hidden-post-visibility').val('<?php echo $visibility; ?>');
$('#visibility-radio-<?php echo $visibility; ?>').attr('checked', true);
} catch(err){}
}) (jQuery);
</script>
<?php
}
Source: How to set new posts visibility to private by default?
Note: I shortened the code to fit the needs here.
Moreover I can't even trash that thing!
The reason you couldn't trash the posts was because you were always setting thepost_status
toprivate
. When trashing posts, the post status is set totrash
, but you were overriding this behavior. I've found that a better approach is to only set the post status toprivate
if the post status is currentlypublic
.private
if it is currentlypublish
.public
isn't a post status.