Forcing all posts associated with a custom post type to be private

The question:

Does anyone know of a way to add code to the functions.php file which will automatically force all posts belonging to a custom post type to be “private” and/or “password protected” with a default password set?

I am specifically referring to creating a new post or editing an existing post thus ensuring a post belonging to a specific custom post type never changes…

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

You can hook onto save_post, wp_insert_post or wp_insert_post_data to modify the post object prior to it being inserted or saved.

Using save_post or wp_insert_post the callback would need to declare two args and would receive the post object as the second incoming variable.. (and i’m showing you to cover the alternatives, TheDeadMedic’s example would be fine to).

For setting default values for a particular post type for new posts you can use a small hack by hooking onto default_content (although default_title would also work to), like the example i gave here.

You essentially need two functions, one to modify post objects at the time of save/insert and one to set default post object values, here’s an example of the two necessary functions(again noting you can swap my save_post callback for the example already given by TheDeadMedic).

add_action( 'save_post', 'check_type_values', 10, 2 );

function check_type_values( $post_id, $post ) {

    if( $post->post_type )
        switch( $post->post_type ) {
            case 'my_custom_type':
                $post->post_status = 'private';
                $post->post_password = ( '' == $post->post_password ) ? 'some_default_when_no_password' : $post->post_password;
            break;
        }   
    return;
}

add_filter( 'default_content', 'set_default_values', 10, 2 );

function set_default_values( $post_content, $post ) {

    if( $post->post_type )
        switch( $post->post_type ) {
            case 'my_custom_type':
                $post->post_status = 'private';
                $post->post_password = 'some_default_password';
            break;
        }
    return $post_content;
}

Hope that helps…

Method 2

function force_type_private($post)
{
    if ($post['post_type'] != 'my_post_type' || $post['post_status'] == 'trash')
        return $post;

    $post['post_password'] = 'my password';
    $post['post_status'] = 'private';
    return $post;
}
add_filter('wp_insert_post_data', 'force_type_private');

Method 3

Couldn’t we just make a template page for the custom post type and do a check if the is the user is logged in and check if the user is a certain role? Lets take for example you want to have a post-type that is only to be viewed by the admins:

<?php if ( is_user_logged_in() && is_admin() ) : if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
  <?php the_content(); ?>
<?php endwhile; endif; endif; ?>

Method 4

There are three hooks specifically for when the status of a post changes:

/**
 * Fires when a post is transitioned from one status to another.
 */
do_action( 'transition_post_status', $new_status, $old_status, $post );

/**
 * Fires when a post is transitioned from one status to another.
 *
 * The dynamic portions of the hook name, `$new_status` and `$old_status`,
 * refer to the old and new post statuses, respectively.
 */
do_action( "{$old_status}_to_{$new_status}", $post );

/**
 * Fires when a post is transitioned from one status to another.
 *
 * The dynamic portions of the hook name, `$new_status` and `$post->post_type`,
 * refer to the new post status and post type, respectively.
 */
do_action( "{$new_status}_{$post->post_type}", $post->ID, $post );

How to use:

/**
 * Portfolio always published as private
 *
 * @param $post_id
 */
function wp_neavr2_portfolio_always_publish_as_private( $post_id ) {

    wp_update_post( array(
        'ID'          => $post_id,
        'post_status' => 'private',
    ) );
}

add_action( 'publish_portfolio', 'wp_neavr2_portfolio_always_publish_as_private' );

In this case, the portfolio post type will always be published privately. However, it is possible to create a draft, as this is not restricted.

Note that since this is not a filter, you must use the wp_update_post() function to update the status.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment