I tend to use template_redirect
action to check, if a user has access to certain content, e.g. a page. To me, it is the most logical and straightforward place to handle the checking. As per the docs, https://developer.wordpress.org/reference/hooks/template_redirect/, the action,
Fires before determining which template to load.
Also the WP object has been already set up and the current user is known, so checking the user and the content is easy.
To mark something as restricted content, I might use a page template, a custom taxonomy, or just plain post meta – depending on the use case and how lazy I’m feeling at that moment.
I might do something like this,
add_action( 'template_redirect', 'my_maybe_protected_content' );
function my_maybe_protected_content() : void {
// optional conditions..
if ( ! is_page() ) {
return;
}
// current post id
// use get_queried_object(), if post object is needed
$post_id = get_queried_object_id();
// check for protected content
if ( ! my_is_protected_content($post_id) ) {
return;
}
// access and/or auth chcecks
if (
! is_user_logged_in() ||
! my_user_has_access(
wp_get_current_user(), $post_id
)
) {
my_redirect_user();
}
}
function my_is_protected_content(int $post_id) : bool {
// option 1 - determine from template
if ( 'path/to/page-template.php' === get_page_template_slug( $post_id ) ) {
return true;
}
// option 2 - use a custom taxonomy
if ( has_term( 'is_protected_content', 'my_utility_taxonomy', $post_id ) ) {
return true;
}
// option 3 - check from post meta
$protected_by_meta_flag = get_post_meta( $post_id, 'my_protected_content_meta_key', true );
if ( $protected_by_meta_flag ) {
return true;
}
// default...
return false;
}
function my_user_has_access(WP_User $user, int $post_id) : bool {
// some fancy logic...
return true;
}
function my_redirect_user() {
nocache_headers();
wp_redirect( wp_login_url() );
exit();
}
The code would go into functions.php
, an additional PHP file required in functions.php
, or a custom plugin.