Restrict specific private page to a specific user
-
19-04-2021 - |
Question
Each user has a user meta called profile_url chosen during registration. After user creation, a page with that slug is created and made private (the author of the page is the admin). The user in his front-end dashboard has the possibility to make this page public or private. When the page is private, the owner user cannot see it.
I would like to make the private page visible to the owner user.
The only way that came to mind is to add capabilities, like:
$ user = new WP_User ($ user_id);
$ user-> add_cap ('read_private_pages');
but I'd like to specify the page id, and I don't know if it's possible.
Thank you
La solution
I assume you're using wp_insert_post()
to create the private page for the user. The function returns the ID of the created page. You can use this ID as part of a custom capability you grant to the user.
// create the new $user
// create private page
$private_page_id = wp_insert_post( $postarr, $wp_error = false ); // returns id on success, 0 on failure
if ( $private_page_id ) {
// grant custom cap
$user->add_cap("can_access_{$private_page_id}", true);
}
When user tries to access the private page, use user_has_cap
filter to check, if the user has the required custom cap and dynamically grant the private page reading capability.
add_filter('user_has_cap', 'user_can_access', 10, 4);
function user_can_access($allcaps, $caps, $args, $user) {
$object = get_queried_object();
// make sure we're on a post
if ( ! is_a($object, 'WP_Post') ) {
return $allcaps;
}
// it should be a private page post
if ( 'page' !== $object->post_type || 'private' !== $object->post_status ) {
return $allcaps;
}
// does the user have the required access cap?
$can_access = 'can_access_' . $object->ID;
if ( isset( $allcaps[$can_access] ) && true === $allcaps[$can_access] ) {
// if so, allow user to access the private content
$allcaps['read_private_pages'] = true;
}
return $allcaps;
}
Autres conseils
New answer
OK another way round would be to use WP_Query.
You could create a page called Profile
and create a file called page-profile.php
Then use the code below to get the current users page data (assuming you are just saving the post name, not the complete user url in the meta)
// if user is not logged in then return or redirect to login page
if(!is_user_logged_in()) wp_safe_redirect(wp_login_url());
// get the user id
$user_id = get_current_user_id();
// get the current user profile url
$profile_url = get_user_meta($user_id, 'profile_url');
// page query args
$args = [
'post_status' => ['publish','private'],
'pagename' => $profile_url
];
// create the query
$page = new WP_Query( $args );
get_header();
?>
<?php if ( $page->have_posts() ): ?>
<?php while($page->have_posts()): $page->the_post() ?>
<?php the_title()?>
<?php endwhile; ?>
<?php endif; ?>
<?php
get_footer();
This means the user would always got to the url http://yoursite.com/profile
to view their page.
User pagename
if page but use name
if custom post type in the WP Query.