Remove password protected posts from archive pages

In this tutorial we’ll show how to remove password-protected posts from all of the archive pages in WordPress. There is no need to modify the theme, create custom loops or custom queries.

We’ll modify the main query created by WordPress using two hooks; then, we’ll show other ways to use the same functions to search posts with a specific password.

All code provided will be added to the functions.php file inside the theme’s folder.

 

Adding the hooks

Only the main query will be modified to avoid conflicts with other queries created by the theme or plugins. Then, we’ll add a temporarily hook to filter out the password-protected posts.

function check_for_global_query( $query ){
if( ! $query->is_main_query() )
return;
//add new filter, this will remove the password-protected posts
add_filter( 'posts_where', array( &$this, 'remove_password_protected'), 100, 2 ); 
} add_action( 'pre_get_posts', 'check_for_global_query', 100 );

The following function will do the heavy lifting. It will remove all password-protected post using the “post_where” filter. We’ll run additional checks before applying any changes. After the change has been made, we’ll remove the original hook, so it doesn’t affect the queries that run after that.

function remove_password_protected( $where, $query ){
if( ! $query->is_main_query() )
return;
// remove previous filter to avoid conflicts with new or custom queries	
remove_filter( 'posts_where', array( &$this, 'remove_password_protected'), 100, 2 ); 
global $wpdb;
return $where . " AND $wpdb->posts.post_password = '';
}

That is it; none the archive pages will display password-protected posts. To restrict it to a particular page use any of WordPress’ conditional tags.

 

Extending the functionality

The functions can be modify to work with any custom WP_Query. Use these functions to search for a posts using a particular password.

function check_password_protected_var( $query ){
if( ! isset( $query->query['post_password'] ))
return;
//add new filter, this will remove the password-protected posts
add_filter( 'posts_where', array( &$this, 'remove_password_protected'), 100, 2 ); 
} add_action( 'pre_get_posts', 'check_password_protected_var', 100 );
function remove_password_protected( $where, $query ){
if( ! isset( $query->query['post_password'] ))
return;
// remove previous filter to avoid conflicts with new or custom queries	
remove_filter( 'posts_where', array( &$this, 'remove_password_protected'), 100, 2 ); 
global $wpdb;
return $where . " AND $wpdb->posts.post_password = '';
}

Filter out posts using the “post_password” argument on any custom WordPress query (WP_Query).

$posts = new WP_Query( array( 
'post_password' => '',
'posts_per_page' => 5, 
) );

We hope the tutorial has been helpful. Problems or questions about this tutorial? feel free to post a comment in the comments section below.